C#開發微信門戶及應用(29)--微信個性化菜單的實現

来源:http://www.cnblogs.com/wuhuacong/archive/2016/04/08/5366730.html
-Advertisement-
Play Games

有一段時間沒有接著微信的主題繼續介紹裡面的功能模塊了,這段時間來,微信也做了不少的變化改動,針對這些特性我全面核對了一下相關的微信公眾號和企業號的介面,對原有的微信API和系統管理做了全面的更新,本隨筆以及後面的隨筆就是基於這個工作上的總結,以期把微信涉及的功能模塊,都使用C#實現的方式來介紹。本隨 ...


有一段時間沒有接著微信的主題繼續介紹裡面的功能模塊了,這段時間來,微信也做了不少的變化改動,針對這些特性我全面核對了一下相關的微信公眾號和企業號的介面,對原有的微信API和系統管理做了全面的更新,本隨筆以及後面的隨筆就是基於這個工作上的總結,以期把微信涉及的功能模塊,都使用C#實現的方式來介紹。本隨筆主要介紹微信公眾號的個性化菜單的實現,雖然目前微信公眾號和企業號已經在功能上接近一致,不過在企業號上還沒有個性化菜單的相關介面。

1、個性化菜單介紹

我們先瞭解一下個性化菜單的介紹,根據官方的資料,如下介紹。

為了幫助公眾號實現靈活的業務運營,微信公眾平臺新增了個性化菜單介面,開發者可以通過該介面,讓公眾號的不同用戶群體看到不一樣的自定義菜單。該介面開放給已認證訂閱號和已認證服務號。

開發者可以通過以下條件來設置用戶看到的菜單:

1、用戶分組(開發者的業務需求可以藉助用戶分組來完成)
2、性別
3、手機操作系統
4、地區(用戶在微信客戶端設置的地區)
5、語言(用戶在微信客戶端設置的語言)

個性化菜單介面說明:

1、個性化菜單要求用戶的微信客戶端版本在iPhone6.2.2,Android 6.2.4以上。
2、菜單的刷新策略是,在用戶進入公眾號會話頁或公眾號profile頁時,如果發現上一次拉取菜單的請求在5分鐘以前,就會拉取一下菜單,如果菜單有更新,就會刷新客戶端的菜單。測試時可以嘗試取消關註公眾賬號後再次關註,則可以看到創建後的效果。
3、普通公眾號的個性化菜單的新增介面每日限制次數為2000次,刪除介面也是2000次,測試個性化菜單匹配結果介面為20000次
4、出於安全考慮,一個公眾號的所有個性化菜單,最多只能設置為跳轉到3個功能變數名稱下的鏈接
5、創建個性化菜單之前必須先創建預設菜單(預設菜單是指使用普通自定義菜單創建介面創建的菜單)。如果刪除預設菜單,個性化菜單也會全部刪除

個性化菜單匹配規則說明:

當公眾號創建多個個性化菜單時,將按照發佈順序,由新到舊逐一匹配,直到用戶信息與matchrule相符合。如果全部個性化菜單都沒有匹配成功,則返回預設菜單。
例如公眾號先後發佈了預設菜單,個性化菜單1,個性化菜單2,個性化菜單3。那麼當用戶進入公眾號頁面時,將從個性化菜單3開始匹配,如果個性化菜單3匹配成功,則直接返回個性化菜單3,否則繼續嘗試匹配個性化菜單2,直到成功匹配到一個菜單。
根據上述匹配規則,為了避免菜單生效時間的混淆,決定不予提供個性化菜單編輯API,開發者需要更新菜單時,需將完整配置重新發佈一輪。

除正常的預設菜單外,個性化菜單提供了下麵幾個處理操作。

1 創建個性化菜單

2 刪除個性化菜單

3 測試個性化菜單匹配結果

4 查詢個性化菜單

5 刪除所有菜單

個性化自定義菜單功能,是指商家可以根據粉絲的分組、性別、手機操作系統,甚至地區,來分別展示公眾號的菜單。

比如,一家健身會所的公眾號,將自定義菜單根據粉絲性別進行了分開設置。男性粉絲進入公眾號會展示男生們比較感興趣菜單內容,跆拳道、搏擊等;若是女性粉絲,則會展示瑜伽、舞蹈、防身術等女性粉絲感興趣的菜單課程等。

 

2、個性化菜單的C#設計處理

微信的菜單是微信處理中很重要的一環,因為它是微信給用戶入口體驗重要的一環,也是很直觀的界面呈現之一,菜單的展示就是需要我們絞盡腦汁來精簡的界面元素了,由於菜單的重要性以及功能的豐富性,我在之前好幾篇隨筆專門介紹了菜單的各種處理。

在《C#開發微信門戶及應用(6)--微信門戶菜單的管理操作》、《C#開發微信門戶及應用(9)-微信門戶菜單管理及提交到微信伺服器》、《C#開發微信門戶及應用(11)--微信菜單的多種表現方式介紹》、《C#開發微信門戶及應用(20)-微信企業號的菜單管理》分別對相關的菜單有過介紹,有需要可以參考瞭解一下。

菜單模塊,在微信公眾號和企業號,它們都可以共用一個模型,因此我們把這些內容都放在微信共用模塊裡面,包括它的實體類信息(如菜單模塊),雖然有些地方,部分欄位內容沒有,但是我們可以通過實體類的JSON標識來進行處理,從而實現比較彈性化的實體類信息承載。

如下標識代碼所示。

    /// <summary>
    /// 菜單基本信息(公眾號、企業號公用,其他部分一樣)
    /// </summary>
    public class MenuJson : BaseJsonResult
    {
        /// <summary>
        /// 按鈕描述,既按鈕名字,不超過16個位元組,子菜單不超過40個位元組
        /// </summary>
        public string name { get; set; }

        /// <summary>
        /// 按鈕類型(click或view)
        /// </summary>
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string type { get; set; }

        /// <summary>
        /// 按鈕KEY值,用於消息介面(event類型)推送,不超過128位元組
        /// </summary>
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string key { get; set; }

        /// <summary>
        /// 網頁鏈接,用戶點擊按鈕可打開鏈接,不超過256位元組
        /// </summary>
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string url { get; set; }

        /// <summary>
        /// media_id類型和view_limited類型必須,調用新增永久素材介面返回的合法media_id
        /// </summary>
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string media_id { get; set; }

        /// <summary>
        /// 子按鈕數組,按鈕個數應為2~5個
        /// </summary>
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public List<MenuJson> sub_button { get; set; }

上面這個實體類是菜單信息的基礎信息,我們需要從這個基礎上擴展出來幾個實體類,方便在構建,獲取菜單信息的時候進行信息轉換,如下幾個類圖的設計所示。

通過這幾個類的關係,我們就可以適應所有的預設菜單和個性化菜單,以及企業號的菜單信息轉換處理了,通過JSON轉換為對應的實體類,實現信息的強類型處理。

其中我們菜單處理的API實現類代碼如下所示。

    /// <summary>
    /// 菜單的相關操作
    /// </summary>
    public class MenuApi : IMenuApi

這樣我們在IMenuApi的基礎上增加幾個個性化的介面。

        /// <summary>
        /// 創建個性化菜單
        /// </summary>
        /// <param name="accessToken">調用介面憑證</param>
        /// <param name="menuJson">菜單對象</param>
        /// <returns></returns>
        string CreateConditionalMenu(string accessToken, MenuListJson menuJson);

        /// <summary>
        /// 根據菜單ID刪除個性化菜單
        /// </summary>
        /// <param name="accessToken">調用介面憑證</param>
        /// <param name="menuid">菜單ID</param>
        /// <returns></returns>
        CommonResult DeleteConditionalMenu(string accessToken, string menuid);

        /// <summary>
        /// 測試個性化菜單匹配結果
        /// </summary>
        /// <param name="accessToken">調用介面憑證</param>
        /// <returns></returns>
        MenuListJson TryMatchConditionalMenu(string accessToken, string user_id);

然後在MenuApi實現類裡面實現相關的邏輯處理即可。

下麵是創建個性化菜單的介面說明。

創建個性化菜單

http請求方式:POST(請使用https協議)

https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token=ACCESS_TOKEN

請求示例

{
 	"button":[
 	{	
    	"type":"click",
    	"name":"今日歌曲",
     	"key":"V1001_TODAY_MUSIC" 
	},
	{ 
		"name":"菜單",
		"sub_button":[
		{	
			"type":"view",
			"name":"搜索",
			"url":"http://www.soso.com/"
		},
		{
			"type":"view",
			"name":"視頻",
			"url":"http://v.qq.com/"
		},
		{
			"type":"click",
			"name":"贊一下我們",
			"key":"V1001_GOOD"
		}]
 }],
"matchrule":{
  "group_id":"2",
  "sex":"1",
  "country":"中國",
  "province":"廣東",
  "city":"廣州",
  "client_platform_type":"2"
  "language":"zh_CN"
  }
}

其中上面的信息,轉換為我們的實體類對象信息就是如下所示。

MenuListJson menuJson

它API返回結果如下所示。

{
	"menuid":"208379533"
}

為了承載這個信息,我們需要定義一個實體類來承載這個信息。

    /// <summary>
    /// 返回MenuId的結果
    /// </summary>
    public class MenuIdResult
    {       
        /// <summary>
        /// 菜單的ID
        /// </summary>
        public string menuid { get; set; }
    }

最後我們的API介面只需要獲取裡面的菜單ID值,字元串類型的就可以了,API具體實現代碼如下所示。

        /// <summary>
        /// 創建個性化菜單
        /// </summary>
        /// <param name="accessToken">調用介面憑證</param>
        /// <param name="menuJson">菜單對象</param>
        /// <returns></returns>
        public string CreateConditionalMenu(string accessToken, MenuListJson menuJson)
        {
            string result = "";
            var url = string.Format("https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token={0}", accessToken);
            //matchrule不能為空
            ArgumentValidation.CheckForNullReference(menuJson.matchrule, "matchrule");

            string postData = menuJson.ToJson();
            MenuIdResult list = JsonHelper<MenuIdResult>.ConvertJson(url, postData);
            if (list != null)
            {
                result = list.menuid;
            }
            return result;
        }

而刪除個性化菜單的介面也是類似的處理,如下所示。

        /// <summary>
        /// 根據菜單ID刪除個性化菜單
        /// </summary>
        /// <param name="accessToken">調用介面憑證</param>
        /// <param name="menuid">菜單ID</param>
        /// <returns></returns>
        public CommonResult DeleteConditionalMenu(string accessToken, string menuid)
        {
            var url = string.Format("https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token={0}", accessToken);
            var data = new
            {
                menuid = menuid
            };

            string postData = data.ToJson();
            return Helper.GetExecuteResult(url, postData);
        }

另外,對於個性化菜單來說,查詢、刪除所有的菜單操作介面和普通預設菜單是一樣的,因此可以重用這兩個介面,不過由於我們擴展了查詢返回的信息類,所以如果是個性化菜單,那麼它返回的JSON字元串裡面,包含了conditionalmenu的屬性,這個是一個集合 ,也就是說個性化菜單是多個規則的個性化菜單的集合。

菜單的JSON數據結構如下所示。

 

3、個性化菜單封裝介面的使用

有了上面介面的封裝,我們可以在創建個性化菜單的時候很方便了,構建個性化菜單的時候,我們需要把全部需要出現的菜單都需要放在一個conditionalmenu的單元裡面,雖然這樣的單元在集合裡面出現多個。

如下麵是構建一個個性化的菜單項目,和普通的預設菜單不同,它需要指定一個matchrule的對象,如下代碼所示。

            MenuJson conditional = new MenuJson("相關鏈接", new MenuJson[] { 
                new MenuJson("個性化菜單", ButtonType.click, "event_company")
            });
            MatchRule rule = new MatchRule()
            {
                sex = "1"
            };

            MenuListJson menuJson = new MenuListJson();
            menuJson.button.AddRange(new MenuJson[] { conditional });
            menuJson.matchrule = rule;

通過上面的代碼瞭解,我們如果需要增加多個個性化菜單,那麼就是通過這個方法,每次創建一個個性化菜單的方式進行構建,當然如果我們使用查詢個性化菜單的結果可以看到,如果創建多個,那麼conditionalmenu集合裡面是多個對象的。

調用代碼每次添加一個個性化菜單的操作如下所示。

                string menuid = menuBLL.CreateConditionalMenu(token, menuJson);
                Console.WriteLine("創建菜單:" + (!string.IsNullOrEmpty(menuid) ? "成功:" + menuid : "失敗"));

我們創建多個規則後,可以通過TryMatch的方式來檢查匹配的結果,也就是對應不同用戶(openid)會出現不同的個性化菜單列表了。

                    var myResult = menuBLL.TryMatchConditionalMenu(token, openId);
                    if (myResult != null)
                    {
                        Console.WriteLine(myResult.ToJson());
                    }

                    var userid_female = "oSiLnt2J4mYkhVG3aLTdMIF1hv-s";//女性的ID
                    myResult = menuBLL.TryMatchConditionalMenu(token, userid_female);
                    if (myResult != null)
                    {
                        Console.WriteLine(myResult.ToJson());
                    }

 

如果對這個《C#開發微信門戶及應用》系列感興趣,可以關註我的其他文章,系列隨筆如下所示:

C#開發微信門戶及應用(28)--微信“搖一搖·周邊”功能的使用和介面的實現

C#開發微信門戶及應用(27)-公眾號模板消息管理 

C#開發微信門戶及應用(26)-公眾號微信素材管理

C#開發微信門戶及應用(25)-微信企業號的客戶端管理功能

C#開發微信門戶及應用(24)-微信小店貨架信息管理

C#開發微信門戶及應用(23)-微信小店商品管理介面的封裝和測試

C#開發微信門戶及應用(22)-微信小店的開發和使用

C#開發微信門戶及應用(21)-微信企業號的消息和事件的接收處理及解密 

C#開發微信門戶及應用(20)-微信企業號的菜單管理

C#開發微信門戶及應用(19)-微信企業號的消息發送(文本、圖片、文件、語音、視頻、圖文消息等)

C#開發微信門戶及應用(18)-微信企業號的通訊錄管理開發之成員管理

C#開發微信門戶及應用(17)-微信企業號的通訊錄管理開發之部門管理

C#開發微信門戶及應用(16)-微信企業號的配置和使用

C#開發微信門戶及應用(15)-微信菜單增加掃一掃、發圖片、發地理位置功能

 C#開發微信門戶及應用(14)-在微信菜單中採用重定向獲取用戶數據

C#開發微信門戶及應用(13)-使用地理位置擴展相關應用

C#開發微信門戶及應用(12)-使用語音處理

C#開發微信門戶及應用(11)--微信菜單的多種表現方式介紹

C#開發微信門戶及應用(10)--在管理系統中同步微信用戶分組信息

C#開發微信門戶及應用(9)-微信門戶菜單管理及提交到微信伺服器

C#開發微信門戶及應用(8)-微信門戶應用管理系統功能介紹

C#開發微信門戶及應用(7)-微信多客服功能及開發集成

C#開發微信門戶及應用(6)--微信門戶菜單的管理操作

C#開發微信門戶及應用(5)--用戶分組信息管理

C#開發微信門戶及應用(4)--關註用戶列表及詳細信息管理

C#開發微信門戶及應用(3)--文本消息和圖文消息的應答

C#開發微信門戶及應用(2)--微信消息的處理和應答

C#開發微信門戶及應用(1)--開始使用微信介面


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

-Advertisement-
Play Games
更多相關文章
  • 介紹 在日常維護工作當中經常會需要對數據進行導出操作,而mysqldump是導出數據過程中使用非常頻繁的一個工具;它自帶的功能參數非常多,文章中會列舉出一些常用的操作,在文章末尾會將所有的參數詳細說明列出來。 語法: 預設不帶參數的導出,導出文本內容大概如下:創建資料庫判斷語句-刪除表-創建表-鎖表 ...
  • 文章出自:聽雲博客 前段時間,Oracle官方發佈了MySQL 5.7的GA版本。新版本中實現了真正意義的並行複製(基於Group Commit的Group Replication),而不再是基於schema的並行複製。這一特性極大的改善了特定場景下的主從複製延遲過高的狀況。隨著MySQL成熟度的提 ...
  • 1. 軟體源 2. 更新並升級已有軟體,並安裝一些基礎依賴庫 3. 安裝軟體 Nginx/MySQL/Redis/Git/SVN apt-get install nginx mysql-server redis-server git subversion PHP 及核心擴展 apt-get inst ...
  • 這個問題發生後,我覺得很疑惑,因為伺服器上確定沒有安裝印表機。那麼印表機是從哪裡來的呢? 通過百度搜索,發現網上的一個帖子解答了我的疑惑。原帖地址:http://blog.chinaunix.net/uid-563697-id-1989152.html 原來是連接遠程桌面時,將本地的印表機共用的原因 ...
  • 安裝了一個ubuntu 15.10,沒有集成vim,很失望,先安裝個vim,sudo apt-get install vim。 開始獲取g++-5: $ sudo add-apt-repository ppa:ubuntu-toolchain-r/test $ sudo apt-get update ...
  • VMware下,centos系統,安裝好後,一直連不上外網。在網上查了好多資料,都沒有找到解決的辦法。最後,把自己的解決方案,寫到下麵。 第一步、打開文件 $ vim /etc/sysconfig/network-scripts/ifcfg-eth0 #自動獲取DEVICE=eth0BOOTPROT ...
  • 安裝php yum install php yum install php-mysql php-gd php-imap php-ldap php-odbc php-pear php-xml php-xmlrpc yum install php yum install php-mysql php-gd ...
  • 作為本系列博文的開篇,有必要先做些聲明,用於免責、以絕口水: 1. 博文僅圍繞已經棄用的、C/S結構的《上海市個人非營業性客車額度競拍程式》客戶端(NetBidClient)進行介紹,對於正在使用的系統不進行任何討論。 2. 作者從未向“代拍黃牛”提供過任何技術支持或外掛軟體,也沒有依賴相關技術從事 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...