訊息回覆
處理請(qǐng)求,並回應(yīng)
#1)追蹤
也可參考官網(wǎng)文件:https ://mp.weixin.qq.com/wiki
當(dāng)微信使用者追蹤公眾帳號(hào)時(shí),可以給其適當(dāng)?shù)奶崾???梢允菤g迎詞,可以是幫助提示。範(fàn)例程式碼如下:
?class?EventHandler?:?IHandler ????{????????///?<summary> ????????///?請(qǐng)求的xml????????///?</summary> ????????private?string?RequestXml?{?get;?set;?}????????///?<summary> ????????///?構(gòu)造函數(shù)????????///?</summary> ????????///?<param name="requestXml"></param> ????????public?EventHandler(string?requestXml) ????????{????????????this.RequestXml?=?requestXml; ????????}????????///?<summary> ????????///?處理請(qǐng)求????????///?</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ù)小二,有事您開(kāi)口~\n\n"; ????????????????response?=?tm.GenerateContent(); ????????????}????????????return?response; ????????} ????}
官方給的介紹是這樣的
追蹤/取消追蹤事件
#用戶在追蹤與取消追蹤公眾號(hào)時(shí),微信會(huì)把這個(gè)事件推到開(kāi)發(fā)者填寫(xiě)的URL。方便開(kāi)發(fā)者給用戶下發(fā)歡迎訊息或是做帳號(hào)的解綁。
微信伺服器在五秒鐘內(nèi)收不到回應(yīng)會(huì)斷掉連接,並且重新發(fā)起請(qǐng)求,總共重試三次。
關(guān)於重試的訊息排重,建議使用FromUserName + CreateTime 排重。
假如伺服器無(wú)法保證在五秒內(nèi)處理並回復(fù),可以直接回復(fù)空串,微信伺服器不會(huì)對(duì)此作任何處理,並且不會(huì)發(fā)起重試。
推送XML封包範(fàn)例:
描述 | ||
---|---|---|
#開(kāi)發(fā)者微訊號(hào) | ||
發(fā)送方帳號(hào)(一個(gè)OpenID) | ||
訊息建立時(shí)間(整數(shù)) | ||
訊息類型,event | ||
事件類型,subscribe(訂閱)、unsubscribe(取消訂閱) |
參數(shù) | 是否必須 | 說(shuō)明 |
---|---|---|
button | 是 | 一級(jí)菜單數(shù)組,個(gè)數(shù)應(yīng)為1~3個(gè) |
sub_button | 否 | 二級(jí)菜單數(shù)組,個(gè)數(shù)應(yīng)為1~5個(gè) |
type | 是 | 菜單的響應(yīng)動(dòng)作類型 |
name | 是 | 菜單標(biāo)題,不超過(guò)16個(gè)字節(jié),子菜單不超過(guò)60個(gè)字節(jié) |
key | click等點(diǎn)擊類型必須 | 菜單KEY值,用于消息接口推送,不超過(guò)128字節(jié) |
url | view類型必須 | 網(wǎng)頁(yè)鏈接,用戶點(diǎn)擊菜單可打開(kāi)鏈接,不超過(guò)1024字節(jié) |
media_id | media_id類型和view_limited類型必須 | 調(diào)用新增永久素材接口返回的合法media_id |
當(dāng)然也可以使用在線調(diào)試接口調(diào)試菜單是否設(shè)置正確:我要在線調(diào)試菜單接口
詳細(xì)步驟
1、首先獲取access_token
access_token是公眾號(hào)的全局唯一票據(jù),公眾號(hào)調(diào)用各接口時(shí)都需使用access_token。正常情況下access_token有效期為7200秒,重復(fù)獲取將導(dǎo)致上次獲取的access_token失效。
公眾號(hào)可以使用AppID和AppSecret調(diào)用本接口來(lái)獲取access_token。AppID和AppSecret可在開(kāi)發(fā)模式中獲得(需要已經(jīng)成為開(kāi)發(fā)者,且?guī)ぬ?hào)沒(méi)有異常狀態(tài))。注意調(diào)用所有微信接口時(shí)均需使用https協(xié)議。
接口調(diào)用請(qǐng)求說(shuō)明
http請(qǐng)求方式: GET https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
參數(shù)說(shuō)明
參數(shù) | 是否必須 | 說(shuō)明 |
---|---|---|
grant_type | 是 | 獲取access_token填寫(xiě)client_credential |
appid | 是 | 第三方用戶唯一憑證 |
secret | 是 | 第三方用戶唯一憑證密鑰,既appsecret |
返回說(shuō)明
正常情況下,微信會(huì)返回下述JSON數(shù)據(jù)包給公眾號(hào):
{"access_token":"ACCESS_TOKEN","expires_in":7200}
參數(shù) | 說(shuō)明 |
---|---|
access_token | 獲取到的憑證 |
expires_in | 憑證有效時(shí)間,單位:秒 |
錯(cuò)誤時(shí)微信會(huì)返回錯(cuò)誤碼等信息,JSON數(shù)據(jù)包示例如下(該示例為AppID無(wú)效錯(cuò)誤):
{"errcode":40013,"errmsg":"invalid appid"}
創(chuàng)建自定義菜單
自定義菜單能夠幫助公眾號(hào)豐富界面,讓用戶更好更快地理解公眾號(hào)的功能。
目前自定義菜單最多包括3個(gè)一級(jí)菜單,每個(gè)一級(jí)菜單最多包含5個(gè)二級(jí)菜單。一級(jí)菜單最多4個(gè)漢字,二級(jí)菜單最多7個(gè)漢字,多出來(lái)的部分將會(huì)以“...”代替。請(qǐng)注意,創(chuàng)建自定義菜單后,由于微信客戶端緩存,需要24小時(shí)微信客戶端才會(huì)展現(xiàn)出來(lái)。建議測(cè)試時(shí)可以嘗試取消關(guān)注公眾賬號(hào)后再次關(guān)注,則可以看到創(chuàng)建后的效果。
3、查詢菜單
使用接口創(chuàng)建自定義菜單后,開(kāi)發(fā)者還可使用接口查詢自定義菜單的結(jié)構(gòu)。
請(qǐng)求說(shuō)明
http請(qǐng)求方式:GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
返回說(shuō)明
對(duì)應(yīng)創(chuàng)建接口,正確的Json返回結(jié)果: {"menu":{"button":[{"type":"click","name":"今日歌曲","key":"V1001_TODAY_MUSIC","sub_button":[]},{"type":"click","name":"歌手簡(jiǎn)介","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)建自定義菜單后,開(kāi)發(fā)者還可使用接口刪除當(dāng)前使用的自定義菜單。
請(qǐng)求說(shuō)明
http請(qǐng)求方式:GET https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN
返回說(shuō)明
對(duì)應(yīng)創(chuàng)建接口,正確的Json返回結(jié)果: {"errcode":0,"errmsg":"ok"}
5、事件處理
用戶點(diǎn)擊自定義菜單后,如果菜單按鈕設(shè)置為click類型,則微信會(huì)把此次點(diǎn)擊事件推送給開(kāi)發(fā)者,注意view類型(跳轉(zhuǎn)到URL)的菜單點(diǎn)擊不會(huì)上報(bào)。
推送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ù)說(shuō)明:
參數(shù) | 描述 |
---|---|
ToUserName | 開(kāi)發(fā)者微信號(hào) |
FromUserName | 發(fā)送方帳號(hào)(一個(gè)OpenID) |
CreateTime | 消息創(chuàng)建時(shí)間 (整型) |
MsgType | 消息類型,event |
Event | 事件類型,CLICK |
EventKey | 事件KEY值,與自定義菜單接口中KEY值對(duì)應(yīng) |
實(shí)例講解
我們將會(huì)在上一篇的基礎(chǔ)上,添加自定義菜單的功能
1、獲取access_token
首先需要得到AppId和AppSecret
當(dāng)你成為開(kāi)發(fā)者后,自然能夠在,開(kāi)發(fā)者模式,便可看到這兩個(gè)值,可以重置。
然后調(diào)用按照二.1中所示,進(jìn)行操作。
注意:access_token有過(guò)期時(shí)間,如果過(guò)期,需要重新獲取。
private static DateTime GetAccessToken_Time; /// <summary> /// 過(guò)期時(shí)間為7200秒 /// </summary> private static int Expires_Period = 7200; /// <summary> /// /// </summary> private static string mAccessToken; /// <summary> /// /// </summary> public static string AccessToken { get { //如果為空,或者過(guò)期,需要重新獲取 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是否過(guò)期 /// </summary> /// <returns>bool</returns> private static bool HasExpired() { if (GetAccessToken_Time != null) { //過(guò)期時(shí)間,允許有一定的誤差,一分鐘。獲取時(shí)間消耗 if (DateTime.Now > GetAccessToken_Time.AddSeconds(Expires_Period).AddSeconds(-60)) { return true; } } return false; }
2、設(shè)置菜單
菜單需根據(jù)需要,按照實(shí)際要求進(jìn)行設(shè)定。
這里我們只做簡(jiǎn)單的演示。
然后還提供了友情鏈接,這里提供了view類型的菜單,直接可以跳轉(zhuǎn)至URL頁(yè)面,為跳轉(zhuǎn)做個(gè)好的演示。
具體菜單如下:
{ "button": [ { "name": "測(cè)試跳轉(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、管理菜單
因?yàn)椴藛蔚淖兏鼪](méi)有那么頻繁,因此通過(guò)txt文件來(lái)設(shè)置菜單,并通過(guò)管理界面來(lái)管理菜單。
主要的管理功能:
1)從文件加載菜單
2)創(chuàng)建菜單。即將菜單通知微信服務(wù)端,并更新至微信客戶端
3)查詢菜單。獲取當(dāng)前系統(tǒng)的菜單。
4)刪除菜單。從微信服務(wù)器刪除菜單,也可以刪除后再創(chuàng)建。
實(shí)現(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://www.miracleart.cn/{0}", Context.AccessToken); return HttpUtility.GetData(url); } /// <summary> /// 創(chuàng)建菜單 /// </summary> public static void CreateMenu(string menu) { string url = string.Format("http://www.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://www.miracleart.cn/{0}", Context.AccessToken); HttpUtility.GetData(url); } /// <summary> /// 加載菜單 /// </summary> /// <returns></returns> public static string LoadMenu() { return FileUtility.Read(Menu_Data_Path); } }
4、基本方法
上面的代碼,其實(shí)我們對(duì)一些公共功能做了封裝。如進(jìn)行g(shù)et請(qǐng)求、POST提交等操作,讀取文件等。
這里我們提供進(jìn)行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ā)送請(qǐng)求 /// </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ā)送請(qǐng)求 /// </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ā)送請(qǐng)求 /// </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è)計(jì)ASPX或者WinForm一樣,都要綁定按鈕的事件。這里只是通過(guò)XML消息將請(qǐng)求傳遞過(guò)來(lái)。
通過(guò)“2、設(shè)置菜單"中具體的菜單內(nèi)容,我們便已經(jīng)知道需要進(jìn)行哪些事件處理了。對(duì)于按鈕類型為view的,無(wú)須處理,它會(huì)自動(dòng)跳轉(zhuǎn)至指定url.
需要處理的點(diǎn)擊事件:
1)贊一下
2)幫助
這個(gè)還要沿用上章中的事件處理器EventHandler來(lái)擴(kuò)展處理。
具體的實(shí)現(xiàn)代碼吧:
class EventHandler : IHandler { /// <summary> /// 請(qǐng)求的xml /// </summary> private string RequestXml { get; set; } /// <summary> /// 構(gòu)造函數(shù) /// </summary> /// <param name="requestXml"></param> public EventHandler(string requestXml) { this.RequestXml = requestXml; } /// <summary> /// 處理請(qǐng)求 /// </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ù)小二,有事您說(shuō)話~\n\n"; return tm.GenerateContent(); } /// <summary> /// 處理點(diǎn)擊事件 /// </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)試效果
圖中點(diǎn)擊的幫助菜單,如果大家仔細(xì)觀察,會(huì)發(fā)現(xiàn)后面斷點(diǎn)進(jìn)入第二次了,這是因?yàn)榍懊嫣岬降?,微信服?wù)器5秒未回復(fù),就會(huì)重復(fù)嘗試發(fā)3次請(qǐng)求,所以就會(huì)有多次進(jìn)入斷點(diǎn)的效果。
最終效果
Demo下載
鏈接:點(diǎn)我下載? 密碼:41dt
Git地址:https://github.com/XiaoYong666/-Demo
?
更多微信公眾號(hào)開(kāi)發(fā)自動(dòng)消息回復(fù)和自定義菜單?相關(guān)文章請(qǐng)關(guān)注PHP中文網(wǎng)!
?

熱AI工具

Undress AI Tool
免費(fèi)脫衣圖片

Undresser.AI Undress
人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門(mén)文章

熱工具

記事本++7.3.1
好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強(qiáng)大的PHP整合開(kāi)發(fā)環(huán)境

Dreamweaver CS6
視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版
神級(jí)程式碼編輯軟體(SublimeText3)
