顧名思義,我們就是來做一個訂閱号機器人,大緻是這樣一個過程
公衆号接收使用者消息 -> 微信平台發送消息給我們的伺服器 -> 我們的伺服器處理消息 -> 傳回處理結果給微信平台 -> 微信平台發送内容給使用者。
基于這樣一個大前提就有了下面的步驟。
1、填寫伺服器配置,可以接收微信平台發送的内容
2、開發服務端,并驗證伺服器位址的有效性
3、處理具體的業務邏輯
1. 配置微信公衆号
首先肯定需要有一個訂閱号,然後在訂閱号背景點選 開發者->基本配置進入如下頁面,點選确定
然後進入配置頁面,我們一一對配置進行講解
- 開發者ID,開發者調用的唯一标示,調用接口的時候需要傳遞。
- 開發者密碼,這個很重要一定要儲存在自己的伺服器上面,用于驗證安全性。
- 服務位址,這個就是我們用來接收微信平台轉發的使用者消息的服務的位址
- 令牌,使用者接收資訊時候做驗證是否請求來自微信平台
- 用于加密消息,防止被截獲,如果 6 設定為明文模式不需要這個配置。
- 是否加密傳輸消息
我們本期隻做接收圖檔消息,驗證完成以後回複消息,是以隻需要配置 3、4。
- 是我們具體的伺服器位址,path是 weixin/receive 這個下文中具體代碼部分會詳細講解
- Token 随便生成一個 UUID 就可以
- 随機生成,後面如果調用 API 會用到。
這時候你點選送出會提示驗證失敗,是因為你還沒有部署 API,配置到這裡我們就開始編寫代碼。
2. 編寫服務端
伺服器端使用現有的輪子非常簡單,因為是 spring-boot 項目,直接引入一個現成的微信 starter,一定要添加 repository ,這個是依托 Github 自帶的倉庫。
<repositories>
<repository>
<id>developer-weapons-repository</id>
<url>https://raw.githubusercontent.com/developer-weapons/repository/master</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.developer.weapons</groupId>
<artifactId>wechat-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
然寫兩個接口,一個 GET 用于第一次綁定微信背景驗證用,一個 POST 用于以後接收消息 /weixin/receive
把之前準備好的 token 配置到 application.properties 然後注入到 Controller 裡面,大緻的驗證代碼如下,如果驗證簽名成功就傳回 echostr,算是通信的标示,如果驗證失敗傳回 error。
@Autowired
private WechatOfficialService wechatOfficialService;
@Value("${weixin.token}")
private String token;
@RequestMapping(value = "/weixin/receive", method = RequestMethod.GET)
public void receive(
@RequestParam(value = "signature") String signature,
@RequestParam(value = "timestamp") String timestamp,
@RequestParam(value = "nonce") String nonce,
@RequestParam(value = "echostr") String echostr,
HttpServletResponse response) throws IOException {
boolean valid = wechatOfficialService.isValid(signature, timestamp, nonce, token);
PrintWriter writer = response.getWriter();
if (valid) {
writer.print(echostr);
} else {
writer.print("error");
}
writer.flush();
writer.close();
}
編寫到這裡就可以找一個伺服器部署起來,點選驗證喽,這時候點選送出直接成功了,點選啟用以後就生效了,生效以後你原來配置的自動回複就會生效,是以這個操作請謹慎。
3. 處理業務邏輯
處理業務邏輯首先是接收消息,下面是接收消息的代碼
@RequestMapping(value = "/weixin/receive", method = RequestMethod.POST)
public void receive(
@RequestParam(value = "signature") String signature,
@RequestParam(value = "timestamp") String timestamp,
@RequestParam(value = "nonce") String nonce,
HttpServletRequest request,
HttpServletResponse response) throws IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
boolean valid = wechatOfficialService.isValid(signature, timestamp, nonce, token);
PrintWriter writer = response.getWriter();
if (!valid) {
writer.print("error");
writer.flush();
writer.close();
return;
}
try {
Map<String, String> map = wechatOfficialService.toMap(request.getInputStream());
if (map.get("MsgType").equals("image")) {
String msg = OfficialAutoReplyMessage.build()
.withContent("接收到圖檔連結為:" + map.get("PicUrl"))
.withMsgtype(MessageTypeEnum.TEXT)
.withFromUserName(map.get("ToUserName"))
.withToUserName(map.get("FromUserName"))
.toXml();
writer.print(msg);
writer.flush();
writer.close();
return;
}
} catch (Exception e) {
log.error("WeixinController receive error", e);
}
writer.print("success");
writer.flush();
writer.close();
}
第一步還是驗證消息是否來自微信平台,然後使用
wechatOfficialService.toMap
方法解析出接收消息的内容,目前判斷比較簡單,直接判斷是否是圖檔消息,然後傳回圖檔的 URL 給發送消息的使用者。效果圖如下
那麼接下來就到了最關鍵的一步,如何鑒黃,這個具體的邏輯可以參考這一篇文章,現在我們直接把相關代碼怼上。
按照上面的文章修改代碼後結果如下,具體的 publicKey 和 privateKey 自己參考下哦。關注公衆号 逆鋒起筆,回複 pdf,下載下傳你需要的各種學習資料。
if (map.get("MsgType").equals("image")) {
String res = checkService.check(publicKey, privateKey, map.get("PicUrl"));
OfficialAutoReplyMessage officialAutoReplyMessage =
OfficialAutoReplyMessage.build()
.withMsgtype(MessageTypeEnum.TEXT)
.withFromUserName(map.get("ToUserName"))
.withToUserName(map.get("FromUserName"));
if (StringUtils.equals("forbid", res)) {
officialAutoReplyMessage.withContent("小哥,你的圖檔有點問題哦");
} else {
officialAutoReplyMessage.withContent("騷年,你這圖檔剛剛的沒問題");
}
writer.print(officialAutoReplyMessage.toXml());
writer.flush();
writer.close();
return;
}
最終效果如下
是以你會搭建自己的鑒黃機器人了嗎?點選原文擷取項目源碼。