記一次接收微信公眾平臺推送消息的實例

来源:http://www.cnblogs.com/wangrudong003/archive/2017/04/06/6674816.html
-Advertisement-
Play Games

本章的內容來源是有朋友咨詢怎麼做微信公眾號信息的收發消息功能,因此本著為社區做貢獻的態度申請了個人公眾號,然後嘗試對接了一下接收公眾號內容信息的流程;要說對接其實呢也算不上,因為個人賬號只有簡單的一些接收,被動回覆等功能信息,不能群發和使用客服介面,所以本章主要分享的是怎麼接受信息和被動發送回覆信息 ...


本章的內容來源是有朋友咨詢怎麼做微信公眾號信息的收發消息功能,因此本著為社區做貢獻的態度申請了個人公眾號,然後嘗試對接了一下接收公眾號內容信息的流程;要說對接其實呢也算不上,因為個人賬號只有簡單的一些接收,被動回覆等功能信息,不能群發和使用客服介面,所以本章主要分享的是怎麼接受信息和被動發送回覆信息的實例;

在公眾平臺上綁定消息通知接收地址

這種設置的東西,其實跟著官網設置就行了,不過本人根據官網文檔一步一步設置的時候,還是遇到一些問題,因此這裡需要記錄下註意的關鍵點;首先我們登陸公眾平臺-》開發-》基本配置-》點擊“修改配置”-》這個時候會出現以下截圖:

填寫上面內容的時候需要註意以下幾點:

1. 接收的url地址必須外網能訪問並且在80埠

2. 第一次保存“伺服器配置”時,必須在接收地址中以get方式獲取的公眾平臺通知的“echostr”參數,然後返回輸出這個“echostr”值給平臺(這樣你在公眾平臺保存服務配置的時候才能成功),這個地方官網文字描述不是很突出,不重點看的話很難發現

到此,只要做到上面兩點那麼您“伺服器配置”才能保存成功,千萬仔細哦;

 

分享接收公眾平臺通知信息的代碼

 1 /// <summary>
 2         /// 接收“服務配置”時通知的信息  格式如:signature=08c66dd8b2fd8fe43118965b336d6098642607f3&echostr=6917887702473243501&timestamp=1491458849&nonce=1123949701
 3         /// </summary>
 4         /// <returns></returns>
 5         [HttpGet]
 6         public string Get()
 7         {
 8             
 9             var echostr = Request.Query["echostr"];
10             if (string.IsNullOrWhiteSpace(echostr)) { return "別瞎搞。"; }
11 
12             var sbLog = new StringBuilder(string.Empty);
13             sbLog.Append($"method:get->echostr:{echostr}->");
14             try
15             {
16                 sbLog.Append($"QueryString:{Request.QueryString.Value}->");
17             }
18             catch (Exception ex)
19             {
20                 sbLog.Append($"異常信息:{ex.Message}->");
21             }
22             finally
23             {
24                 PublicTool.WriteLog(sbLog.ToString());
25             }
26             return echostr;
27         }

接收post過來的用戶發送的內容信息,目前公眾平臺通知的類型有: text:文本消息 image:圖形消息 voice:語音消息 video:視頻消息 shortvideo:小視頻消息 location:地理位置 link:鏈接消息;

 1 /// <summary>
 2         /// 接收post過來的用戶發送的內容信息
 3         /// </summary>
 4         /// <returns></returns>
 5         [HttpPost]
 6         public string Post()
 7         {
 8             var sbLog = new StringBuilder(string.Empty);
 9             var now = DateTime.Now;
10             var reStr = string.Empty;  //返回信息,1.空表示不需要再通知 2.返回正規文本內容表示回覆消息 3.其他信息表示需要再次通知內容
11             sbLog.Append($"method:post->");
12             try
13             {
14                 var str = string.Empty;
15                 using (var stream = Request.Body)
16                 {
17                     using (var reader = new StreamReader(stream))
18                     {
19                         str = reader.ReadToEnd();
20                     }
21                 }
22                 sbLog.Append($"str:{str}->");
23                 if (string.IsNullOrWhiteSpace(str)) { return reStr; }
24 
25                 var data = PublicTool._XmlDeserialize<xml>(str);
26                 if (data == null) { return reStr; }
27                 sbLog.Append($"ToUserName:{data.ToUserName},FromUserName:{data.FromUserName},MsgType:{data.MsgType},CreateTime:{data.CreateTime}->");
28 
29                 //消息類型 對應枚舉 MsgTypeEm
30                 switch (data.MsgType)
31                 {
32                     case "text":
33                         
34                         break;
35                     case "image":
36                         break;
37                     case "voice":
38                         break;
39                     case "video":
40                         break;
41                     case "shortvideo":
42                         break;
43 
44                     case "location":
45                         break;
46                     case "link":
47                         break;
48                 }
49 
50                 //自動回覆信息(暫時:只有文字內容)
51                 var reHuaYu = string.Empty;
52                 if (data.Content.Contains("測試") || data.Content.Contains("ceshi"))
53                 {
54                     reHuaYu = "請儘量發一些有用的信息!";
55                 }
56                 else if (data.Content.Contains("你好") || data.Content.Contains("您好") || data.Content.Contains("群主") || data.Content.Contains("在麽"))
57                 {
58                     reHuaYu = "您好,謝謝您的支持!";
59                 }
60 
61                 if (!string.IsNullOrWhiteSpace(reHuaYu))
62                 {
63                     reStr = string.Format(@"<xml>
64                                                 <ToUserName><![CDATA[{0}]]></ToUserName>
65                                                 <FromUserName><![CDATA[{1}]]></FromUserName>
66                                                 <CreateTime>{2}</CreateTime>
67                                                 <MsgType><![CDATA[{3}]]></MsgType>
68                                                 <Content><![CDATA[{4}]]></Content>
69                                            </xml>",
70                                            data.FromUserName,
71                                            data.ToUserName,
72                                            now,
73                                            "text",
74                                            reHuaYu);
75                 }
76             }
77             catch (Exception ex)
78             {
79                 sbLog.Append($"異常信息:{ex.Message}->");
80             }
81             finally
82             {
83                 if (!string.IsNullOrEmpty(sbLog.ToString()))
84                 {
85                     PublicTool.WriteLog(sbLog.ToString());
86                 }
87             }
88             return reStr;
89         }

 

iis和Kestrel監聽項目埠引發的一些思考,待解惑

本次我使用的是.netcore的webapi來接收通知消息,但是當公眾平臺有80埠限制的時候,頓時我蒙了,因為我伺服器iis上有一個項目是綁定了80埠的,這個時候如果使用Kestrel再綁定一個埠那肯定不行的;想到iis可以創建虛擬子應用程式(多個子應用程式對應一個大的網站配置,這樣80埠就可以共用了),思考著Kestrel是不是也可以呢,失望的是查了很多資料都暫時沒有涉及到或者是我沒有找到這方面的資料,因此只好放棄了;

下麵分享下.netcore中我操作xml序列化和反序列方法,首先需要引入 System.Xml.Serialization :

 1  /// <summary>
 2         /// xml字元串反序列化
 3         /// </summary>
 4         /// <typeparam name="T"></typeparam>
 5         /// <param name="xml"></param>
 6         /// <returns></returns>
 7         public static T _XmlDeserialize<T>(string xml) where T : class, new()
 8         {
 9             T t = default(T);
10             if (string.IsNullOrEmpty(xml)) return t;
11 
12             XmlSerializer serializer = new XmlSerializer(typeof(T));
13             using (var reader = new StringReader(xml))
14             {
15                 t = (T)serializer.Deserialize(reader);
16             }
17             return t;
18         }
19 
20         /// <summary>
21         /// xml序列化
22         /// </summary>
23         /// <param name="obj"></param>
24         /// <returns></returns>
25         public static string _XMLSerialize(object obj)
26         {
27             XmlSerializer xs = new XmlSerializer(obj.GetType());
28             StringBuilder strBuidler = new StringBuilder();
29             XmlWriterSettings setting = new XmlWriterSettings();
30             setting.OmitXmlDeclaration = true;//去掉xml版本聲明
31             using (System.Xml.XmlWriter xw = System.Xml.XmlWriter.Create(strBuidler, setting))
32             {
33                 XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();
34                 xmlns.Add(string.Empty, string.Empty);
35                 xs.Serialize(xw, obj, xmlns);
36             }
37             return strBuidler.ToString();
38         }

文本日誌

 1 /// <summary>
 2         /// 文本日誌
 3         /// </summary>
 4         /// <param name="content"></param>
 5         /// <param name="basePath"></param>
 6         public static async void WriteLog(string content, string basePath = null)
 7         {
 8             basePath = basePath ?? AppContext.BaseDirectory;
 9             var now = DateTime.Now;
10 
11             var year = now.ToString("yyyy");
12             var month = now.ToString("MM");
13             var date = now.ToString("dd");
14 
15             var fileName = $"{now.ToString("HH")}.txt";
16             var path = Path.Combine(basePath, year, month, date, fileName);
17             if (!System.IO.File.Exists(path))
18             {
19 
20                 basePath = Path.Combine(basePath, year);
21                 if (!Directory.Exists(basePath)) { Directory.CreateDirectory(basePath); }
22 
23                 basePath = Path.Combine(basePath, month);
24                 if (!Directory.Exists(basePath)) { Directory.CreateDirectory(basePath); }
25 
26                 basePath = Path.Combine(basePath, date);
27                 if (!Directory.Exists(basePath)) { Directory.CreateDirectory(basePath); }
28 
29                 path = Path.Combine(basePath, fileName);
30             }
31             using (FileStream stream = new FileStream(path, FileMode.Append, FileAccess.Write))
32             {
33                 using (var writer = new StreamWriter(stream))
34                 {
35                     await writer.WriteLineAsync($"{now.ToString("yyyy-MM-dd HH:mm:ss.fff")}:{content}");
36                 }
37             }
38         }

總結一下吧:

有點好奇為什麼微信公眾平臺使用的是xml格式數據來交互,不知道是出於什麼考慮;從介面對接上來說很簡單,就是平長的get,post方式來傳遞數據,需要註意的應該是一些細節上的問題吧;還有待解決Kestrel部署netcore時是否能創建多個子虛擬目錄問題(如果您已經知道了這個答案,請不吝賜教,謝謝);最後發一張測試的公眾號二維碼,關註後輸入:測試 或 您好,群主等信息會有我介面返回的自動回覆信息;


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 下載MATLAB2015b破解版 操作系統:Ubuntu 16.o4 LTS 程式文件:Matlab2015b glnxa64破解版 解壓提取文件:在ubuntu系統下可以直接提取壓縮文件,得到三個文件: license_standalone.lic Matlab 2015b Linux64 Cra ...
  • win7下安裝Ubuntu後進不去win7的解決方法 剛剛給同學在win7下安裝了Ubuntu16.04,結果在安裝完後竟然無法在電腦重啟後,找到win7的進入選項。 在網上找了找,都不行!就差點重裝了。終於還是找到了! 安裝Ubuntu後直接進入Ubuntu系統, "Ctrl+alt+t" 進入終 ...
  • 解決 Bash On Windows "無法從 Windows 應用商店下載。請檢查網路連接。"的問題 Fiddler和Bash On Windows 源離線壓縮包:http://pan.baidu.com/s/1kVofL4b 不想從百度網盤下載的,可以從官方下載: Fiddler:https:/ ...
  • 作業: 集群搭建 1、部署nginx反向代理三個web服務,調度演算法使用加權輪詢; 2、所有web服務使用共用存儲nfs,保證所有web都對其有讀寫許可權,保證數據一致性; 一、nginx服務 1. 先安裝yum install epel-release -y 2.安裝後發現沒有epel源,重新安裝一 ...
  • C#中遍歷各類數據集合的方法總結: 1.枚舉類型 2.遍歷ArrayList(Queue、Stack) 這裡以string為例,當然ArrayList中的元素可以是任何數據類型,遍歷時須確認ArrayList中的元素都是同一數據類型。 此外遍歷Queue隊列和Stack堆棧的方式與ArrayList ...
  • 三年前寫過基於ConcurrentQueue的非同步隊列,今天在整理代碼的時候發現當時另外一種實現方式-使用BlockingCollection實現,這種方式目前依然在實際項目中使用。關於BlockingCollection的基本使用請查閱MSDN。源碼實現 下麵直接上代碼:(代碼已經放到了我的git ...
  • 抱歉問題解決前沒留截圖,總之就是使用巨集相關的功能都打不開,會彈窗報錯,英文,大意是【一個或多個組件不存在,請嘗試重裝】。 嘗試過: 修複安裝VS2010 按此文照做:https://visualstudioextensions.vlasovstudio.com/2014/02/13/visual-s ...
  • 在 UWP 開發中,我們在進行數據綁定時,除了可以使用傳統的綁定 Binding,也可以使用全新的 x:Bind,由於後者是在程式編譯時進行初始化操作(不同於 Binding,它是在運行時創建、初始化),所以我們可以稱 x:Bind 為編譯型綁定,正像本文標題一樣。之所以引入 x:Bind,是因為它 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...