一、自定義菜單概述
自定義菜單能夠幫助公衆號豐富界面,讓用戶更好更快地理解公衆號的功能。開啓自定義菜單後,公衆號界面如圖所示:
二、申請自定義菜單
個人訂閱號只能編輯生成菜單,無法開發、企業訂閱號通過微信認證;可以申請到自定義菜單資格
服務號默認有菜單權限。
三、獲得AppId 和AppSecert
AppId和AppSecret在開發者中心-開發者ID中,可以找到。
四、獲得Access Token
用appid和appsecert獲得access token,接口爲
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
程序實現如下
$appid = ""; $appsecret = ""; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); $jsoninfo = json_decode($output, true); $access_token = $jsoninfo["access_token"];
你也可以直接在瀏覽器地址欄中,拼接出地址,執行後,獲得如下數據
{"access_token":"N2L7KXa084WvelONYjkJ_traBMCCvy_UKmpUUzlrQ0EA2yNp3Iz6eSUrRG0bhaR_viswd50vDuPkY5nG43d1gbm-olT2KRMxOsVE08RfeD9lvK9lMguNG9kpIkKGZEjIf8Jv2m9fFhf8bnNa-yQH3g","expires_in":7200}
參數說明如下
參數 |
說明 |
access_token |
獲取到的憑證 |
expires_in |
憑證有效時間,單位:秒 |
其中的
N2L7KXa084WvelONYjkJ_traBMCCvy_UKmpUUzlrQ0EA2yNp3Iz6eSUrRG0bhaR_viswd50vDuPkY5nG43d1gbm-olT2KRMxOsVE08RfeD9lvK9lMguNG9kpIkKGZEjIf8Jv2m9fFhf8bnNa-yQH3g
就是access token。
或者使用官方的接口調試工具,地址爲:
點擊檢查問題得,得到原文 http://www.cnblogs.com/txw1958/p/weixin-58-custom-menu.html
這樣也獲得了access token
五、組織菜單內容
自定義類型包括如下
1、click:點擊推事件 用戶點擊click類型按鈕後,微信服務器會通過消息接口推送消息類型爲event 的結構給開發者(參考消息接口指南),並且帶上按鈕中開發者填寫的key值,開發者可以通過自定義的key值與用戶進行交互; 2、view:跳轉URL 用戶點擊view類型按鈕後,微信客戶端將會打開開發者在按鈕中填寫的網頁URL,可與網頁授權獲取用戶基本信息接口結合,獲得用戶基本信息。 3、scancode_push:掃碼推事件 用戶點擊按鈕後,微信客戶端將調起掃一掃工具,完成掃碼操作後顯示掃描結果(如果是URL,將進入URL),且會將掃碼的結果傳給開發者,開發者可以下發消息。 4、scancode_waitmsg:掃碼推事件且彈出“消息接收中”提示框 用戶點擊按鈕後,微信客戶端將調起掃一掃工具,完成掃碼操作後,將掃碼的結果傳給開發者,同時收起掃一掃工具,然後彈出“消息接收中”提示框,隨後可能會收到開發者下發的消息。 5、pic_sysphoto:彈出系統拍照發圖 用戶點擊按鈕後,微信客戶端將調起系統相機,完成拍照操作後,會將拍攝的相片發送給開發者,並推送事件給開發者,同時收起系統相機,隨後可能會收到開發者下發的消息。 6、pic_photo_or_album:彈出拍照或者相冊發圖 用戶點擊按鈕後,微信客戶端將彈出選擇器供用戶選擇“拍照”或者“從手機相冊選擇”。用戶選擇後即走其他兩種流程。 7、pic_weixin:彈出微信相冊發圖器 用戶點擊按鈕後,微信客戶端將調起微信相冊,完成選擇操作後,將選擇的相片發送給開發者的服務器,並推送事件給開發者,同時收起相冊,隨後可能會收到開發者下發的消息。 8、location_select:彈出地理位置選擇器 用戶點擊按鈕後,微信客戶端將調起地理位置選擇工具,完成選擇操作後,將選擇的地理位置發送給開發者的服務器,同時收起位置選擇工具,隨後可能會收到開發者下發的消息。 9、media_id:下發消息(除文本消息) 用戶點擊media_id類型按鈕後,微信服務器會將開發者填寫的永久素材id對應的素材下發給用戶,永久素材類型可以是圖片、音頻、視頻、圖文消息。請注意:永久素材id必須是在“素材管理/新增永久素材”接口上傳後獲得的合法id。 10、view_limited:跳轉圖文消息URL 用戶點擊view_limited類型按鈕後,微信客戶端將打開開發者在按鈕中填寫的永久素材id對應的圖文消息URL,永久素材類型只支持圖文消息。請注意:永久素材id必須是在“素材管理/新增永久素材”接口上傳後獲得的合法id。
接口調用請求說明
http請求方式:POST(請使用https協議) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
請求示例
{ "button":[ { "type":"click", "name":"今日歌曲", "key":"V1001_TODAY_MUSIC" }, { "type":"click", "name":"歌手簡介", "key":"V1001_TODAY_SINGER" }, { "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" }] }] }
參數說明
參數 | 是否必須 | 說明 |
---|---|---|
button | 是 | 一級菜單數組,個數應爲1~3個 |
sub_button | 否 | 二級菜單數組,個數應爲1~5個 |
type | 是 | 菜單的響應動作類型,目前有click、view兩種類型 |
name | 是 | 菜單標題,不超過16個字節,子菜單不超過40個字節 |
key | click類型必須 | 菜單KEY值,用於消息接口推送,不超過128字節 |
url | view類型必須 | 網頁鏈接,用戶點擊菜單可打開鏈接,不超過256字節 |
原文 http://www.cnblogs.com/txw1958/p/weixin-58-custom-menu.html
返回結果
正確時的返回JSON數據包如下:
{"errcode":0,"errmsg":"ok"}
錯誤時的返回JSON數據包如下(示例爲無效菜單名長度):
{"errcode":40018,"errmsg":"invalid button name size"}
六、提交菜單內容給服務器
菜單的JSON結構爲
{"button":[{"name":"天氣預報","sub_button":[{"type":"click","name":"北京天氣","key":"天氣北京"},{"type":"click","name":"上海天氣","key":"天氣上海"},{"type":"click","name":"廣州天氣","key":"天氣廣州"},{"type":"click","name":"深圳天氣","key":"天氣深圳"},{"type":"view","name":"本地天氣","url":"http://m.hao123.com/a/tianqi"}]},{"name":"方倍工作室","sub_button":[{"type":"click","name":"公司簡介","key":"company"},{"type":"click","name":"趣味遊戲","key":"遊戲"},{"type":"click","name":"講個笑話","key":"笑話"}]}]}
將以下代碼保存爲menu.php,並且在瀏覽器中運行該文件(比如 http://127.0.0.1/menu.php),將直接向微信服務器提交菜單,
<?php $appid = "aaaaaa"; $appsecret = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret"; $output = https_request($url); $jsoninfo = json_decode($output, true); $access_token = $jsoninfo["access_token"]; $jsonmenu = '{ "button":[ { "name":"天氣預報", "sub_button":[ { "type":"click", "name":"北京天氣", "key":"天氣北京" }, { "type":"click", "name":"上海天氣", "key":"天氣上海" }, { "type":"click", "name":"廣州天氣", "key":"天氣廣州" }, { "type":"click", "name":"深圳天氣", "key":"天氣深圳" }, { "type":"view", "name":"本地天氣", "url":"http://m.hao123.com/a/tianqi" }] }, { "name":"方倍工作室", "sub_button":[ { "type":"click", "name":"公司簡介", "key":"company" }, { "type":"click", "name":"趣味遊戲", "key":"遊戲" }, { "type":"click", "name":"講個笑話", "key":"笑話" }] }] }'; $url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=".$access_token; $result = https_request($url, $jsonmenu); var_dump($result); function https_request($url,$data = null){ $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); if (!empty($data)){ curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $data); } curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($curl); curl_close($curl); return $output; } ?>
原文 http://www.cnblogs.com/txw1958/p/weixin-58-custom-menu.html
或者使用官方的調試接口 使用網頁調試工具調試該接口
提交成功後,重新關注後即可看到菜單。菜單效果類似如下:原文 http://www.cnblogs.com/txw1958/p/weixin-58-custom-menu.html
七、響應菜單點擊事件
在消息接口中處理event事件,其中的click代表菜單點擊,通過響應菜單結構中的key值迴應消息,view事件無須響應,將直接跳轉過去
<?php /* 【版權聲明】 本軟件產品的版權歸方倍工作室所有,受《中華人民共和國計算機軟件保護條例》等知識產權法律及國際條約與慣例的保護。您獲得的只是本軟件的使用權。 您不得: * 在未得到授權的情況下刪除、修改本軟件及其他副本上一切關於版權的信息; * 銷售、出租此軟件產品的任何部分; * 從事其他侵害本軟件版權的行爲。 如果您未遵守本條款的任一約定,方倍工作室有權立即終止本條款的執行,且您必須立即終止使用本軟件並銷燬本軟件產品的任何副本。這項要求對各種拷貝形式有效。 您同意承擔使用本軟件產品的風險,在適用法律允許的最大範圍內,方倍工作室在任何情況下不就因使用或不能使用本軟件產品所發生的特殊的、意外的、非直接或間接的損失承擔賠償責任。即使已事先被告知該損害發生的可能性。 如使用本軟件所添加的任何信息,發生版權糾紛,方倍工作室不承擔任何責任。 方倍工作室對本條款擁有最終解釋權。 CopyRight 2013 方倍工作室 All Rights Reserved */ define("TOKEN", "weixin"); $wechatObj = new wechatCallbackapiTest(); if (!isset($_GET['echostr'])) { $wechatObj->responseMsg(); }else{ $wechatObj->valid(); } class wechatCallbackapiTest { public function valid() { $echoStr = $_GET["echostr"]; if($this->checkSignature()){ echo $echoStr; exit; } } private function checkSignature() { $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr); $tmpStr = implode( $tmpArr ); $tmpStr = sha1( $tmpStr ); if( $tmpStr == $signature ){ return true; }else{ return false; } } public function responseMsg() { $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; if (!empty($postStr)){ $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $RX_TYPE = trim($postObj->MsgType); switch ($RX_TYPE) { case "text": $resultStr = $this->receiveText($postObj); break; case "event": $resultStr = $this->receiveEvent($postObj); break; default: $resultStr = ""; break; } echo $resultStr; }else { echo ""; exit; } } private function receiveText($object) { $funcFlag = 0; $contentStr = "你發送的內容爲:".$object->Content; $resultStr = $this->transmitText($object, $contentStr, $funcFlag); return $resultStr; } private function receiveEvent($object) { $contentStr = ""; switch ($object->Event) { case "subscribe": $contentStr = "歡迎關注方倍工作室"; case "unsubscribe": break; case "CLICK": switch ($object->EventKey) { case "company": $contentStr[] = array("Title" =>"公司簡介", "Description" =>"方倍工作室提供移動互聯網相關的產品及服務", "PicUrl" =>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"weixin://addfriend/pondbaystudio"); break; default: $contentStr[] = array("Title" =>"默認菜單回覆", "Description" =>"您正在使用的是方倍工作室的自定義菜單測試接口", "PicUrl" =>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"weixin://addfriend/pondbaystudio"); break; } break; default: break; } if (is_array($contentStr)){ $resultStr = $this->transmitNews($object, $contentStr); }else{ $resultStr = $this->transmitText($object, $contentStr); } return $resultStr; } private function transmitText($object, $content, $funcFlag = 0) { $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[%s]]></Content> <FuncFlag>%d</FuncFlag> </xml>"; $resultStr = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content, $funcFlag); return $resultStr; } private function transmitNews($object, $arr_item, $funcFlag = 0) { //首條標題28字,其他標題39字 if(!is_array($arr_item)) return; $itemTpl = " <item> <Title><![CDATA[%s]]></Title> <Description><![CDATA[%s]]></Description> <PicUrl><![CDATA[%s]]></PicUrl> <Url><![CDATA[%s]]></Url> </item> "; $item_str = ""; foreach ($arr_item as $item) $item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']); $newsTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[news]]></MsgType> <Content><![CDATA[]]></Content> <ArticleCount>%s</ArticleCount> <Articles> $item_str</Articles> <FuncFlag>%s</FuncFlag> </xml>"; $resultStr = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($arr_item), $funcFlag); return $resultStr; } } ?>
原文 http://www.cnblogs.com/txw1958/p/weixin-58-custom-menu.html
八、菜單中獲取OpenID
由於菜單中只能填寫固定的url地址,對於想要菜單中獲取用戶的OpenID的情況,可以使用OAuth2.0授權的方式來實現。
URL中填寫的地址爲一個固定的回調地址。原理方法可以參考 微信公衆平臺開發(99) 自定義菜單獲取OpenID
九、微信自定義菜單生成器
使用方倍工作室的 微信自定義菜單生成器,可以在線生成菜單,地址爲 http://menu.fangbei.org/