微信提供2種機制生成菜單java
是在公衆平臺官網經過網站功能發佈菜單 ,這種方式接入後臺服務器以後菜單會失效。程序員
是經過API調用設置的菜單json
微信官方文檔是這樣子描述:小程序
一、自定義菜單最多包括3個一級菜單,每一個一級菜單最多包含5個二級菜單。 二、一級菜單最多4個漢字,二級菜單最多7個漢字,多出來的部分將會以「...」代替。 三、建立自定義菜單後,菜單的刷新策略是,在用戶進入公衆號會話頁或公衆號profile頁時,若是發現上一次拉取菜單的請求在5分鐘之前,就會拉取一下菜單,若是菜單有更新,就會刷新客戶端的菜單。測試時能夠嘗試取消關注公衆帳號後再次關注,則能夠看到建立後的效果。
自定義菜單接口類型按鈕,以下10種:api
一、click:點擊推事件用戶點擊click類型按鈕後,微信服務器會經過消息接口推送消息類型爲event的結構給開發者(參考消息接口指南),而且帶上按鈕中開發者填寫的key值,開發者能夠經過自定義的key值與用戶進行交互; 二、view:跳轉URL用戶點擊view類型按鈕後,微信客戶端將會打開開發者在按鈕中填寫的網頁URL,可與網頁受權獲取用戶基本信息接口結合,得到用戶基本信息。 三、scancode_push:掃碼推事件用戶點擊按鈕後,微信客戶端將調起掃一掃工具,完成掃碼操做後顯示掃描結果(若是是URL,將進入URL),且會將掃碼的結果傳給開發者,開發者能夠下發消息。 四、scancode_waitmsg:掃碼推事件且彈出「消息接收中」提示框用戶點擊按鈕後,微信客戶端將調起掃一掃工具,完成掃碼操做後,將掃碼的結果傳給開發者,同時收起掃一掃工具,而後彈出「消息接收中」提示框,隨後可能會收到開發者下發的消息。 五、pic_sysphoto:彈出系統拍照發圖用戶點擊按鈕後,微信客戶端將調起系統相機,完成拍照操做後,會將拍攝的相片發送給開發者,並推送事件給開發者,同時收起系統相機,隨後可能會收到開發者下發的消息。 六、pic_photo_or_album:彈出拍照或者相冊發圖用戶點擊按鈕後,微信客戶端將彈出選擇器供用戶選擇「拍照」或者「從手機相冊選擇」。用戶選擇後即走其餘兩種流程。 七、pic_weixin:彈出微信相冊發圖器用戶點擊按鈕後,微信客戶端將調起微信相冊,完成選擇操做後,將選擇的相片發送給開發者的服務器,並推送事件給開發者,同時收起相冊,隨後可能會收到開發者下發的消息。 八、location_select:彈出地理位置選擇器用戶點擊按鈕後,微信客戶端將調起地理位置選擇工具,完成選擇操做後,將選擇的地理位置發送給開發者的服務器,同時收起位置選擇工具,隨後可能會收到開發者下發的消息。 九、media_id:下發消息(除文本消息)用戶點擊media_id類型按鈕後,微信服務器會將開發者填寫的永久素材id對應的素材下發給用戶,永久素材類型能夠是圖片、音頻、視頻、圖文消息。請注意:永久素材id必須是在「素材管理/新增永久素材」接口上傳後得到的合法id。 十、view_limited:跳轉圖文消息URL用戶點擊view_limited類型按鈕後,微信客戶端將打開開發者在按鈕中填寫的永久素材id對應的圖文消息URL,永久素材類型只支持圖文消息。請注意:永久素材id必須是在「素材管理/新增永久素材」接口上傳後得到的合法id。
請注意,3到8的全部事件,僅支持微信iPhone5.4.1以上版本,和Android5.4以上版本的微信用戶,舊版本微信用戶點擊後將沒有迴應,開發者也不能正常接收到事件推送。9和10,是專門給第三方平臺旗下未微信認證(具體而言,是資質認證未經過)的訂閱號準備的事件類型,它們是沒有事件推送的,能力相對受限,其餘類型的公衆號沒必要使用。數組
接口調用請求說明服務器
http請求方式:POST(請使用https協議) https://api.weixin.qq.com/cgi...微信
click和view的請求示例微信開發
{ "button":[ { "type":"click", "name":"今日歌曲", "key":"V1001_TODAY_MUSIC" }, { "name":"菜單", "sub_button":[ { "type":"view", "name":"搜索", "url":"http://www.soso.com/" }, { "type":"miniprogram", "name":"wxa", "url":"http://mp.weixin.qq.com", "appid":"wx286b93c14bbf93aa", "pagepath":"pages/lunar/index" }, { "type":"click", "name":"贊一下咱們", "key":"V1001_GOOD" }] }] }
其餘新增按鈕類型的請求示例app
{ "button": [ { "name": "掃碼", "sub_button": [ { "type": "scancode_waitmsg", "name": "掃碼帶提示", "key": "rselfmenu_0_0", "sub_button": [ ] }, { "type": "scancode_push", "name": "掃碼推事件", "key": "rselfmenu_0_1", "sub_button": [ ] } ] }, { "name": "發圖", "sub_button": [ { "type": "pic_sysphoto", "name": "系統拍照發圖", "key": "rselfmenu_1_0", "sub_button": [ ] }, { "type": "pic_photo_or_album", "name": "拍照或者相冊發圖", "key": "rselfmenu_1_1", "sub_button": [ ] }, { "type": "pic_weixin", "name": "微信相冊發圖", "key": "rselfmenu_1_2", "sub_button": [ ] } ] }, { "name": "發送位置", "type": "location_select", "key": "rselfmenu_2_0" }, { "type": "media_id", "name": "圖片", "media_id": "MEDIA_ID1" }, { "type": "view_limited", "name": "圖文消息", "media_id": "MEDIA_ID2" } ] }
參數說明
參數 | 是否必須 | 說明 |
---|---|---|
button | 是 | 一級菜單數組,個數應爲1~3個 |
sub_button | 否 | 二級菜單數組,個數應爲1~5個 |
type | 是 | 菜單的響應動做類型,view表示網頁類型,click表示點擊類型,miniprogram表示小程序類型 |
name | 是 | 菜單標題,不超過16個字節,子菜單不超過60個字節 |
key | click等點擊類型必須 | 菜單KEY值,用於消息接口推送,不超過128字節 |
url | view、miniprogram類型必須 | 網頁 連接,用戶點擊菜單可打開連接,不超過1024字節。 type爲miniprogram時,不支持小程序的老版本客戶端將打開本url。 |
media_id | media_id類型和view_limited類型必須 | 調用新增永久素材接口返回的合法media_id |
appid | miniprogram類型必須 | 小程序的appid(僅認證公衆號可配置) |
pagepath | miniprogram類型必須 | 小程序的頁面路徑 |
返回結果
正確時的返回JSON數據包以下:
{"errcode":0,"errmsg":"ok"}
錯誤時的返回JSON數據包以下(示例爲無效菜單名長度):
{"errcode":40018,"errmsg":"invalid button name size"}
代碼示例:
1 簡單的一級菜單能夠直接發送json字符串 ,調用接口便可。
能夠查看此博客 https://www.jianshu.com/p/6ee...
2 複雜的二級菜單
@Data public class BasicButton { private String name; private String type; /** * 二級菜單的數組標籤 爲 sub_button */ private BasicButton []sub_button; }
@Data public class ClickButton extends BasicButton { private String key; }
@Data public class ViewButton extends BasicButton { private String url ; }
public final static String CREAT_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token="; public static void creatOption() { String url = CREAT_OPTION_URL + AccessTokenTool.getToken(); String data = JSON.toJSONString(getMenu()); log.info("發送的菜單json數據爲: " + data); String s = HttpUtil.sendHttpByPost(url, data); log.info("返回的菜單json數據爲: " + s); JSONObject jsonObject = JSONObject.parseObject(s); if (jsonObject.getInteger("errcode") == 0) { log.info("設置自定義菜單成功。"); } else { log.error("設置自定義菜單失敗。"); } } /** * 組裝菜單數據 * * @return */ private static Menu getMenu() { ClickButton btn11 = new ClickButton(); btn11.setName("點擊事件11"); btn11.setType("click"); btn11.setKey("11"); ClickButton btn12 = new ClickButton(); btn12.setName("點擊事件12"); btn12.setType("click"); btn12.setKey("12"); ClickButton btn13 = new ClickButton(); btn13.setName("點擊事件13"); btn13.setType("click"); btn13.setKey("13"); ViewButton btn14 = new ViewButton(); btn14.setName("view類型事件14"); btn14.setType("view"); btn14.setUrl("https://www.baidu.com"); //須要跳轉的url ViewButton btn21 = new ViewButton(); btn21.setName("view類型事件21"); btn21.setType("view"); btn21.setUrl("須要跳轉的url"); //須要跳轉的url ViewButton btn22 = new ViewButton(); btn22.setName("view類型事件22"); btn22.setType("view"); btn22.setUrl("須要跳轉的url"); //須要跳轉的url ClickButton btn31 = new ClickButton(); btn31.setName("點擊事件31"); btn31.setType("click"); btn31.setKey("31"); ViewButton btn32 = new ViewButton(); btn32.setName("view類型事件32"); btn32.setType("view"); btn32.setUrl("/find"); //須要跳轉的url ClickButton btn33 = new ClickButton(); btn33.setName("點擊事件33"); btn33.setType("click"); btn33.setKey("33"); ViewButton btn34 = new ViewButton(); btn34.setName("view類型事件34"); btn34.setType("view"); btn34.setUrl( "https://www.baidu.com"); //須要跳轉的url BasicButton mainBtn1 = new BasicButton(); mainBtn1.setName("一級菜單1"); mainBtn1.setSub_button(new BasicButton[]{ btn11, btn12, btn13 ,btn14}); BasicButton mainBtn2 = new BasicButton(); mainBtn2.setName("一級菜單2"); mainBtn2.setSub_button(new BasicButton[] { btn21, btn22}); BasicButton mainBtn3 = new BasicButton(); mainBtn3.setName("一級菜單3"); mainBtn3.setSub_button(new BasicButton[] { btn31, btn32, btn33,btn34 }); /** * 這是公衆號 「 程序員平常錦集 」 目前的菜單結構 ,每一個一級菜單都有二級菜單項<br> * * 在某個一級菜單下沒有二級菜單的狀況,menu該如何定義呢?<br> * 好比,第三個一級菜單項不是「點擊事件31」,而直接是「view類型事件32」,那麼menu應該這樣定義:<br> * menu.setButton(new Button[] { mainBtn1, mainBtn2, btn32 }); */ Menu menu = new Menu(); menu.setButton(new BasicButton[] { mainBtn1, mainBtn2, mainBtn3 }); return menu; }
微信會將點擊事件推送給開發者,也就是咱們填寫的服務器地址!
這裏請注意:
請注意,點擊菜單彈出子菜單,不會產生上報。 請注意,第3個到第8個的全部事件,僅支持微信iPhone5.4.1以上版本,和Android5.4以上版本的微信用戶,舊版本微信用戶點擊後將沒有迴應,開發者也不能正常接收到事件推送。
推送XML數據包示例:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[CLICK]]></Event> <EventKey><![CDATA[EVENTKEY]]></EventKey> </xml>
參數說明:
事件類型Event爲:CLICK
EventKey 就是咱們自定義菜單時候所填寫的key值,根據這個key值區分不一樣的菜單。
點擊菜單,解析微信推送給咱們的xml數據:
//這裏xml轉爲 map類型了 public static BaseMsg handleClick(Map<String, String> xmlData) { String eventKey = xmlData.get("EventKey"); BaseMsg bm = null; switch (eventKey) { case "11": bm = new TextMsg(xmlData, "菜單11"); break; case "12": bm = new TextMsg(xmlData,"菜單11" );; break; case "13": bm = new TextMsg(xmlData, ""); break; case "31": bm = new TextMsg(xmlData, "更多信息,敬請期待!"); break; case "33": //返回圖文消息 bm = ArticlesMessageTool.getAiticlesMessage(xmlData, "url") //其餘的消息類型本身定義便可 break; default: bm = new TextMsg(xmlData, " 歡迎。。。。 "); } return bm; }
@XStreamAlias("xml") //設置根節點名 @Data public class BaseMsg { //置頂別名首字母大寫 @XStreamAlias("ToUserName") private String toUserName;//開發者微信號 private String FromUserName;//發送方賬號(一個OpenID) private String CreateTime;//消息建立時間 (整型) private String MsgType;//MsgType 文本類型 public BaseMsg(Map<String, String> map) { this.CreateTime = System.currentTimeMillis() / 1000 + ""; this.FromUserName = map.get("ToUserName"); this.toUserName = map.get("FromUserName"); } }
@XStreamAlias("xml") @Data public class TextMsg extends BaseMsg { private String Content;//文本消息內容 public TextMsg(Map<String, String> map, String Content) { super(map); this.Content = Content; this.setMsgType("text"); } }
@XStreamAlias("xml") //設置根節點名 @Data public class ImageMsg extends BaseMsg { private String ArticleCount;// 是 圖文消息個數;當用戶發送文本、圖片、視頻、圖文、地理位置這五種消息時,開發者只能回覆1條圖文消息;其他場景最多可回覆8條圖文消息 private List<ArticlesItem> Articles;// 是 圖文消息信息,注意,若是圖文數超過限制,則將只發限制內的 public ImageMsg() { } public ImageMsg(Map<String, String> map) { super(map); this.setMsgType("news"); }
/** * 獲取圖文消息 * * @param custermName * @param serverName * @param createTime * @param xmlData * @return */ public static ImageMsg getAiticlesMessage(Map<String, String> xmlData, String url) { ImageMsg imageMsg = new ImageMsg(xmlData); List<ArticlesItem> list = new ArrayList<ArticlesItem>(); ArticlesItem item = new ArticlesItem(); String title = "歡迎使用公衆號!"; String description = "點擊圖文進入"; //圖片路徑 String picurl = "本身的服務器地址" + "/img/008.jpg"; item.setDescription(AirPortConfig.description); item.setTitle(AirPortConfig.title); item.setPicUrl(picurl); item.setUrl(url); list.add(item); // 多個能夠繼續設置..... imageMsg.setArticleCount("1"); imageMsg.setMsgType("news"); imageMsg.setArticles(list); return imageMsg; }
public static Map<String, String> getXmlData(InputStream inputStream) { Map<String, String> map = new HashMap<>(); //截取xml SAXReader reader = new SAXReader(); try { Document document = reader.read(inputStream); Element rootElement = document.getRootElement(); //獲取根節點 List<Element> elements = rootElement.elements(); // h獲取全部的節點 for (Element e : elements) { map.put(e.getName(), e.getStringValue()); } } catch (DocumentException e) { e.printStackTrace(); } return map; }
public static String bean2Xml(BaseMsg baseMsg) { XStream xStream = new XStream(); //若沒有這句,xml中的根元素會是<包.類名>;或者說:註解根本就沒生效,因此的元素名就是類的屬性 xStream.processAnnotations(BaseMsg.class); xStream.processAnnotations(TextMsg.class); xStream.processAnnotations(ImageMsg.class); String xml = xStream.toXML(baseMsg); log.info("返回的xml = " + xml); return xml; }
<!-- https://mvnrepository.com/artifact/dom4j/dom4j --> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> <!-- https://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream --> <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.11.1</version> </dependency>
更多信息關注微信公衆號
!