微信公衆號開發C#系列-七、消息管理-接收事件推送

一、概述

在微信用戶和公衆號產生交互的過程當中,用戶的某些操做會使得微信服務器經過事件推送的形式通知到開發者在開發者中心處設置的服務器地址,從而開發者能夠獲取到該信息。其中,某些事件推送在發生後,是容許開發者回覆用戶的,某些則不容許git

咱們在上一篇微信公衆號開發C#系列-六、消息管理-普通消息接受處理中講到,微信的消息能夠大致分爲兩種類型,一種是包括:文本,語音,圖片等的普通消息,另外一種就是本篇要將的事件類型。包括:關注/取消關注事件,掃描帶參數二維碼事件,上報地理位置事件,自定義菜單相關事件等,本篇一一進行講解。介於偏於內容過多易產生閱讀疲勞,對於自定義菜單相關事件的處理咱們放在下一篇中講解。github

這裏的消息指的是傳統的微信公衆平臺消息交互,微信用戶向公衆號發送消息後,公衆號回覆消息給微信用戶。包括如下類型:數據庫

  1. 關注/取消關注事件:subscribe/unsubscribe
  2. 掃描帶參數二維碼事件:scan
  3. 上報地理位置事件:location
  4. 自定義菜單事件
  5. 點擊菜單拉取消息時的事件推送
  6. 點擊菜單跳轉連接時的事件推送

本篇主要介紹前三種。服務器

二、實現方式

使用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(取消訂閱)

4.1 關注事件

關注事件咱們只須要重寫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;
}

關注事件執行後效果

在上面的關注事件中,用戶關注公衆號就會自動執行上面的事件代碼,咱們就能夠在事件代碼中作相關的業務處理,如綁定用戶分組、增長用戶到本地等等。同時推送一條歡迎消息返回到用戶手機上。

4.2 取消關注事件

取消關注事件與關注事件相似,主要是事件變成了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;
}

上面的代碼在用戶取消公衆號的關注時就會自動執行,能夠看到咱們有一行代碼針對用戶取消關注時執行的業務邏輯,同時返回了一個文本消息。實際用戶已經取消關注,返回的消息也返回不到用戶手機上的。

五、掃描帶參數二維碼事件

用戶掃描帶場景值二維碼時,可能推送如下兩種事件:

  1. 若是用戶還未關注公衆號,則用戶能夠關注公衆號,關注後微信會將帶場景值關注事件推送給開發者。
  2. 若是用戶已經關注公衆號,則微信會將帶場景值掃描事件推送給開發者。

5.1 接口展現與實現方式

對於第一種上面已經講了,這裏就只說明下第二種。

推送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.2 生成帶參數的二維碼用途

微信公衆號生成帶參數的二維碼有何用途?

  1. 能夠區分粉絲來源,只須要生成不一樣的帶參數的二維碼,把這些二維碼分別投放到各個渠道,粉絲經過這些渠道二維碼進來就能夠區分粉絲來源,微號幫後臺渠道粉絲列表中有粉絲數及明細;
  2. 粉絲經過掃描渠道二維碼關注公衆號,會打標籤分組,好比粉絲掃商店A、B的二維碼進來的, 在微信公衆號後來的用戶管理中可查看到商店A/B二維碼名下的粉絲明細及分組狀況;
  3. 能夠生成多個不一樣的渠道二維碼配置不一樣的營銷活動,設置不一樣的關注回覆信息,讓粉絲第一時間瞭解活動動機,是否有興趣參與等等;
  4. 能夠利用渠道二維碼生成功能,能夠實現微信收款前關注公衆號,間接分析粉絲後續消費狀況;
  5. 考覈推廣員完成任務的進度,如以推廣名字生成多不個同的二維碼,分配給不一樣的推廣員,每一個推廣員吸引了多少粉絲關注公衆號,微號幫後臺均可以一一明細;
  6. 帶參數的二維碼也叫渠道二維碼或者場景二維碼,生存的數量有限,且是永久二維碼。當數量用完後能夠刪除一些不用的二維碼釋放出來,二次利用。

經過掃描帶場景值的二維碼進入

六、上報地理位置事件

用戶贊成上報地理位置後,每次進入公衆號會話時,都會在進入時上報地理位置,或在進入會話後每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,也能夠用來監測企業員工的位置進行微信考勤。在微信運營的時候,用戶地理位置仍是咱們進行營銷策劃、廣告活動投放、用戶精準營銷的重要依據。

參考文章

微信公衆平臺技術文檔-官方

Senparc.Weixin SDK + 官網示例源代碼

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),及時瞭解最新動態。

掃描二維碼當即關注

微信號:guosisoft

相關文章
相關標籤/搜索