主要就是三個:返回API文本消息,返回普通文本消息,發送事件消息?? --會出現失敗的情況
(后續補充說明:出現檢測出錯,不一定是代碼出現了問題,也有可能是1.微信方面檢測時出現服務器請求失敗,2.我們程序反應過慢,服務器處理超過微信方面的接收時長,導致微信方面未接收信息,報錯)
?
今天大概一下午坐著查這個了,眼睛疼得要命
圖忘記截了,現在只剩下成功的圖了,明天大概就會有結果了
先把當前成功的代碼發布上來
用的C# MVC


public ActionResult Receive(string timestamp, string nonce, string encrypt_type){Log4NetHelper.Info("merchant message recive");var encryptMsg = string.Empty;try{string appid = "";if (!string.IsNullOrEmpty(Request["appid"])){appid = Request["appid"].Substring(1);}WeixinMessage message = null;var safeMode = Request.QueryString.Get("encrypt_type") == "aes";using (var streamReader = new StreamReader(Request.InputStream)){var decryptMsg = string.Empty;var msg = streamReader.ReadToEnd();#region 解密if (safeMode){var msg_signature = Request.QueryString.Get("msg_signature");var wxBizMsgCrypt = new WXBizMsgCrypt(CachedConfigContext.Current.WeixinOpenConfig.Token,CachedConfigContext.Current.WeixinOpenConfig.EncodingAESKey,CachedConfigContext.Current.WeixinOpenConfig.AppID);var ret = wxBizMsgCrypt.DecryptMsg(msg_signature, timestamp, nonce, msg, ref decryptMsg);if (ret != 0)//解密失敗 {//TODO:開發者解密失敗的業務處理邏輯//注意:本demo用log4net記錄此信息,你可以用其他方法Log4NetHelper.Info(string.Format("decrypt message return {0}, request body {1}", ret, msg));WriteTxt.RecodeBug(string.Format("1商戶接收信息,解密失敗:decrypt message return {0}, request body {1}", ret, msg), "/merchant_receive.txt");}}else{decryptMsg = msg;}#endregion//將傳入的數據流轉成對象message = AcceptMessageAPI.Parse(decryptMsg);}#region 全網發布流進入 appid值為wx570bc396a51b8ff8if (appid.Contains("wx570bc396a51b8ff8"))//微信官方測試賬號,用來全網發布測試的 {var openId = message.Body.FromUserName.Value;var myUserName = message.Body.ToUserName.Value;WriteTxt.RecodeBug(string.Format("1官方微信測試賬號進入 event={0},openID={1}, myUserName={2}", message.Type, openId, myUserName), "/merchant_receive.txt");#region 全網發布eventif (message.Type == WeixinMessageType.Event){string content = string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName>" +"<FromUserName><![CDATA[{1}]]></FromUserName>" +"<CreateTime>{2}</CreateTime>" +"<MsgType><![CDATA[text]]></MsgType>" +"<Content><![CDATA[{3}]]></Content></xml>",openId, myUserName, Util.CreateTimestamp(), message.Body.Event.Value.ToString() + "from_callback");WriteTxt.RecodeBug(string.Format("2全網發布事件返回內容content={0},safeMode={1}", content, safeMode), "/merchant_receive.txt");#region 加密if (safeMode){var msg_signature = Request.QueryString.Get("msg_signature");var wxBizMsgCrypt = new WXBizMsgCrypt(CachedConfigContext.Current.WeixinOpenConfig.Token,CachedConfigContext.Current.WeixinOpenConfig.EncodingAESKey,CachedConfigContext.Current.WeixinOpenConfig.AppID);var ret = wxBizMsgCrypt.EncryptMsg(content, timestamp, nonce, ref encryptMsg);if (ret != 0)//加密失敗 {//TODO:開發者加密失敗的業務處理邏輯//Log4NetHelper.Info(string.Format("encrypt message return {0}, response body {1}", ret, response));WriteTxt.RecodeBug(string.Format("2商戶接收信息,加密失敗:encrypt message return {0}, response body {1}", ret, encryptMsg), "/merchant_receive.txt");}else{WriteTxt.RecodeBug(string.Format("2商戶接收信息,加密成功:encrypt message return {0}, response body {1}", ret, encryptMsg), "/merchant_receive.txt");}}else{encryptMsg = content;}#endregionreturn new ContentResult{Content = encryptMsg,ContentType = "text/xml",ContentEncoding = System.Text.UTF8Encoding.UTF8};} #endregion#region 全網發布textelse if (message.Type == WeixinMessageType.Text){string con = message.Body.Content.Value.ToString();WriteTxt.RecodeBug(string.Format("2全網發布Text中的content={0},\"TESTCOMPONENT_MSG_TYPE_TEXT\".Equals(con)={1}", con, "TESTCOMPONENT_MSG_TYPE_TEXT".Equals(con)), "/merchant_receive.txt");//全網發布中,立即返回信息到粉絲#region 全網發布text,立即返回if ("TESTCOMPONENT_MSG_TYPE_TEXT".Equals(con)){string content = string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName>" +"<FromUserName><![CDATA[{1}]]></FromUserName>" +"<CreateTime>{2}</CreateTime>" +"<MsgType><![CDATA[text]]></MsgType>" +"<Content><![CDATA[{3}]]></Content></xml>",openId, myUserName, Util.CreateTimestamp(), "TESTCOMPONENT_MSG_TYPE_TEXT_callback");WriteTxt.RecodeBug(string.Format("3全網發布TEXT 立即回復 content={0},safeMode={1}", content, safeMode), "/merchant_receive.txt");#region 加密if (safeMode){var msg_signature = Request.QueryString.Get("msg_signature");var wxBizMsgCrypt = new WXBizMsgCrypt(CachedConfigContext.Current.WeixinOpenConfig.Token,CachedConfigContext.Current.WeixinOpenConfig.EncodingAESKey,CachedConfigContext.Current.WeixinOpenConfig.AppID);var ret = wxBizMsgCrypt.EncryptMsg(content, timestamp, nonce, ref encryptMsg);if (ret != 0)//加密失敗 {//TODO:開發者加密失敗的業務處理邏輯//Log4NetHelper.Info(string.Format("encrypt message return {0}, response body {1}", ret, response));WriteTxt.RecodeBug(string.Format("2商戶接收信息,加密失敗:encrypt message return {0}, response body {1}", ret, encryptMsg), "/merchant_receive.txt");}else{WriteTxt.RecodeBug(string.Format("2商戶接收信息,加密成功:encrypt message return {0}, response body {1}", ret, encryptMsg), "/merchant_receive.txt");}}else{encryptMsg = content;}#endregion//直接返回不太對,直接將加密判斷給領過來了(上面)return new ContentResult{Content = encryptMsg,ContentType = "text/xml",ContentEncoding = System.Text.UTF8Encoding.UTF8};}#endregion#region 全網發布text 客服接口發送else{string content = message.Body.Content.Value.ToString();WriteTxt.RecodeBug(string.Format("3content={0}", content), "/merchant_receive.txt");if (content.StartsWith("QUERY_AUTH_CODE", true, System.Globalization.CultureInfo.CurrentCulture)){string temp = content.Split(':')[1];WriteTxt.RecodeBug(string.Format("QUERY_AUTH_CODE拿到的值={0}", temp), "/merchant_receive.txt");HttpContext.Response.Write("");WriteTxt.RecodeBug(string.Format("全網發布text客服回復start"), "/merchant_receive.txt");var ourPublic = ServiceContext.Current.WeixinOpenService.GetWxSetting();string componentAccessToken = ourPublic.ComponentAccessToken;QueryAuthData data = Qxun.Framework.Weixin.Open.ComponentAPI.QueryAuthorization(componentAccessToken, CachedConfigContext.Current.WeixinOpenConfig.AppID, temp);ReplayActiveMessageAPI.RepayText(data.authorization_info.authorizer_access_token, openId, temp + "_from_api");WriteTxt.RecodeBug(string.Format("4全網發布text客服回復end"), "/merchant_receive.txt");return Content("success");}}#endregion} #endregion}#endregion//進入消息獲取分析方法 Executevar response = WeixinExecutor.Execute(message, mpn.MerchantID);#region 加密if (safeMode){var msg_signature = Request.QueryString.Get("msg_signature");var wxBizMsgCrypt = new WXBizMsgCrypt(CachedConfigContext.Current.WeixinOpenConfig.Token,CachedConfigContext.Current.WeixinOpenConfig.EncodingAESKey,CachedConfigContext.Current.WeixinOpenConfig.AppID);var ret = wxBizMsgCrypt.EncryptMsg(response, timestamp, nonce, ref encryptMsg);if (ret != 0)//加密失敗 {//TODO:開發者加密失敗的業務處理邏輯//Log4NetHelper.Info(string.Format("encrypt message return {0}, response body {1}", ret, response));WriteTxt.RecodeBug(string.Format("2商戶接收信息,加密失敗:encrypt message return {0}, response body {1}", ret, response), "/merchant_receive.txt");}}else{encryptMsg = response;}#endregion}catch (Exception e){WriteTxt.RecodeBug(string.Format("10Exception:商戶接受信息,出現異常:{0}", e.Message), "/merchant_receive.txt");}return new ContentResult{Content = encryptMsg,ContentType = "text/xml",ContentEncoding = System.Text.UTF8Encoding.UTF8};}
官網文檔說明:
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419318611&lang=zh_CN
官網上的總結主要有以下幾點:
1.微信會拿一個公眾號來進行測試,其appid的值就是下面這個了,主要用來和原來的代碼進行區分,不要將自己正常的運行也給弄進去了
-
(1)appid: wx570bc396a51b8ff8
-
(2)Username: gh_3c884a361561
2.這里的檢測有三種,這里,由于百度的時候,有些都說不要加密,這一點我也不好直接說不對,不過之前有一次使用的時候,沒有經過加密判斷,就失敗了


var safeMode = Request.QueryString.Get("encrypt_type") == "aes"; string encryptMsg=""; #region 加密if (safeMode){var msg_signature = Request.QueryString.Get("msg_signature");var wxBizMsgCrypt = new WXBizMsgCrypt(CachedConfigContext.Current.WeixinOpenConfig.Token,CachedConfigContext.Current.WeixinOpenConfig.EncodingAESKey,CachedConfigContext.Current.WeixinOpenConfig.AppID);var ret = wxBizMsgCrypt.EncryptMsg(content, timestamp, nonce, ref encryptMsg);if (ret != 0)//加密失敗 {//TODO:開發者加密失敗的業務處理邏輯//Log4NetHelper.Info(string.Format("encrypt message return {0}, response body {1}", ret, response));WriteTxt.RecodeBug(string.Format("2商戶接收信息,加密失敗:encrypt message return {0}, response body {1}", ret, encryptMsg), "/merchant_receive.txt");}else{WriteTxt.RecodeBug(string.Format("2商戶接收信息,加密成功:encrypt message return {0}, response body {1}", ret, encryptMsg), "/merchant_receive.txt");}}else{encryptMsg = content;}#endregion
?
第一種:推送事件消息,返回的信息Content值得是
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[subscribe]]></Event> </xml>
接收的Event的值+ "from_callback"
傳回去的content 格式 ,我這邊的設置,因為傳回去的都是text類型,推送普通文本信息也是text的
?
string content = string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName>" +"<FromUserName><![CDATA[{1}]]></FromUserName>" +"<CreateTime>{2}</CreateTime>" +"<MsgType><![CDATA[text]]></MsgType>" +"<Content><![CDATA[{3}]]></Content></xml>",openId, myUserName, Util.CreateTimestamp(), message.Body.Event.Value.ToString() + "from_callback");
?
return new ContentResult{Content = content,ContentType = "text/xml",ContentEncoding = System.Text.UTF8Encoding.UTF8};
?
微信事件推送鏈接:
https://mp.weixin.qq.com/wiki/2/5baf56ce4947d35003b86a9805634b1e.html
第二種:返回普通文本消息
這個傳進來和傳回去的內容都是固定的,傳入的值會是"TESTCOMPONENT_MSG_TYPE_TEXT",傳回去的值必須是"TESTCOMPONENT_MSG_TYPE_TEXT_callback"
至于為什么固定了傳入的值,是為了區分下面那種客服回復的情況。所以這種情況就要判斷一下是否content是否等于TESTCOMPONENT_MSG_TYPE_TEXT,contains也是可以的
這個返回信息和上面那個差不多
第三種:返回API文本消息
傳入的Content會是:QUERY_AUTH_CODE:$query_auth_code$ 這樣的,$query_auth_code$是要用的的值,需要截取出來。用string.Split(':')[1]就可以了,反正微信那邊傳過來都是絕對符合格式的
因為這個需要先返回個空字符串,c#這邊用這種寫法就可以了。當然不能在這里就給return了,我們還得繼續那客服發信息的接口呢。
需要拿到的有:我們公眾號作為被授權方的 ComponentAccessToken,我們公眾號的appid,以及之前截取的$query_auth_code$這個拿到的值
調用https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token={0}這個接口,post傳值 :component_appid和authorization_code —— 這個是用來獲取 authorization_info授權信息內的authorizer_access_token的
微信API文檔地址:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1453779503&token=fdc4e8827bb64f7892affcca13cc451abc6581df&lang=zh_CN
?
拿到authorizer_access_token之后,就可以調用客服發送信息的接口了https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={0}
?
客服發送信息的官方接口:https://mp.weixin.qq.com/wiki/1/70a29afed17f56d537c833f89be979c9.html
以上三種就差不多了
當然,這些的前提是,項目測試授權正常。
?
總覺得沒有失敗的圖不好,就跑去人家那邊截了個圖過來
?
?
上面的都是2016-07-27晚上八點左右寫的
?
今天去查看了一下,已經發布成功了,過了十多個小時吧,一天內就通過了,微信處理挺快的呢