spring-boot-route(二十三)開發微信公眾號

Java旅途發表於2020-10-23

在講微信公眾號開發之前,先來大概瞭解一下微信公眾號。微信公眾號大體上可以分為服務號和訂閱號,訂閱號和服務號的區別如下:

  1. 服務號可以申請微信支付功能。
  2. 服務號只能由企業申請,訂閱號可以有企業或個人申請。
  3. 訂閱號和服務號每月推送訊息次數不同,訂閱號每天可以推送一次,服務號每月可以推送四次。
  4. 服務號推送的訊息會出現在使用者的聊天列表中,而訂閱號推送的訊息顯示在訂閱號資料夾中。
  5. 還有一些其他介面功能的區別和限制,總的來說服務號支援更高階的功能開發。

訂閱號更加偏向於向使用者傳遞諮詢,一般各種技術類公眾號都屬於訂閱號,訂閱號的訊息推送並不會有太顯眼的提醒,如果你想讓某個公眾號的推送內容更加顯眼,可以選擇置為星標。置為星標後公眾號會顯示在所有訂閱號的最頂部,同時收到訊息後會有黃色五角星星標提醒。

一 公眾號配置伺服器

微信官方提供了非常完善的接入文件,如果想了解文件的具體內容,直接瀏覽器搜尋微信開發文件就可以了。但是為了方便開發,一般不會直接去根據微信開發文件進行開發,gitee上有許多開源專案對微信開發文件進行了封裝,這裡我使用mica-weixin開發包進行演示,mica-weixinjfinal-weixin的boot版本。

配置伺服器資訊很簡單,具體流程就是微信服務傳送請求一個請求給業務伺服器,業務伺服器驗證請求後給微信服務一個響應

1.1 搭建業務服務

本地搭建一個spring-boot-weixin的專案,使用內網穿透工具進行穿透,使其可以與外網進行通訊。

1.1.1 引入mica-weixin依賴

<dependency>
    <groupId>net.dreamlu</groupId>
    <artifactId>mica-weixin</artifactId>
    <version>2.0.1</version>
</dependency>

1.1.2 配置公眾號資訊

mica-weixin通過配置檔案進行公眾號資訊的配置,如果你想通過資料庫配置公眾號資訊,可以參考我以前寫過的一篇文章jfinal-weixin自定義配置支援多公眾號

dream:
  weixin:
    wx-configs:
    - appId: xxxxxx
      appSecret: xxxxxx
      token: javatrip
      encodingAesKey: xxxxxx

appIdappSecret可在公眾號後臺進行檢視,具體位置在選單開發—>基本配置中,其中appSecret要妥善保管,現在公眾號已經不支援檢視appSecret了,如果你忘了appSecret,只能進行重置。

1.1.3 開發訊息校驗介面

mica-weixin已經為我們提供好了訊息校驗介面,只需要繼承DreamMsgControllerAdapter就可以了。

@WxMsgController("/weixin/wx")
public class WeiXinMsgController extends DreamMsgControllerAdapter {
    @Override
    protected void processInFollowEvent(InFollowEvent inFollowEvent) {
    }

    @Override
    protected void processInTextMsg(InTextMsg inTextMsg) {
    }

    @Override
    protected void processInMenuEvent(InMenuEvent inMenuEvent) {
    }
}

同時,需要開啟快取,由於mica-weixin的將access_token等資訊放在了快取中。在啟動類上加@EnableCaching就開啟了。

@SpringBootApplication
@EnableCaching
public class WeixinApplication {
    public static void main(String[] args) {
        SpringApplication.run(WeixinApplication.class, args);
    }
}

1.1.4 公眾號後臺配置伺服器資訊

使用內網穿透工具穿透內網地址,然後在公眾號後臺選單開發—>基本配置中填寫伺服器配置資訊。

填寫完成後點選啟用,這樣就完成了微信伺服器和業務伺服器的關係配置。開啟開發者配置後,自動回覆、自定義選單等功能都不能正常使用了。這時候就需要去呼叫對應的介面實現這些功能。

二 實現各種訊息介面

2.1 關注訊息

在一步中,自定義類WeiXinMsgController中需要重寫三個父類中的方法,其中processInFollowEvent()就是關注和取消關注的方法,取消關注後使用者雖然不能收到訊息,但是後臺可以接收到使用者取消關注的事件。

@Override
protected void processInFollowEvent(InFollowEvent inFollowEvent) {

    OutTextMsg defaultMsg = new OutTextMsg(inFollowEvent);
    // 關注
    if(InFollowEvent.EVENT_INFOLLOW_SUBSCRIBE.equals(inFollowEvent.getEvent())){
        // 可將關注使用者錄入db,此處可以獲取到使用者openid
        String openId = inFollowEvent.getFromUserName();
        // 查詢db,根據響應訊息型別封裝訊息體
        if("文字訊息"){
            OutTextMsg otm = new OutTextMsg(inFollowEvent);
            otm.setContent("訊息內容");
            render(otm);
            return;
        }else if("圖片訊息"){
            OutImageMsg oim = new OutImageMsg(inFollowEvent);
            // 這裡需要呼叫微信提供的素材介面,將圖片上傳至素材庫。
            oim.setMediaId("圖片素材id");
            render(oim);
            return;
        }else if("圖文訊息"){
            OutNewsMsg onm = new OutNewsMsg(inFollowEvent);
            onm.addNews("標題","簡介","圖片地址","圖文連結");
            render(onm);
            return;
        }else if("視訊訊息"){
            OutVideoMsg ovm = new OutVideoMsg(inFollowEvent);
            ovm.setTitle("標題");
            ovm.setDescription("簡介");
            ovm.setMediaId("視訊素材id");
            render(ovm);
            return;
        }else{
            defaultMsg.setContent("感謝關注");
        }
    }
    // 取消關注
    if(InFollowEvent.EVENT_INFOLLOW_UNSUBSCRIBE.equals(inFollowEvent.getEvent())){
        log.info("使用者取消關注了");
        // 此處可以將取消關注的使用者更新db
    }
}

2.2 關鍵詞訊息

響應內容跟關注訊息一樣,查詢db去匹配關鍵詞,然會根據訊息內容封裝對應的訊息體進行返回,如果沒匹配到關鍵詞則回覆統一的訊息內容。processInTextMsg()方法就是用來回復關鍵詞訊息的。

@Override
protected void processInTextMsg(InTextMsg inTextMsg) {

    String content = inTextMsg.getContent();
    // 根據使用者傳送的content去查詢db中的響應內容
    if("文字訊息"){
        OutTextMsg otm = new OutTextMsg(inTextMsg);
        otm.setContent("訊息內容");
        render(otm);
        return;
    }else if("圖片訊息"){
        OutImageMsg oim = new OutImageMsg(inTextMsg);
        // 這裡需要呼叫微信提供的素材介面,將圖片上傳至素材庫。
        oim.setMediaId("圖片素材id");
        render(oim);
        return;
    }else if("圖文訊息"){
        OutNewsMsg onm = new OutNewsMsg(inTextMsg);
        onm.addNews("標題","簡介","圖片地址","圖文連結");
        render(onm);
        return;
    }else if("視訊訊息"){
        OutVideoMsg ovm = new OutVideoMsg(inTextMsg);
        ovm.setTitle("標題");
        ovm.setDescription("簡介");
        ovm.setMediaId("視訊素材id");
        render(ovm);
        return;
    }else{
        OutTextMsg otm = new OutTextMsg(inTextMsg);
        otm.setContent("暫未查到關鍵詞...");
    }
}

2.3 選單訊息

點選選單後也是一樣,通過processInMenuEvent()方法進行響應內容的回覆。

@Override
protected void processInMenuEvent(InMenuEvent inMenuEvent) {
    String eventKey = inMenuEvent.getEventKey();
    // 根據使用者傳送的content去查詢db中的響應內容
    if("文字訊息"){
        OutTextMsg otm = new OutTextMsg(inMenuEvent);
        otm.setContent("訊息內容");
        render(otm);
        return;
    }else if("圖片訊息"){
        OutImageMsg oim = new OutImageMsg(inMenuEvent);
        // 這裡需要呼叫微信提供的素材介面,將圖片上傳至素材庫。
        oim.setMediaId("圖片素材id");
        render(oim);
        return;
    }else if("圖文訊息"){
        OutNewsMsg onm = new OutNewsMsg(inMenuEvent);
        onm.addNews("標題","簡介","圖片地址","圖文連結");
        render(onm);
        return;
    }else if("視訊訊息"){
        OutVideoMsg ovm = new OutVideoMsg(inMenuEvent);
        ovm.setTitle("標題");
        ovm.setDescription("簡介");
        ovm.setMediaId("視訊素材id");
        render(ovm);
        return;
    }else{
        OutTextMsg otm = new OutTextMsg(inMenuEvent);
        otm.setContent("無效連結,請重試...");
    }
}

三 介面API呼叫

目前,微信提供的介面對訂閱號的限制比較大,未認證的訂閱號基本上只有接收訊息的幾個功能介面。

呼叫介面的時候需要傳遞token,獲取token需要在微信後臺中配置業務伺服器的白名單。如下:

如果需要配置多個白名單ip,使用Enter鍵將多個ip分隔開。

mica-weixin提供了所有的介面封裝,具體可參考它的官方文件,如果要獲取微信選單,可以這樣寫:

@WxApi("weixin/api")
public class WeiXinApiController {
    @GetMapping("menu")
    @ResponseBody
    public String getMenu(){
        ApiResult menu = MenuApi.getMenu();
        return menu.getJson();
    }
}

@WxApi這個是它的自定義註解,其實就是包含了@RequestMapping@Controller

四 其他事項

4.1 多公眾號配置

mica-weixin提供了多公眾號配置的功能,使用ThreadLocalappid進行繫結。只需要簡單配置即可實現多公眾號配置。

dream:
  weixin:
    wx-configs:
      - appId: xxxxxx
        appSecret: xxxxxx
        token: javatrip
        encodingAesKey: xxxxxx
      - appId: xxxxxx
        appSecret: xxxxxx
        token: javatrip
        encodingAesKey: xxxxxx

4.2 redis配置

access_token的有效期是2小時,並且該介面有呼叫次數限制,mica-weixinaccess_token儲存在redis中,避免每次呼叫介面都去獲取access-token,因此專案需要配置redis。

spring:
  redis:
    host: localhost
    port: 6379

4.3 手動選擇ThreadLocal

如果想要開發微信公眾號的後臺管理功能,多公眾號的時候就需要手動去指定當前執行緒使用哪個公眾號資訊。如下:

ApiConfigKit.setThreadLocalAppId(appid);

至此,SpringBoot開發微信公眾號就算完成了,由於訂閱號開放的介面太少了,好多功能不能正常演示。還有mica-weixin也許不是最好的選擇,如果想試著開發微信公眾號,可以在gitee上找一下開發包。至於我為什麼會使用mica-weixin,是因為我曾用過一段時間的jfinal框架,與之配套的微信開發包就是jfinal-weixin,也就是jfinal版的mica-weixin


此是spring-boot-route系列的第二十三篇文章,這個系列的文章都比較簡單,主要目的就是為了幫助初次接觸Spring Boot 的同學有一個系統的認識。本文已收錄至我的github,歡迎各位小夥伴star

githubhttps://github.com/binzh303/spring-boot-route

點關注、不迷路

如果覺得文章不錯,歡迎關注點贊收藏,你們的支援是我創作的動力,感謝大家。

如果文章寫的有問題,請不要吝惜文筆,歡迎留言指出,我會及時核查修改。

相關文章