微信公衆號開發(四)自定義菜單

 

本篇文章,我們來做一個最常見的,也是用戶最喜歡使用的功能——自定義菜單。
因爲菜單只需要點一下就可以獲取需要的信息,無需用戶手動輸入關鍵字,用戶體驗相對來說比較好。

打開開發文檔,選擇"自定義菜單"的"菜單創建接口"。

注意:
1、自定義菜單最多包括3個一級菜單,每個一級菜單最多包含5個二級菜單。
2、一級菜單最多4個漢字,二級菜單最多7個漢字,多出來的部分將會以“...”代替。
3、創建自定義菜單後,微信是有一定的菜單刷新策略,不會立馬看到效果,儘量嘗試先取消關注後再次關注,即可以看到創建後的效果。

菜單的類型非常多,文檔中列了10種類型,這裏不一一說明

舉兩個比較常見的類型:
1、click:點擊推事件類型,即點擊之後微信服務器會推送一個事件類型的消息到我們的URL上,與之前的關注/取消關注類似。
2、view:跳轉URL類型,即點擊之後可以跳轉到指定的網頁地址。

現在我們利用click類型的按鈕來實現需求:

用戶點擊"安生"按鈕後,公衆號馬上推送安生的信息,點擊"工業大學"按鈕後,馬上推送學校信息,不需要用戶再手動輸入關鍵字。

實現細節:

1.用戶點擊click類型按鈕後,微信服務器會推送一個事件類型的消息到URL上,也就是意味着需要使用之前的MsgType判斷是否爲event類型。
2.需要判斷是什麼事件,我們之前判斷的是關注事件subscribe,但現在是click類型,所以Event屬性我們需要判斷是否爲click。
3.我們可能會有很多個click類型的按鈕,所以需要根據不同的按鈕來回復不同的內容,微信爲每個click類型的按鈕提供了key屬性,不同的按鈕設置不同的key值,根據key值即可知道當前需要處理的是哪個按鈕。

創建菜單:

那麼接下來,我們就需要創建自定義菜單了。

開發文檔中,已經提供創建菜單的接口地址了,我們需要把菜單轉換爲json數據傳遞過去。

下圖是官方提供的菜單具體參數:

先把我們的要創建的自定義菜單對應的json數據準備好:

{
     "button":[
     {    
          "type":"click",
          "name":"安生",
          "key":"as"
      },
     {    
          "type":"click",
          "name":"工業大學",
          "key":"xx"
      },
      {
           "name":"愛好",
           "sub_button":[
           {    
               "type":"view",
               "name":"農藥",
               "url":"http://www.baidu.com"
            },
           {    
               "type":"view",
               "name":"吃雞",
               "url":"http://www.mi.com"
            }]
       }]
 }

access_token介紹

接下來,我們注意看這個接口的地址:https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN

地址最後有一個access_token的參數,對於該參數的介紹,在開發文檔的"首頁"有這麼一句話。

公衆平臺以access_token爲接口調用憑據,來調用接口,所有接口的調用需要先獲取access_token,也就意味着它就是一個門票,請求接口時需要帶上這個門票,如果沒有就無法獲取需要的信息,access_token在2小時內有效,過期需要重新獲取,但1天內獲取次數有限,開發者需自行存儲,詳見獲取接口調用憑據(access_token)文檔。

這句話說明了我們在調用接口之前,必須先獲取到access_token這麼一個憑據。

獲取access_token

打開文檔 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183

文檔告訴我們,access_token的有效期目前爲2個小時,需定時刷新,重複獲取將導致上次獲取的access_token失效,而且也有獲取的次數限制,所以我們應該把它緩存起來,2個小時內重複使用,另外, 如果access_token要保存在數據庫中,至少要保留512個字符空間。

通過文檔介紹可知,我們請求指定的接口地址,並且把我們之前分配到的appid與secret作爲參數傳遞過去,即可以獲取到有效的access_token。

代碼:

package com.ansheng.util;

import java.util.Date;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public class WechatUtil {
	//URL驗證時使用的token
   public static final String TOKEN="has";
   //appid
   public static final String APPID="自己的appid";
   //secret
   public static final String SECRET="自己的secret";
   //創建菜單接口地址
   public static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
   //獲取access_token的接口地址ַ
   public static final String GET_ACCESSTOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
   //緩存的access_token
   private static String accessToken;
   //access_token的失效時間
   private static long expiresTime;
   
   
   /***
       * 獲取accessToken
    */
   public static String getAccessToken() {
	   //判斷accessToken是否已經過期,如果過期需要重新獲取
	   if(accessToken==null||expiresTime<new Date().getTime()) {
		   //發起請求獲取accessToken
		   String result=HttpUtil.sendGet(GET_ACCESSTOKEN_URL.replace("APPID", APPID).replace("APPSECRET", SECRET),"");
		   //把json字符串轉換爲json對象
		   JSONObject json = JSON.parseObject(result);
		   //緩存accessToken
           accessToken = json.getString("access_token");
           //設置accessToken的失效時間
           long expires_in = json.getLong("expires_in");
           //失效時間 = 當前時間 + 有效期(提前一分鐘)
           expiresTime = new Date().getTime()+ (expires_in-60) * 1000;
	   }
	   return accessToken;
   }
   
   /***
    * �����Զ���˵�
    */
   public static void createMenu(String menu){
       String result = HttpUtil.sendPost(CREATE_MENU_URL.replace("ACCESS_TOKEN", getAccessToken()),menu);
       System.out.println(result);
   }
   public static void main(String[] args) {
	   String menu="{\r\n" + 
	   		"     \"button\":[\r\n" + 
	   		"     {    \r\n" + 
	   		"          \"type\":\"click\",\r\n" + 
	   		"          \"name\":\"安生\",\r\n" + 
	   		"          \"key\":\"as\"\r\n" + 
	   		"      },\r\n" + 
	   		"     {    \r\n" + 
	   		"          \"type\":\"click\",\r\n" + 
	   		"          \"name\":\"工業大學\",\r\n" + 
	   		"          \"key\":\"xx\"\r\n" + 
	   		"      },\r\n" + 
	   		"      {\r\n" + 
	   		"           \"name\":\"愛好\",\r\n" + 
	   		"           \"sub_button\":[\r\n" + 
	   		"           {    \r\n" + 
	   		"               \"type\":\"view\",\r\n" + 
	   		"               \"name\":\"農藥\",\r\n" + 
	   		"               \"url\":\"http://www.baidu.com\"\r\n" + 
	   		"            },\r\n" + 
	   		"           {    \r\n" + 
	   		"               \"type\":\"view\",\r\n" + 
	   		"               \"name\":\"吃雞\",\r\n" + 
	   		"               \"url\":\"http://www.mi.com\"\r\n" + 
	   		"            }]\r\n" + 
	   		"       }]\r\n" + 
	   		" }";
	   createMenu(menu);
	  
}
}

 

代碼中的HttpUtil是發起http請求的工具類,網上可以找到很多,這裏就不貼出來了。

通過getAccessToken方法我們就可以獲取到需要的accessToken憑據了。

接下來我們使用main方法直接調用createMenu方法,把菜單的json數據傳入即可。當然,想要更靈活的設置菜單,需要寫菜單管理的相關頁面使用可視化的方式來編輯菜單。

接口響應的結果爲:{"errcode":0,"errmsg":"ok"},代表菜單創建成功,這時候就可以打開公衆號測試了,如果不能及時看到新的菜單,應先取消關注再重新關注公衆號。

如果響應的結果是其他,代表創建過程出錯了,這時候應該對照錯誤碼,查找錯誤原因。

上面列出的是比較常見的錯誤,如果上面找不到,需要在全局返回碼中搜索。
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433747234

菜單效果:

菜單已經創建成功,我們最後一步就是做業務處理了。

1.InMsgEntity類添加EventKey屬性

2.判斷菜單key值

	@RequestMapping(value="/intoWechat",method=RequestMethod.POST,produces= {MediaType.TEXT_XML_VALUE})
	@ResponseBody
	public Object handleMessage(@RequestBody InMsgEntity msg) {
		//創建消息響應對象
		OutMsgEntity out=new OutMsgEntity();
		//把原來的發送方設置爲接收方
		out.setToUserName(msg.getFromUserName());
		//把原來的接收方設置爲發送方
		out.setFromUserName(msg.getToUserName());
		//獲取接收的消息類型
		String msgType=msg.getMsgType();
		out.setMsgType(msgType);
		//設置消息創建時間
		out.setCreateTime(new Date().getTime());
		//公衆號回覆內容
		String outContent=null;
		//根據類型設置不同的消息數據
		if("text".equals(msgType)) {
			String inContent=msg.getContent();
			if(inContent.contains("安生")) {
				outContent="安生畢業於中原工業大學,該學校建於1955年,原名中原工學院";
			}else if(inContent.contains("中原工業大學")) {
				outContent="中原工業大學隸屬於教育部和河南省共建高校,原名中原工學院,於2022年更名爲中原工業大學";
			}else {
				//發送什麼就回什麼
				outContent=inContent;
			}
			out.setContent(outContent);
		}else if("image".contentEquals(msgType)) {
			out.setMediaId(new String[] {msg.getMediaId()});
		}else if("event".equals(msgType)) {
			//判斷關注事件
			if("subscribe".equals(msg.getEvent())) {
				out.setContent("歡迎關注,我是安生![愉快]");
				//設置消息響應類型
				out.setMsgType("text");
			}else if("CLICK".equals(msg.getEvent())) {
				//獲取菜單的key值
				String key=msg.getEventKey();
				if("as".equals(key)) {
					 outContent = "安生畢業於中原工業大學,該學校建於1955年,原名中原工學院";
				}else if("xx".equals(key)) {
					outContent="中原工業大學隸屬於教育部和河南省共建高校,原名中原工學院,於2022年更名爲中原工業大學";

				}
				out.setMsgType("text");
                out.setContent(outContent);
			}
			
			
		}
		return out;
	}

此時就結束了

發佈了87 篇原創文章 · 獲贊 40 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章