消息回復(fù)
處理請求,并響應(yīng)
1)關(guān)注
也可參考官網(wǎng)文檔:https://mp.weixin.qq.com/wiki
當(dāng)微信用戶關(guān)注公眾賬號時,可以給其適當(dāng)?shù)奶崾???梢允菤g迎詞,可以是幫助提示。示例代碼如下:
?class?EventHandler?:?IHandler ????{????????///?<summary> ????????///?請求的xml????????///?</summary> ????????private?string?RequestXml?{?get;?set;?}????????///?<summary> ????????///?構(gòu)造函數(shù)????????///?</summary> ????????///?<param name="requestXml"></param> ????????public?EventHandler(string?requestXml) ????????{????????????this.RequestXml?=?requestXml; ????????}????????///?<summary> ????????///?處理請求????????///?</summary> ????????///?<returns></returns> ????????public?string?HandleRequest() ????????{????????????string?response?=?string.Empty; ????????????EventMessage?em?=?EventMessage.LoadFromXml(RequestXml);????????????if?(em.Event.Equals("subscribe",StringComparison.OrdinalIgnoreCase)) ????????????{????????????????//回復(fù)歡迎消息 ????????????????TextMessage?tm?=?new?TextMessage(); ????????????????tm.ToUserName?=?em.FromUserName; ????????????????tm.FromUserName?=?em.ToUserName; ????????????????tm.CreateTime?=?Common.GetNowTime(); ????????????????tm.Content?=?"歡迎您關(guān)注我們,我是服務(wù)小二,有事您開口~\n\n"; ????????????????response?=?tm.GenerateContent(); ????????????}????????????return?response; ????????} ????}
官方給出的介紹是這樣的
關(guān)注/取消關(guān)注事件
用戶在關(guān)注與取消關(guān)注公眾號時,微信會把這個事件推送到開發(fā)者填寫的URL。方便開發(fā)者給用戶下發(fā)歡迎消息或者做帳號的解綁。
微信服務(wù)器在五秒內(nèi)收不到響應(yīng)會斷掉連接,并且重新發(fā)起請求,總共重試三次。
關(guān)于重試的消息排重,推薦使用FromUserName + CreateTime 排重。
假如服務(wù)器無法保證在五秒內(nèi)處理并回復(fù),可以直接回復(fù)空串,微信服務(wù)器不會對此作任何處理,并且不會發(fā)起重試。
推送XML數(shù)據(jù)包示例:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[subscribe]]></Event> </xml> |
參數(shù)說明:
參數(shù) | 描述 |
---|---|
ToUserName | 開發(fā)者微信號 |
FromUserName | 發(fā)送方帳號(一個OpenID) |
CreateTime | 消息創(chuàng)建時間 (整型) |
MsgType | 消息類型,event |
Event | 事件類型,subscribe(訂閱)、unsubscribe(取消訂閱) |
也可使用微信在線接口調(diào)試工具測試是否正常:取消/關(guān)注事件接口在線調(diào)試
2)問候
簡單的交流問候,比如你好、幫助等等,跟我們使用微信聊天一樣,不過回應(yīng)是由我們的程序響應(yīng)。具體功能,可以根據(jù)自己的需要進行添加。
微信本來就是溝通的平臺。這個案例,可以用于在線服務(wù)機器人,類似于淘寶的客服機器人,可是我們這個是微信版的。
其實,很簡單,獲取請求消息,根據(jù)關(guān)鍵字來匹配回應(yīng)。當(dāng)然這里可能要做的工作很多,如何支持智能匹配,如何支持模糊匹配等。
/// <summary> /// 文本信息處理類 /// </summary> public class TextHandler : IHandler { /// <summary> /// 請求的XML /// </summary> private string RequestXml { get; set; } /// <summary> /// 構(gòu)造函數(shù) /// </summary> /// <param name="requestXml">請求的xml</param> public TextHandler(string requestXml) { this.RequestXml = requestXml; } /// <summary> /// 處理請求 /// </summary> /// <returns></returns> public string HandleRequest() { string response = string.Empty; TextMessage tm = TextMessage.LoadFromXml(RequestXml); string content = tm.Content.Trim(); if (string.IsNullOrEmpty(content)) { response = "您什么都沒輸入,沒法幫您啊,%>_<%。"; } else { if (content.StartsWith("tq", StringComparison.OrdinalIgnoreCase)) { string cityName = content.Substring(2).Trim(); response = WeatherHelper.GetWeather(cityName); } else { response = HandleOther(content); } } tm.Content = response; //進行發(fā)送者、接收者轉(zhuǎn)換 string temp = tm.ToUserName; tm.ToUserName = tm.FromUserName; tm.FromUserName = temp; response = tm.GenerateContent(); return response; } /// <summary> /// 處理其他消息 /// </summary> /// <param name="tm"></param> /// <returns></returns> private string HandleOther(string requestContent) { string response = string.Empty; if (requestContent.Contains("你好") || requestContent.Contains("您好")) { response = "您也好~"; } else if (requestContent.Contains("傻")) { response = "我不傻!哼~ "; } else if (requestContent.Contains("shit") || requestContent.Contains("小王八蛋")) { response = "哼,你說臟話! "; } else if (requestContent.Contains("是誰")) { response = "我是大哥大,有什么能幫您的嗎?~"; } else if (requestContent.Contains("再見")) { response = "再見!"; } else if (requestContent.Contains("bye")) { response = "Bye!"; } else if (requestContent.Contains("謝謝")) { response = "不客氣!嘿嘿"; } else if (requestContent == "h" || requestContent == "H" || requestContent.Contains("幫助")) { response = @"有事找警察"; } else { response = "您說的,可惜,我沒明白啊,試試其他關(guān)鍵字吧。"; } return response; } }
實現(xiàn)效果如圖所示:
自定義菜單
首先呢,我們要了解下微信公眾號開發(fā)里面菜單有哪些類型呢?
自定義菜單接口可實現(xiàn)多種類型按鈕,如下:
請注意,3到8的所有事件,僅支持微信iPhone5.4.1以上版本,和Android5.4以上版本的微信用戶,舊版本微信用戶點擊后將沒有回應(yīng),開發(fā)者也不能正常接收到事件推送。9和10,是專門給第三方平臺旗下未微信認證(具體而言,是資質(zhì)認證未通過)的訂閱號準(zhǔn)備的事件類型,它們是沒有事件推送的,能力相對受限,其他類型的公眾號不必使用。
接口調(diào)用請求說明
http請求方式:POST(請使用https協(xié)議) http://m.miracleart.cn/
click和view的請求示例
{ "button":[ { "type":"click", "name":"今日歌曲", "key":"V1001_TODAY_MUSIC" }, { "name":"菜單", "sub_button":[ { "type":"view", "name":"搜索", "url":"http://m.miracleart.cn/" }, { "type":"view", "name":"視頻", "url":"http://m.miracleart.cn/" }, { "type":"click", "name":"贊一下我們", "key":"V1001_GOOD" }] }] }
參數(shù)說明
參數(shù) | 是否必須 | 說明 |
---|---|---|
button | 是 | 一級菜單數(shù)組,個數(shù)應(yīng)為1~3個 |
sub_button | 否 | 二級菜單數(shù)組,個數(shù)應(yīng)為1~5個 |
type | 是 | 菜單的響應(yīng)動作類型 |
name | 是 | 菜單標(biāo)題,不超過16個字節(jié),子菜單不超過60個字節(jié) |
key | click等點擊類型必須 | 菜單KEY值,用于消息接口推送,不超過128字節(jié) |
url | view類型必須 | 網(wǎng)頁鏈接,用戶點擊菜單可打開鏈接,不超過1024字節(jié) |
media_id | media_id類型和view_limited類型必須 | 調(diào)用新增永久素材接口返回的合法media_id |
當(dāng)然也可以使用在線調(diào)試接口調(diào)試菜單是否設(shè)置正確:我要在線調(diào)試菜單接口
詳細步驟
1、首先獲取access_token
access_token是公眾號的全局唯一票據(jù),公眾號調(diào)用各接口時都需使用access_token。正常情況下access_token有效期為7200秒,重復(fù)獲取將導(dǎo)致上次獲取的access_token失效。
公眾號可以使用AppID和AppSecret調(diào)用本接口來獲取access_token。AppID和AppSecret可在開發(fā)模式中獲得(需要已經(jīng)成為開發(fā)者,且?guī)ぬ枦]有異常狀態(tài))。注意調(diào)用所有微信接口時均需使用https協(xié)議。
接口調(diào)用請求說明
http請求方式: GET https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
參數(shù)說明
參數(shù) | 是否必須 | 說明 |
---|---|---|
grant_type | 是 | 獲取access_token填寫client_credential |
appid | 是 | 第三方用戶唯一憑證 |
secret | 是 | 第三方用戶唯一憑證密鑰,既appsecret |
返回說明
正常情況下,微信會返回下述JSON數(shù)據(jù)包給公眾號:
{"access_token":"ACCESS_TOKEN","expires_in":7200}
參數(shù) | 說明 |
---|---|
access_token | 獲取到的憑證 |
expires_in | 憑證有效時間,單位:秒 |
錯誤時微信會返回錯誤碼等信息,JSON數(shù)據(jù)包示例如下(該示例為AppID無效錯誤):
{"errcode":40013,"errmsg":"invalid appid"}
創(chuàng)建自定義菜單
自定義菜單能夠幫助公眾號豐富界面,讓用戶更好更快地理解公眾號的功能。
目前自定義菜單最多包括3個一級菜單,每個一級菜單最多包含5個二級菜單。一級菜單最多4個漢字,二級菜單最多7個漢字,多出來的部分將會以“...”代替。請注意,創(chuàng)建自定義菜單后,由于微信客戶端緩存,需要24小時微信客戶端才會展現(xiàn)出來。建議測試時可以嘗試取消關(guān)注公眾賬號后再次關(guān)注,則可以看到創(chuàng)建后的效果。
3、查詢菜單
使用接口創(chuàng)建自定義菜單后,開發(fā)者還可使用接口查詢自定義菜單的結(jié)構(gòu)。
請求說明
http請求方式:GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
返回說明
對應(yīng)創(chuàng)建接口,正確的Json返回結(jié)果: {"menu":{"button":[{"type":"click","name":"今日歌曲","key":"V1001_TODAY_MUSIC","sub_button":[]},{"type":"click","name":"歌手簡介","key":"V1001_TODAY_SINGER","sub_button":[]},{"name":"菜單","sub_button":[{"type":"view","name":"搜索","url":"http://www.soso.com/","sub_button":[]},{"type":"view","name":"視頻","url":"http://v.qq.com/","sub_button":[]},{"type":"click","name":"贊一下我們","key":"V1001_GOOD","sub_button":[]}]}]}}
4、刪除菜單
使用接口創(chuàng)建自定義菜單后,開發(fā)者還可使用接口刪除當(dāng)前使用的自定義菜單。
請求說明
http請求方式:GET https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN
返回說明
對應(yīng)創(chuàng)建接口,正確的Json返回結(jié)果: {"errcode":0,"errmsg":"ok"}
5、事件處理
用戶點擊自定義菜單后,如果菜單按鈕設(shè)置為click類型,則微信會把此次點擊事件推送給開發(fā)者,注意view類型(跳轉(zhuǎn)到URL)的菜單點擊不會上報。
推送XML數(shù)據(jù)包示例:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[CLICK]]></Event> <EventKey><![CDATA[EVENTKEY]]></EventKey> </xml>
參數(shù)說明:
參數(shù) | 描述 |
---|---|
ToUserName | 開發(fā)者微信號 |
FromUserName | 發(fā)送方帳號(一個OpenID) |
CreateTime | 消息創(chuàng)建時間 (整型) |
MsgType | 消息類型,event |
Event | 事件類型,CLICK |
EventKey | 事件KEY值,與自定義菜單接口中KEY值對應(yīng) |
實例講解
我們將會在上一篇的基礎(chǔ)上,添加自定義菜單的功能
1、獲取access_token
首先需要得到AppId和AppSecret
當(dāng)你成為開發(fā)者后,自然能夠在,開發(fā)者模式,便可看到這兩個值,可以重置。
然后調(diào)用按照二.1中所示,進行操作。
注意:access_token有過期時間,如果過期,需要重新獲取。
private static DateTime GetAccessToken_Time; /// <summary> /// 過期時間為7200秒 /// </summary> private static int Expires_Period = 7200; /// <summary> /// /// </summary> private static string mAccessToken; /// <summary> /// /// </summary> public static string AccessToken { get { //如果為空,或者過期,需要重新獲取 if (string.IsNullOrEmpty(mAccessToken) || HasExpired()) { //獲取 mAccessToken = GetAccessToken(AppID, AppSecret); } return mAccessToken; } } /// <summary> /// /// </summary> /// <param name="appId"></param> /// <param name="appSecret"></param> /// <returns></returns> private static string GetAccessToken(string appId, string appSecret) { string url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appId, appSecret); string result = HttpUtility.GetData(url); XDocument doc = XmlUtility.ParseJson(result, "root"); XElement root = doc.Root; if (root != null) { XElement access_token = root.Element("access_token"); if (access_token != null) { GetAccessToken_Time = DateTime.Now; if (root.Element("expires_in")!=null) { Expires_Period = int.Parse(root.Element("expires_in").Value); } return access_token.Value; } else { GetAccessToken_Time = DateTime.MinValue; } } return null; } /// <summary> /// 判斷Access_token是否過期 /// </summary> /// <returns>bool</returns> private static bool HasExpired() { if (GetAccessToken_Time != null) { //過期時間,允許有一定的誤差,一分鐘。獲取時間消耗 if (DateTime.Now > GetAccessToken_Time.AddSeconds(Expires_Period).AddSeconds(-60)) { return true; } } return false; }
2、設(shè)置菜單
菜單需根據(jù)需要,按照實際要求進行設(shè)定。
這里我們只做簡單的演示。
然后還提供了友情鏈接,這里提供了view類型的菜單,直接可以跳轉(zhuǎn)至URL頁面,為跳轉(zhuǎn)做個好的演示。
具體菜單如下:
{ "button": [ { "name": "測試跳轉(zhuǎn)", "sub_button": [ { "type": "view", "name": "搜索", "url": "http://www.baidu.com/" }, { "type": "view", "name": "視頻", "url": "http://v.qq.com/" }, { "type": "click", "name": "贊一下我們", "key": "BTN_GOOD" } ] }, { "type": "view", "name": "設(shè)備狀態(tài)", "url": "http://vanrui.com/weixin" }, { "type": "click", "name": "幫助", "key": "BTN_HELP" } ] }
3、管理菜單
因為菜單的變更沒有那么頻繁,因此通過txt文件來設(shè)置菜單,并通過管理界面來管理菜單。
主要的管理功能:
1)從文件加載菜單
2)創(chuàng)建菜單。即將菜單通知微信服務(wù)端,并更新至微信客戶端
3)查詢菜單。獲取當(dāng)前系統(tǒng)的菜單。
4)刪除菜單。從微信服務(wù)器刪除菜單,也可以刪除后再創(chuàng)建。
實現(xiàn)代碼如下:
public class MenuManager { /// <summary> /// 菜單文件路徑 /// </summary> private static readonly string Menu_Data_Path = System.AppDomain.CurrentDomain.BaseDirectory + "/Data/menu.txt"; /// <summary> /// 獲取菜單 /// </summary> public static string GetMenu() { string url = string.Format("http://m.miracleart.cn/{0}", Context.AccessToken); return HttpUtility.GetData(url); } /// <summary> /// 創(chuàng)建菜單 /// </summary> public static void CreateMenu(string menu) { string url = string.Format("http://m.miracleart.cn/{0}", Context.AccessToken); //string menu = FileUtility.Read(Menu_Data_Path); HttpUtility.SendHttpRequest(url, menu); } /// <summary> /// 刪除菜單 /// </summary> public static void DeleteMenu() { string url = string.Format("http://m.miracleart.cn/{0}", Context.AccessToken); HttpUtility.GetData(url); } /// <summary> /// 加載菜單 /// </summary> /// <returns></returns> public static string LoadMenu() { return FileUtility.Read(Menu_Data_Path); } }
4、基本方法
上面的代碼,其實我們對一些公共功能做了封裝。如進行g(shù)et請求、POST提交等操作,讀取文件等。
這里我們提供進行g(shù)et、Post提交的方法案例代碼,如果使用,建議優(yōu)化。
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Net;using System.Text;using System.Threading.Tasks;namespace WeChat.Utility { /// <summary> /// 幫助類 /// </summary> class HttpUtility { /// <summary> /// 發(fā)送請求 /// </summary> /// <param name="url">Url地址</param> /// <param name="data">數(shù)據(jù)</param> public static string SendHttpRequest(string url, string data) { return SendPostHttpRequest(url, "application/x-www-form-urlencoded", data); } /// <summary> /// /// </summary> /// <param name="url"></param> /// <returns></returns> public static string GetData(string url) { return SendGetHttpRequest(url, "application/x-www-form-urlencoded"); } /// <summary> /// 發(fā)送請求 /// </summary> /// <param name="url">Url地址</param> /// <param name="method">方法(post或get)</param> /// <param name="method">數(shù)據(jù)類型</param> /// <param name="requestData">數(shù)據(jù)</param> public static string SendPostHttpRequest(string url, string contentType, string requestData) { WebRequest request = (WebRequest)HttpWebRequest.Create(url); request.Method = "POST"; byte[] postBytes = null; request.ContentType = contentType; postBytes = Encoding.UTF8.GetBytes(requestData); request.ContentLength = postBytes.Length; using (Stream outstream = request.GetRequestStream()) { outstream.Write(postBytes, 0, postBytes.Length); } string result = string.Empty; using (WebResponse response = request.GetResponse()) { if (response != null) { using (Stream stream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) { result = reader.ReadToEnd(); } } } } return result; } /// <summary> /// 發(fā)送請求 /// </summary> /// <param name="url">Url地址</param> /// <param name="method">方法(post或get)</param> /// <param name="method">數(shù)據(jù)類型</param> /// <param name="requestData">數(shù)據(jù)</param> public static string SendGetHttpRequest(string url, string contentType) { WebRequest request = (WebRequest)HttpWebRequest.Create(url); request.Method = "GET"; request.ContentType = contentType; string result = string.Empty; using (WebResponse response = request.GetResponse()) { if (response != null) { using (Stream stream = response.GetResponseStream()) { using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) { result = reader.ReadToEnd(); } } } } return result; } } }
class XmlUtility { /// <summary> /// /// </summary> /// <param name="json"></param> /// <param name="rootName"></param> /// <returns></returns> public static XDocument ParseJson(string json,string rootName) { return JsonConvert.DeserializeXNode(json, rootName); } }
5、事件處理
設(shè)置了菜單,這下需要處理事件了。跟我們之前設(shè)計ASPX或者WinForm一樣,都要綁定按鈕的事件。這里只是通過XML消息將請求傳遞過來。
通過“2、設(shè)置菜單"中具體的菜單內(nèi)容,我們便已經(jīng)知道需要進行哪些事件處理了。對于按鈕類型為view的,無須處理,它會自動跳轉(zhuǎn)至指定url.
需要處理的點擊事件:
1)贊一下
2)幫助
這個還要沿用上章中的事件處理器EventHandler來擴展處理。
具體的實現(xiàn)代碼吧:
class EventHandler : IHandler { /// <summary> /// 請求的xml /// </summary> private string RequestXml { get; set; } /// <summary> /// 構(gòu)造函數(shù) /// </summary> /// <param name="requestXml"></param> public EventHandler(string requestXml) { this.RequestXml = requestXml; } /// <summary> /// 處理請求 /// </summary> /// <returns></returns> public string HandleRequest() { string response = string.Empty; EventMessage em = EventMessage.LoadFromXml(RequestXml); if (em != null) { switch (em.Event.ToLower()) { case ("subscribe"): response = SubscribeEventHandler(em); break; case "click": response = ClickEventHandler(em); break; } } return response; } /// <summary> /// 關(guān)注 /// </summary> /// <param name="em"></param> /// <returns></returns> private string SubscribeEventHandler(EventMessage em) { //回復(fù)歡迎消息 TextMessage tm = new TextMessage(); tm.ToUserName = em.FromUserName; tm.FromUserName = em.ToUserName; tm.CreateTime = Common.GetNowTime(); tm.Content = "歡迎您關(guān)注我們,我是服務(wù)小二,有事您說話~\n\n"; return tm.GenerateContent(); } /// <summary> /// 處理點擊事件 /// </summary> /// <param name="em"></param> /// <returns></returns> private string ClickEventHandler(EventMessage em) { string result = string.Empty; if (em != null && em.EventKey != null) { switch (em.EventKey.ToUpper()) { case "BTN_GOOD": result = btnGoodClick(em); break; case "BTN_HELP": result = btnHelpClick(em); break; } } return result; } /// <summary> /// 贊一下 /// </summary> /// <param name="em"></param> /// <returns></returns> private string btnGoodClick(EventMessage em) { //回復(fù)歡迎消息 TextMessage tm = new TextMessage(); tm.ToUserName = em.FromUserName; tm.FromUserName = em.ToUserName; tm.CreateTime = Common.GetNowTime(); tm.Content = @"謝謝您的支持!"; return tm.GenerateContent(); } /// <summary> /// 幫助 /// </summary> /// <param name="em"></param> /// <returns></returns> private string btnHelpClick(EventMessage em) { //回復(fù)歡迎消息 TextMessage tm = new TextMessage(); tm.ToUserName = em.FromUserName; tm.FromUserName = em.ToUserName; tm.CreateTime = Common.GetNowTime(); tm.Content = @"有事找警察~"; return tm.GenerateContent(); }
調(diào)試效果
圖中點擊的幫助菜單,如果大家仔細觀察,會發(fā)現(xiàn)后面斷點進入第二次了,這是因為前面提到的,微信服務(wù)器5秒未回復(fù),就會重復(fù)嘗試發(fā)3次請求,所以就會有多次進入斷點的效果。
最終效果
Demo下載
鏈接:點我下載? 密碼:41dt
Git地址:https://github.com/XiaoYong666/-Demo
?
更多微信公眾號開發(fā)自動消息回復(fù)和自定義菜單?相關(guān)文章請關(guān)注PHP中文網(wǎng)!
?

Alat AI Hot

Undress AI Tool
Gambar buka pakaian secara percuma

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)