本文介紹如何處理微信公眾號開發中的訊息與事件,包括:(1)訊息(事件)概況;(2)驗證訊息的真實性;(3)解析訊息;(4)被動回覆訊息; (5)發送其他訊息。
1 訊息(事件)概況
當一般微信用戶向公眾號發送訊息或微信伺服器向公眾號推送事件時,微信伺服器將POST訊息(事件)的XML封包到開發者填寫的公眾號伺服器URL上;公眾號伺服器然後對訊息回應。
1.1 訊息的流轉過程
為了方便區分,我們將微信伺服器發送到公眾號伺服器的訊息稱為請求(Request)訊息;將公眾號伺服器發送到微信伺服器的訊息稱為回應(Response)訊息;將推播事件看成特殊的請求訊息。
請求與回應訊息的串流流程如下圖所示:
1.2 請求訊息
請求訊息有很多種,我們為其一一建立了對應的類,類層次結構如下圖所示:
有些請求訊息,我們可以做出回應,有些則不能,詳見下表:
#訊息類型 | 是否事件 | 能夠被動回覆 | #備註 |
文字 | × | √ | |
#圖片 | × | ##√||
× | √ | ||
× | 未知 | 接收不到視訊訊息,也不知道是否能被動回覆 | |
# × | √ | ||
× | √ | ||
√ | √ | ||
× | 掃描二維碼 | ||
##× | 回報地理位置 | ##√√||
# | 點選選單拉取訊息 | √ | |
#點選選單跳轉連結 | √ | ||
點選選單掃碼推 | #√ | ||
點選選單掃碼等待回覆 | √ | ||
# | 點選選單系統發圖片 | √ | |
接收不到系統發圖事件;微信伺服器會傳送圖片訊息,可回覆 | 點選選單拍照或相簿發圖 | √ | |
微信伺服器會傳送圖片訊息,可回覆 | ##點擊選單微信發圖 | √ |
1.3 回應訊息
回應訊息的類別層次結構如下圖所示:
2 驗證訊息的真實性
公眾號伺服器接收到微信伺服器的請求之後,第一件事是驗證訊息的真實性。
Utility.CheckSignature方法用於驗證訊息簽章是否正確。
範例如下:
/// <summary> /// 验证消息的有效性 /// </summary> /// <param name="context"></param> /// <returns>如果消息有效,返回true;否则返回false。</returns> private bool Validate(HttpContext context) { string username = RequestEx.TryGetQueryString("username"); //在接口配置的URL中加入了username参数,表示哪个微信公众号 AccountInfo account = AccountInfoCollection.GetAccountInfo(username); if (account == null) return false; string token = account.Token; string signature = RequestEx.TryGetQueryString("signature"); string timestamp = RequestEx.TryGetQueryString("timestamp"); string nonce = RequestEx.TryGetQueryString("nonce"); if (string.IsNullOrWhiteSpace(signature) || string.IsNullOrWhiteSpace(timestamp) || string.IsNullOrWhiteSpace(nonce)) return false; return xrwang.weixin.PublicAccount.Utility.CheckSignature(signature, token, timestamp, nonce); } 验证消息真实性
驗證訊息真實性
3 解析訊息
## 如果訊息簽署經過驗證,我們需要將XML格式的訊息文字解析成請求訊息對象,RequestMessageHelper類別用於完成這項工作。RequestMessageHelper helper = new RequestMessageHelper(context.Request); if(helper.Message != null) { //消息解析成功,对它进行处理 }訊息解析成功之後,helper.Message為訊息基類RequestBaseMessage,我們可以根據屬性MsgType及Event判斷到底是哪種訊息(事件),並轉換成適當的子類型。例如:
RequestBaseMessage bm=helper.Message; switch(bm.MsgType) { case RequestMessageTypeEnum.text: //文本消息 HandleTextMessage((RequestTextMessage)bm); break; case RequestMessageTypeEnum.image: //图片消息 HandleImageMessage((RequestImageMessage)bm); break; //处理其他消息 case RequestMessageTypeEnum.event: //事件 RequestEventMessage ev=(RequestEventMessage)bm; switch(ev.Event) { case RequestEventTypeEnum.subscribe: //订阅 HandleSubscribeMessage((RequestSubscribeMessage)ev); break; case RequestEventTypeEnum.unsubscribe: //取消订阅 HandleUnsubscribeMessage((RequestUnsubscribeMessage)ev); break; //处理其他事件 } break; default: break; }
解析訊息的細節請參考原始碼:http://git.oschina.net/xrwang2/xrwang.weixin.PublicAccount/blob/master/PublicAccount /RequestMessage/RequestMessageHelper.cs
4 被動回覆訊息 從微信伺服器接收到訊息(事件)之後,我們可以在5秒內直接(被動)回覆訊息;也可以先直接回覆空字串,然後再在48小時內回覆客服訊息。
先初始化ResponseXxxMessage,然後用ToXml方法得到回應訊息內容。
被動回覆訊息的範例如下:
/// <summary> /// 处理微信的POST请求 /// </summary> /// <param name="context"></param> /// <returns>返回xml响应</returns> private string HandlePost(HttpContext context) { RequestMessageHelper helper = new RequestMessageHelper(context.Request); if (helper.Message != null) { ResponseBaseMessage responseMessage = HandleRequestMessage(helper.Message); return responseMessage.ToXml(helper.EncryptType); } else return string.Empty; } /// <summary> /// 处理请求消息,返回响应消息 /// </summary> /// <returns>返回响应消息</returns> private ResponseBaseMessage HandleRequestMessage(RequestBaseMessage requestMessage) { ResponseTextMessage response = new ResponseTextMessage(requestMessage.FromUserName, requestMessage.ToUserName, DateTime.Now, string.Format("自动回复,请求内容如下:\r\n{0}", requestMessage)); return response; }
以上是.net微信公眾號開發訊息與事件的詳細內容。更多資訊請關注PHP中文網其他相關文章!