在微信用戶和公衆號產生交互的過程當中,用戶的某些操做會使得微信服務器經過事件推送的形式通知到開發者在開發者中心處設置的服務器地址,從而開發者能夠獲取到該信息。其中,某些事件推送在發生後,是容許開發者回覆用戶的,某些則不容許git
咱們在上一篇微信公衆號開發C#系列-六、消息管理-普通消息接受處理中講到,微信的消息能夠大致分爲兩種類型,一種是包括:文本,語音,圖片等的普通消息,另外一種就是本篇要將的事件類型。包括:關注/取消關注事件,掃描帶參數二維碼事件,上報地理位置事件,自定義菜單相關事件等,本篇一一進行講解。介於偏於內容過多易產生閱讀疲勞,對於自定義菜單相關事件的處理咱們放在下一篇中講解。github
這裏的消息指的是傳統的微信公衆平臺消息交互,微信用戶向公衆號發送消息後,公衆號回覆消息給微信用戶。包括如下類型:數據庫
本篇主要介紹前三種。服務器
使用Senparc.Weixin框架來快速處理各類接收事件推送,實現很是簡單,自定義一個繼承MessageHandler的類,重寫這些類型的方法便可。注意:DefaultResponseMessage必須重寫,用於返回沒有處理過的消息類型(也能夠用於默認消息,如幫助信息等);其中全部原OnXX的抽象方法已經都改成虛方法,能夠沒必要每一個都重寫。若不重寫,默認返回DefaultResponseMessage方法中的結果。微信
自定義消息處理類:網絡
public partial class CustomMessageHandler : MessageHandler<MessageContext<IRequestMessageBase, IResponseMessageBase>> { public CustomMessageHandler(Stream inputStream, int maxRecordCount = 0) : base(inputStream, null, maxRecordCount) { WeixinContext.ExpireMinutes = 3; } public override void OnExecuting() { //測試MessageContext.StorageData if (CurrentMessageContext.StorageData == null) { CurrentMessageContext.StorageData = 0; } base.OnExecuting(); } public override void OnExecuted() { base.OnExecuted(); CurrentMessageContext.StorageData = ((int)CurrentMessageContext.StorageData) + 1; } }
定義好事件處理類後,分別重寫上面提到幾種接收事件推送的事件便可。
咱們能夠經過重寫MessageHandler裏的這幾種類型方法來處理咱們的業務,固然也能夠只重寫須要的部分類型,不須要的類型能夠不重寫,只須要定義一個統一的DefaultResponseMessage微信公衆平臺
public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage) { //全部沒有被處理的消息會默認返回這裏的結果 var responseMessage = this.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "這條消息來自DefaultResponseMessage。"; return responseMessage; }
上一篇咱們就已經提到過微信服務器在5秒內收不到響應會斷掉鏈接,而且從新發起請求,總共重試三次。如此以來,咱們模擬有這樣一個場景:當用戶關注微信帳號時,獲取當前用戶信息,而後將信息寫到數據庫中,相似網站的註冊。假設這個關注事件中,咱們須要處理比較複雜的業務邏輯。如送積分,寫用戶日誌,分配用戶組等等一系列的邏輯須要執行,或者網絡環境比較複雜,沒法保證5秒內響應當前用戶的操做,那若是當操做還沒有完成,微信服務器又給咱們的服務器推送了一條相同的關注事件,咱們將再次執行咱們的那些邏輯,這樣就有可能致使數據庫中出現重複的數據(有的童鞋就會說了,我在插入數據以前先判斷當前是否已經存在了,若是存在了就不執行插入的操做。我想說的是,我當初也是這樣想的,但真實的運行環境和咱們的調試環境仍是有差距的,直到發現數據庫中有很多重複的用戶信息時,我才發現消息去重的重要性。)。框架
消息的去重普通消息和事件消息是有區別的。普通消息使用msgid,而事件消息使用FromUserName + CreateTime。分佈式
用戶在關注與取消關注公衆號時,微信會把這個事件推送到開發者填寫的URL。方便開發者給用戶下發歡迎消息或者作賬號的解綁。ide
假如服務器沒法保證在五秒內處理並回復,能夠直接回復空串,微信服務器不會對此做任何處理,而且不會發起重試。
關注或取消事件推送XML數據包示例:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[subscribe]]></Event> </xml>
參數說明:
參數 描述 ToUserName 開發者微信號 FromUserName 發送方賬號(一個OpenID) CreateTime 消息建立時間 (整型) MsgType 消息類型,event Event 事件類型,subscribe(訂閱)、unsubscribe(取消訂閱)
關注事件咱們只須要重寫OnEvent_SubscribeRequest事件代碼便可,以下咱們返回了一個文本消息,實現代碼參考:
/// <summary> /// 訂閱(關注)事件 /// </summary> /// <returns></returns> public override IResponseMessageBase OnEvent_SubscribeRequest(RequestMessageEvent_Subscribe requestMessage) { var responseMessage = CreateResponseMessage<ResponseMessageNews>(); foreach (var model in messageList) { responseMessage.Articles.Add(new Article() { Title = "國思公衆號", Description = "歡迎關注國思軟件公衆號,更多內容穩步官網,多謝!", PicUrl = "http://www.rdiframework.net/WeiXin.png", Url = "http://www.rdiframework.net/" }); } return responseMessage; }
在上面的關注事件中,用戶關注公衆號就會自動執行上面的事件代碼,咱們就能夠在事件代碼中作相關的業務處理,如綁定用戶分組、增長用戶到本地等等。同時推送一條歡迎消息返回到用戶手機上。
取消關注事件與關注事件相似,主要是事件變成了unsubscribe(取消關注)。取消關注事件-unsubscribe的主要意義在於及時刪除網站應用中已經記錄的OpenID綁定,消除冗餘數據,而且關注用戶流失的狀況。
取消關注事件咱們只須要重寫OnEvent_UnsubscribeRequest事件代碼便可,以下咱們返回了一個文本消息,實現代碼參考:
/// <summary> /// 退訂/取消關注 /// 實際上用戶沒法收到非訂閱帳號的消息,因此這裏能夠隨便寫。 /// unsubscribe事件的意義在於及時刪除網站應用中已經記錄的OpenID綁定,消除冗餘數據。而且關注用戶流失的狀況。 /// </summary> /// <returns></returns> public override IResponseMessageBase OnEvent_UnsubscribeRequest(RequestMessageEvent_Unsubscribe requestMessage) { int returnValue = RDIFrameworkService.Instance.WeixinBasicService.UserUnsubscribeByOpenId(Id,requestMessage.FromUserName);//退 var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "有空再來"; return responseMessage; }
上面的代碼在用戶取消公衆號的關注時就會自動執行,能夠看到咱們有一行代碼針對用戶取消關注時執行的業務邏輯,同時返回了一個文本消息。實際用戶已經取消關注,返回的消息也返回不到用戶手機上的。
用戶掃描帶場景值二維碼時,可能推送如下兩種事件:
對於第一種上面已經講了,這裏就只說明下第二種。
推送XML數據包示例:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[SCAN]]></Event> <EventKey><![CDATA[SCENE_VALUE]]></EventKey> <Ticket><![CDATA[TICKET]]></Ticket> </xml>
參數說明:
參數 描述 ToUserName 開發者微信號 FromUserName 發送方賬號(一個OpenID) CreateTime 消息建立時間 (整型) MsgType 消息類型,event Event 事件類型,SCAN EventKey 事件KEY值,是一個32位無符號整數,即建立二維碼時的二維碼scene_id Ticket 二維碼的ticket,可用來換取二維碼圖片
對於生成帶參數的二維碼咱們會在後面的文章中專門介紹,這兒咱們瞭解一個這個概念。爲了知足用戶渠道推廣分析和用戶賬號綁定等場景的須要,公衆平臺提供了生成帶參數二維碼的接口。使用該接口能夠得到多個帶不一樣場景值的二維碼,用戶掃描後,公衆號能夠接收到事件推送。具體官方技術文檔可參考:生成帶參數的二維碼
目前有2種類型的二維碼:
一、臨時二維碼,是有過時時間的,最長能夠設置爲在二維碼生成後的30天(即2592000秒)後過時,但可以生成較多數量。臨時二維碼主要用於賬號綁定等不要求二維碼永久保存的業務場景
二、永久二維碼,是無過時時間的,但數量較少(目前爲最多10萬個)。永久二維碼主要用於適用於賬號綁定、用戶來源統計等場景。
掃描帶參數二維碼事件只須要重寫OnEvent_ScanRequest事件代碼便可,以下咱們返回了一個文本消息,實現代碼參考:
public override IResponseMessageBase OnEvent_ScanRequest(RequestMessageEvent_Scan requestMessage) { //經過掃描關注 var responseMessage = CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = responseMessage.Content ?? string.Format("歡迎關注國思軟件,經過掃描二維碼進入,場景值:{0}", requestMessage.EventKey); return responseMessage; }
在上面的代碼中用戶掃描了帶場景值的二維碼進入公衆號後咱們返回了一個提示的文本消息。這是很是有用的功能,經常使用途推廣,能夠根據不一樣的二維碼場景值分別作不一樣的業務處理,如能夠統計關注的每個粉絲從哪裏來的,作到渠道推廣分析,可是關注的都是同一個公衆號。
微信公衆號生成帶參數的二維碼有何用途?
用戶贊成上報地理位置後,每次進入公衆號會話時,都會在進入時上報地理位置,或在進入會話後每5秒上報一次地理位置,公衆號能夠在公衆平臺網站中修改以上設置。上報地理位置時,微信會將上報地理位置事件推送到開發者填寫的URL。要獲取用戶地址位置,須要在微信公衆平臺開發者中心開啓上報地理位置功能,開啓以後會在用戶首次進入公衆號時,彈出是否容許上報地理位置選項,若是選擇容許則在用戶每次進入公衆號會話的時候微信會以XML形式將用戶的地理位置上報到你開發者中心填寫的URL上。
注意:用戶地理位置是被動獲取的,需用戶贊成後纔會上報,微信公衆平臺開發不能主動獲取用戶地理位置。
推送XML數據包示例:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[LOCATION]]></Event> <Latitude>23.137466</Latitude> <Longitude>113.352425</Longitude> <Precision>119.385040</Precision> </xml>
參數說明:
參數 描述 ToUserName 開發者微信號 FromUserName 發送方賬號(一個OpenID) CreateTime 消息建立時間 (整型) MsgType 消息類型,event Event 事件類型,LOCATION Latitude 地理位置緯度 Longitude 地理位置經度 Precision 地理位置精度
上報地理位置事件只須要重寫OnEvent_LocationRequest事件代碼便可,以下咱們返回了一個文本消息,實現代碼參考:
public override IResponseMessageBase OnEvent_LocationRequest(RequestMessageEvent_Location requestMessage) { //這裏是微信客戶端(經過微信服務器)自動發送過來的位置信息 var responseMessage = CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "這裏寫什麼都無所謂,好比:上帝愛你!"; return responseMessage;//這裏也能夠返回null(須要注意寫日誌時候null的問題) }
上報地理位置用處很是多,能夠用維度和經度獲取城市代號,調用天氣Api,也能夠用來監測企業員工的位置進行微信考勤。在微信運營的時候,用戶地理位置仍是咱們進行營銷策劃、廣告活動投放、用戶精準營銷的重要依據。
RDIFramework.NET — 基於.NET的快速信息化系統開發框架 — 系列目錄
RDIFramework.NET ━ .NET快速信息化系統開發框架 ━ 工做流程組件介紹
RDIFramework.NET框架SOA解決方案(集Windows服務、WinForm形式與IIS形式發佈)-分佈式應用
RDIFramework.NET代碼生成器全新V3.5版本發佈-重大升級
一路走來數個年頭,感謝RDIFramework.NET框架的支持者與使用者,你們能夠經過下面的地址瞭解詳情。
RDIFramework.NET官方網站:http://www.rdiframework.net/
RDIFramework.NET官方博客:http://blog.rdiframework.net/
同時須要說明的,之後的全部技術文章以官方網站爲準,歡迎你們收藏!
RDIFramework.NET框架由專業團隊長期打造、一直在更新、一直在升級,請放心使用!
歡迎關注RDIFramework.net框架官方公衆微信(微信號:guosisoft),及時瞭解最新動態。
掃描二維碼當即關注