對於每個POST請求,開發者在響應包(Get)中返回特定XML結構,對該消息進行響應(現支持回覆文本、圖片、圖文、語音、視頻、音樂)。請注意,回覆圖片等多媒體消息時須要預先上傳多媒體文件到微信服務器,只支持認證服務號。web
今天說說下面三個sql
一、關注回覆數據庫
二、自動回覆api
三、關鍵字回覆服務器
1、關注回覆,自動默認回覆微信
所謂關注回覆,就是當關注着搜到公衆號的時候,點擊關注以後,微信返回給用戶的信息,具體的實現辦法cookie
自動默認回覆,就是不管你發送什麼信息,若是沒有特別處理,系統默認回覆的信息。dom
接收微信的信息和發送信息,都是xml格式的,具體在開發文檔中都有具體的說明的,如今就來講說若是實現微信信息的處理和應答。curl
一、先把預先設置好的回覆信息保存到數據庫表裏面ide
CREATE TABLE [dbo].[w_reply]( [reply_id] [int] IDENTITY(1,1) NOT NULL, [reply_text] [varchar](max) NULL, [reply_type] [varchar](50) NULL, [article_id] [int] NULL, [wechat_id] [int] NULL, [reply_fangshi] [int] NULL, CONSTRAINT [PK_w_reply] PRIMARY KEY CLUSTERED ( [reply_id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
wechatapi.aspx頁面處理下面信息
二、接收微信發過來的信息
#region 接收微信消息 /// <summary> /// 接收微信信息 /// </summary> private void RequestMsg() { //接收信息流 Stream requestStream = System.Web.HttpContext.Current.Request.InputStream; byte[] requestByte = new byte[requestStream.Length]; requestStream.Read(requestByte, 0, (int)requestStream.Length); //轉換成字符串 string requestStr = Encoding.UTF8.GetString(requestByte); if (!string.IsNullOrEmpty(requestStr)) { //封裝請求類到xml文件中 XmlDocument requestDocXml = new XmlDocument(); requestDocXml.LoadXml(requestStr); XmlElement rootElement = requestDocXml.DocumentElement; XmlNode MsgType = rootElement.SelectSingleNode("MsgType"); //將XML文件封裝到實體類requestXml中 RequestXml requestXml = new RequestXml(); requestXml.ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText;//開發者微信號 requestXml.FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText;//發送方微信號 requestXml.CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText;//消息發送信息 requestXml.MsgType = MsgType.InnerText; //獲取接收信息的類型 switch (requestXml.MsgType) { //接收普通訊息 case "text"://文本信息 requestXml.Content = rootElement.SelectSingleNode("Content").InnerText; break; case "image"://圖片信息 requestXml.PicUrl = rootElement.SelectSingleNode("PicUrl").InnerText; break; case "location"://地理位置信息 requestXml.Location_X = rootElement.SelectSingleNode("Location_X").InnerText; requestXml.Location_Y = rootElement.SelectSingleNode("Location_Y").InnerText; break; //接收事件推送 //大概包括有:關注/取消關注事件、掃描帶參數二維碼事件、上報地理位置事件、自定義菜單事件、點擊菜單拉取消息時的事件推送、點擊菜單跳轉連接時的事件推送 case "event": requestXml.Event = rootElement.SelectSingleNode("Event").InnerText; requestXml.EventKey = rootElement.SelectSingleNode("EventKey").InnerText; break; } string selday = "0"; int hh = selday == "0" ? 60 : int.Parse(selday) * 24 * 60; //將發送方和接收方寫入cookie中,後期使用 CookieHelper.WriteCookie("WeChatFrom", "ToUserName", requestXml.ToUserName, hh); CookieHelper.WriteCookie("WeChatFrom", "FromUserName", requestXml.FromUserName, hh); //回覆消息 ResponseMsg(requestXml); } } #endregion 接收微信消息
三、回覆信息
#region 回覆消息(微信信息返回) /// <summary> /// 回覆消息(微信信息返回) /// </summary> /// <param name="weixinXML"></param> private void ResponseMsg(RequestXml requestXml) { string resXml = ""; string WeChat_Key = Request.QueryString["key"]; try { DataTable dtWeChat = wechatdal.GetList("wechat_key='" + WeChat_Key + "'").Tables[0]; if (dtWeChat.Rows.Count > 0) { replyset.User_ID = dtWeChat.Rows[0]["user_id"].ToString(); replyset.WeChat_ID = dtWeChat.Rows[0]["wechat_id"].ToString(); replyset.WeChat_Type = dtWeChat.Rows[0]["wechat_type"].ToString(); replyset.WeChat_Name = dtWeChat.Rows[0]["wechat_name"].ToString(); switch (requestXml.MsgType) { //當收到文本信息的時候回覆信息 case "text": resXml = replyset.GetKeyword(requestXml.FromUserName, requestXml.ToUserName, requestXml.Content); break; //當接收推送事件時回覆的信息 case "event": switch (requestXml.Event) { //關注的時候回覆信息 case "subscribe": resXml = replyset.GetSubscribe(requestXml.FromUserName, requestXml.ToUserName); break; //自定義菜單的時候回覆信息 case "CLICK": resXml = replyset.GetMenuClick(requestXml.FromUserName, requestXml.ToUserName, requestXml.EventKey); break; } break; } } } catch (Exception ex) { Writebug("異常:" + ex.Message + "Struck:" + ex.StackTrace.ToString()); } //發送xml格式的信息到微信中 Response.Write(resXml); Response.End(); } #endregion 回覆消息(微信信息返回)
加載wechatapi.aspx的load時間
protected void Page_Load(object sender, EventArgs e) { if (Request.HttpMethod.ToLower() == "post") { RequestMsg(); } else { //微信經過get請求驗證api接口 CheckWeChat(); } }
reply.cs
public class replyset { public string hostUrl = "http://" + HttpContext.Current.Request.Url.Authority; //域名 public string upfileurl = "http://file.api.weixin.qq.com/cgi-bin/media/upload"; public string baiduImg = "http://api.map.baidu.com/staticimage?center={0},{1}&width=700&height=300&zoom=11"; public string User_ID = ""; public string WeChat_ID = ""; public string WeChat_Type = ""; public string WeChat_Name = ""; w_caidan_dal caidandal = new w_caidan_dal(); w_reply_dal replydal = new w_reply_dal(); w_article_dal articledal = new w_article_dal(); w_keyword_dal keyworddal = new w_keyword_dal(); w_vlimg_dal vlimgdal = new w_vlimg_dal(); w_vlimg_model vlimgmodel = new w_vlimg_model(); w_images_dal imagesdal = new w_images_dal(); common wxCommand = new common(); JsonOperate JsonOperate = new JsonOperate(); JavaScriptSerializer Jss = new JavaScriptSerializer(); public replyset() { } #region 關注回覆 /// <summary> /// 關注的時候回覆 /// </summary> /// <param name="FromUserName"></param> /// <param name="ToUserName"></param> /// <returns></returns> public string GetSubscribe(string FromUserName, string ToUserName) { string resXml = ""; string sqlWhere = !string.IsNullOrEmpty(WeChat_ID) ? "WeChat_ID=" + WeChat_ID + " and reply_fangshi=2" : ""; DataTable dtSubscribe = replydal.GetRandomList(sqlWhere, "1").Tables[0]; if (dtSubscribe.Rows.Count > 0) { string article_id = dtSubscribe.Rows[0]["article_id"].ToString(); string reply_type = dtSubscribe.Rows[0]["reply_type"].ToString(); string reply_text = dtSubscribe.Rows[0]["reply_text"].ToString(); if (reply_type == "text") { resXml = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + reply_text + "]]></Content><FuncFlag>0</FuncFlag></xml>"; } else { resXml = GetArticle(FromUserName, ToUserName, article_id, User_ID); } } return resXml; } #endregion 關注回覆 #region 自動回覆 /// <summary> /// 自動默認回覆 /// </summary> /// <param name="FromUserName"></param> /// <param name="ToUserName"></param> /// <param name="WeChat_ID"></param> /// <param name="User_ID"></param> /// <returns></returns> public string GetDefault(string FromUserName, string ToUserName, string WeChat_ID, string User_ID) { string resXml = ""; string sqlWhere = !string.IsNullOrEmpty(WeChat_ID) ? "WeChat_ID=" + WeChat_ID + " and reply_fangshi=1" : ""; //獲取保存的默認回覆設置信息 DataTable dtDefault = replydal.GetRandomList(sqlWhere, "1").Tables[0]; if (dtDefault.Rows.Count > 0) { string article_id = dtDefault.Rows[0]["article_id"].ToString(); string reply_type = dtDefault.Rows[0]["reply_type"].ToString(); string reply_text = dtDefault.Rows[0]["reply_text"].ToString(); //若是選擇的是文本 if (reply_type == "text") { resXml = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + reply_text + "]]></Content><FuncFlag>0</FuncFlag></xml>"; } else { //返回素材(圖文列表) resXml = GetArticle(FromUserName, ToUserName, article_id, User_ID); } } return resXml; } #endregion 默認回覆 #region 關鍵字回覆 /// <summary> /// 關鍵字回覆 /// </summary> /// <param name="FromUserName"></param> /// <param name="ToUserName"></param> /// <param name="Content"></param> /// <returns></returns> public string GetKeyword(string FromUserName, string ToUserName, string Content) { string resXml = ""; string sqlWhere = "wechat_id=" + WeChat_ID + " and keyword_name='" + Content+"'"; DataTable dtKeyword = keyworddal.GetList(sqlWhere).Tables[0]; if (dtKeyword.Rows.Count > 0) { dtKeyword = keyworddal.GetRandomList(sqlWhere, "1").Tables[0]; if (dtKeyword.Rows.Count > 0) { string article_id = dtKeyword.Rows[0]["article_id"].ToString(); string keyword_type = dtKeyword.Rows[0]["keyword_type"].ToString(); string keyword_text = dtKeyword.Rows[0]["keyword_text"].ToString(); switch (keyword_type) { case "text": resXml = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + keyword_text + "]]></Content><FuncFlag>0</FuncFlag></xml>"; break; case "news": resXml = GetArticle(FromUserName, ToUserName, article_id, User_ID); break; } } } else { resXml = GetDefault(FromUserName, ToUserName, WeChat_ID, User_ID); } return resXml; } #endregion 關鍵字回覆 #region 菜單單擊 /// <summary> /// 菜單點擊事件回覆信息 /// </summary> /// <param name="FromUserName"></param> /// <param name="ToUserName"></param> /// <param name="EventKey"></param> /// <returns></returns> public string GetMenuClick(string FromUserName, string ToUserName, string EventKey) { string resXml = ""; string sqlWhere = "wechat_id=" + WeChat_ID + " and caidan_key='" + EventKey + "'"; WriteTxt(sqlWhere); try { DataTable dtMenu = caidandal.GetList(sqlWhere).Tables[0]; if (dtMenu.Rows.Count > 0) { string article_id = dtMenu.Rows[0]["article_id"].ToString(); string caidan_retype = dtMenu.Rows[0]["caidan_retype"].ToString(); string caidan_retext = dtMenu.Rows[0]["caidan_retext"].ToString(); switch (caidan_retype) { case "text": resXml = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + caidan_retext + "]]></Content><FuncFlag>0</FuncFlag></xml>"; break; case "news": resXml = GetArticle(FromUserName, ToUserName, article_id, User_ID); break; } } } catch (Exception ex) { WriteTxt("異常:" + ex.Message + "Struck:" + ex.StackTrace.ToString()); } return resXml; } #endregion 菜單單擊 #region 獲取素材 /// <summary> /// 獲取素材 /// </summary> /// <param name="FromUserName"></param> /// <param name="ToUserName"></param> /// <param name="Article_ID"></param> /// <param name="User_ID"></param> /// <returns></returns> public string GetArticle(string FromUserName, string ToUserName, string Article_ID, string User_ID) { string resXml = ""; DataTable dtArticle = articledal.GetList("article_id=" + Article_ID + " OR article_layid=" + Article_ID).Tables[0]; if (dtArticle.Rows.Count > 0) { resXml = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[news]]></MsgType><Content><![CDATA[]]></Content><ArticleCount>" + dtArticle.Rows.Count + "</ArticleCount><Articles>"; foreach (DataRow Row in dtArticle.Rows) { string article_title = Row["article_title"].ToString(); string article_description = Row["article_description"].ToString(); string article_picurl = Row["article_picurl"].ToString(); string article_url = Row["article_url"].ToString(); string article_type = Row["article_type"].ToString(); switch (article_type) { case "Content": article_url = hostUrl + "/web/wechat/api/article.aspx?aid=" + Row["Article_ID"].ToString(); break; case "Href": article_url = Row["article_url"].ToString(); break; } if (string.IsNullOrEmpty(article_url)) { article_url = hostUrl + "/web/wechat/api/article.aspx?aid=" + Row["Article_ID"].ToString(); } article_url += (article_url.IndexOf("uid=") > -1 ? "" : (article_url.IndexOf("?") > -1 ? "&" : "?") + "uid=" + User_ID); article_url += (article_url.IndexOf("wxid=") > -1 ? "" : (article_url.IndexOf("?") > -1 ? "&" : "?") + "wxid=" + FromUserName); article_url += (article_url.IndexOf("wxref=") > -1 ? "" : (article_url.IndexOf("?") > -1 ? "&" : "?") + "wxref=mp.weixin.qq.com"); resXml += "<item><Title><![CDATA[" + article_title + "]]></Title><Description><![CDATA[" + article_description + "]]></Description><PicUrl><![CDATA[" + article_picurl + "]]></PicUrl><Url><![CDATA[" + article_url + "]]></Url></item>"; } resXml += "</Articles><FuncFlag>1</FuncFlag></xml>"; } return resXml; } #endregion 獲取圖文列表 #region 通用方法 /// <summary> /// unix時間轉換爲datetime /// </summary> /// <param name="timeStamp"></param> /// <returns></returns> private DateTime UnixTimeToTime(string timeStamp) { DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); long lTime = long.Parse(timeStamp + "0000000"); TimeSpan toNow = new TimeSpan(lTime); return dtStart.Add(toNow); } /// <summary> /// datetime轉換爲unixtime /// </summary> /// <param name="time"></param> /// <returns></returns> private int ConvertDateTimeInt(System.DateTime time) { System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); return (int)(time - startTime).TotalSeconds; } /// <summary> /// 記錄bug,以便調試 /// </summary> /// <returns></returns> public bool WriteTxt(string str) { try { FileStream fs = new FileStream(HttpContext.Current.Server.MapPath("Log/wxbugLog.txt"), FileMode.Append); StreamWriter sw = new StreamWriter(fs); //開始寫入 sw.WriteLine(str); //清空緩衝區 sw.Flush(); //關閉流 sw.Close(); fs.Close(); } catch (Exception) { return false; } return true; } #endregion 通用方法 } }
二、關鍵字回覆
關鍵字的回覆也很簡單,咱們先把對應的關鍵字和返回的信息都設置好,而後根據接收的信息中是否存在設置好的關鍵詞來返回對應的信息便可
一、設置關鍵詞(這裏就不在多說了)
二、接收信息和回覆信息前面也說到了,在這裏只把關鍵詞回覆判斷的方法貼出來供你們參考一下
#region 關鍵字回覆 /// <summary> /// 關鍵字回覆 /// </summary> /// <param name="FromUserName"></param> /// <param name="ToUserName"></param> /// <param name="Content"></param> /// <returns></returns> public string GetKeyword(string FromUserName, string ToUserName, string Content) { string resXml = ""; string sqlWhere = "wechat_id=" + WeChat_ID + " and keyword_name='" + Content+"'"; DataTable dtKeyword = keyworddal.GetList(sqlWhere).Tables[0]; if (dtKeyword.Rows.Count > 0) { dtKeyword = keyworddal.GetRandomList(sqlWhere, "1").Tables[0]; if (dtKeyword.Rows.Count > 0) { string article_id = dtKeyword.Rows[0]["article_id"].ToString(); string keyword_type = dtKeyword.Rows[0]["keyword_type"].ToString(); string keyword_text = dtKeyword.Rows[0]["keyword_text"].ToString(); switch (keyword_type) { case "text": resXml = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + keyword_text + "]]></Content><FuncFlag>0</FuncFlag></xml>"; break; case "news": resXml = GetArticle(FromUserName, ToUserName, article_id, User_ID); break; } } } else { resXml = GetDefault(FromUserName, ToUserName, WeChat_ID, User_ID); } return resXml; } #endregion 關鍵字回覆
其餘還有不少圖片回覆,二維碼掃描回覆信息等都大同小異,處理方式都差很少,參考開發文檔很快就能搞定,這裏就不在多說了,不明白的地方在討論。