公眾平臺測試帳號開發全流程第6篇-接收和被動回覆訊息
接收訊息
- 關於訊息,上篇文章已經介紹了差不多,這篇主要是講述接收微信伺服器傳送的訊息。
- 接收訊息又分為普通訊息和事件訊息。
- 普通訊息
- 文字訊息
- 圖片訊息
- 語音訊息
- 視訊訊息
- 小視訊訊息
- 地理位置訊息
- 連結訊息
- 事件訊息
- 關注/取消關注事件
- 掃描帶引數二維碼事件
- 上報地理位置事件
- 自定義選單事件
- 點選選單拉取訊息時的事件推送
- 點選選單跳轉連結時的事件推送
接收訊息注意事項
1、關於重試的訊息排重,推薦使用msgid排重。
2、微信伺服器在五秒內收不到響應會斷掉連線,並且重新發起請求,總共重試三次。假如伺服器無法保證在五秒內處理並回復,可以直接回復空串,微信伺服器不會對此作任何處理,並且不會發起重試。詳情請見“傳送訊息-被動回覆訊息”。
3、為了保證更高的安全保障,開發者可以在公眾平臺官網的開發者中心處設定訊息加密。開啟加密後,使用者發來的訊息會被加密,公眾號被動回覆使用者的訊息也需要加密(但開發者通過客服介面等API呼叫形式向用戶傳送訊息,則不受影響)。關於訊息加解密的詳細說明,請見“訊息加解密說明”。 ——微信平臺開發者文件(接收普通訊息)
關於接收訊息Url
當普通微信使用者向公眾賬號發訊息時,微信伺服器將POST訊息的XML資料包到開發者填寫的URL上。
這邊的URL在公眾平臺測試帳號開發全流程第3篇-接入有提到,該地址也是微信伺服器驗證你所填寫的伺服器地址的有效性的URL,不過驗證是採用GET,而接受訊息是採用POST。
程式碼
我的專案中,微信伺服器傳送的訊息都會發送到該方法中來,方法中的content是返回給微信伺服器的訊息。下一篇會講到。
該方法會接收到普通訊息和事件訊息。可以根據MsgType來區分該訊息是普通訊息還是事件訊息。
由於微信伺服器傳送的是xml格式的資料,所以要用把流解析成xml。這裡是採用dom4j
接收和回覆訊息流程
- 讀取流的資料到document中
- 獲得xml資料中的MsgType
- 根據MsgType判斷訊息是事件訊息還是普通訊息
- 處理訊息(事件訊息和普通訊息)
- 根據訊息選擇對應的內容進行回覆
嚴格來說,傳送被動響應訊息其實並不是一種介面,而是對微信伺服器發過來訊息的一次回覆。
也就是當微信伺服器呼叫該URL時,我們返回的資料即是被動回覆訊息。這裡不討論被動回覆訊息,下篇再進行敘述。下圖就是整個流程了
各訊息型別的推送XML資料包結構
引數 | 描述 |
---|---|
ToUserName | 開發者微訊號 |
FromUserName | 傳送方帳號(一個OpenID) |
CreateTime | 訊息建立時間 (整型) |
MsgType | 訊息型別 |
而事件訊息則都有
引數 | 描述 |
---|---|
Event | 事件型別 |
如有錯誤,請告知。
上面共有的屬性可以封裝為一個基類,其他可以繼承基類,然後根據不同的引數增加屬性。如下圖
關於處理訊息的程式碼,本文不在敘述,每個人有每個人的處理方式和編碼方式,可以根據自己的需求編寫。
關於bean轉換xml和xml轉換bean
我寫了個工具類,大家覺得方便的可以用用,如果有好的建議可以提出來。
import org.dom4j.Document;
import com.thoughtworks.xstream.XStream;
@SuppressWarnings({"rawtypes","unchecked"})
public class XmlUtils {
public static <T> T xml2Bean(Class clazz, Document document) {
XStream xStream = new XStream();
xStream.alias("xml", clazz);
xStream.ignoreUnknownElements();//忽略未知的屬性
return (T) xStream.fromXML(document.asXML());
}
public static <T> String bean2Xml(T t) {
XStream xStream = new XStream();
xStream.alias("xml", t.getClass());
return xStream.toXML(t);
}
}
被動回覆訊息
注意事項
當用戶傳送訊息給公眾號時(或某些特定的使用者操作引發的事件推送時),會產生一個POST請求,開發者可以在響應包(Get)中返回特定XML結構,來對該訊息進行響應(現支援回覆文字、圖片、圖文、語音、視訊、音樂)。嚴格來說,傳送被動響應訊息其實並不是一種介面,而是對微信伺服器發過來訊息的一次回覆。
微信伺服器在將使用者的訊息發給公眾號的開發者伺服器地址(開發者中心處配置)後,微信伺服器在五秒內收不到響應會斷掉連線,並且重新發起請求,總共重試三次,如果在除錯中,發現使用者無法收到響應的訊息,可以檢查是否訊息處理超時。關於重試的訊息排重,有msgid的訊息推薦使用msgid排重。事件型別訊息推薦使用FromUserName + CreateTime 排重。
如果開發者希望增強安全性,可以在開發者中心處開啟訊息加密,這樣,使用者發給公眾號的訊息以及公眾號被動回覆使用者訊息都會繼續加密(但),詳見被動回覆訊息加解密說明。
假如伺服器無法保證在五秒內處理並回復,必須做出下述回覆,這樣微信伺服器才不會對此作任何處理,並且不會發起重試(這種情況下,可以使用客服訊息介面進行非同步回覆),否則,將出現嚴重的錯誤提示。詳見下面說明:
1、(推薦方式)直接回復success
2、直接回復空串(指位元組長度為0的空字串,而不是XML結構體中content欄位的內容為空)
一旦遇到以下情況,微信都會在公眾號會話中,向用戶下發系統提示“該公眾號暫時無法提供服務,請稍後再試”:1、開發者在5秒內未回覆任何內容
2、開發者回覆了異常資料,比如JSON資料等
另外,請注意,回覆圖片等多媒體訊息時需要預先通過素材管理介面上傳臨時素材到微信伺服器,可以使用素材管理中的臨時素材,也可以使用永久素材。—— 微信平臺開發者文件(被動回覆使用者訊息)
回覆內容的XML資料包結構
和接收訊息一樣具有這些相同的引數
引數 | 描述 |
---|---|
ToUserName | 開發者微訊號 |
FromUserName | 傳送方帳號(一個OpenID) |
CreateTime | 訊息建立時間 (整型) |
MsgType | 訊息型別 |
注意ToUserName和FromUserName
回覆訊息的ToUserName和FromUserName與接收訊息正好相反,也就是回覆訊息的ToUserName是接收訊息的FromUserName,FromUserName是接收訊息的ToUserName,及傳送方和接收方互換一些,這點不難理解。
回覆訊息的具體流程
- 獲取需要回復的內容
- 封裝成對應的bean資料
- 使用XStream轉換成xml
- 把xml資料直接輸出到頁面
- 微信伺服器接收到訊息
- 微信伺服器傳送給使用者
- 完成整個訊息接收和回覆訊息流程
該流程就是從接收訊息第4步處理訊息之後執行。