一、自定义菜单概述
自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的功能。开启自定义菜单后,公众号界面如图所示:
二、申请自定义菜单
个人订阅号使用微博认证、企业订阅号通过微信认证;可以申请到自定义菜单资格
服务号默认有菜单权限。
三、获得AppId 和AppSecert
AppId和AppSecret在开发者中心-开发者ID中,可以找到。
四、获得Access Token
用appid和appsecert获得access token,接口为
程序实现如下
$appid = ; $appsecret = ; $url =
你也可以直接在浏览器地址栏中,拼接出地址,执行后,获得如下数据
复制代码 代码如下:{access_token:N2L7KXa084WvelONYjkJ_traBMCCvy_UKmpUUzlrQ0EA2yNp3Iz6eSUrRG0bhaR_viswd50vDuPkY5nG43d1gbm-olT2KRMxOsVE08RfeD9lvK9lMguNG9kpIkKGZEjIf8Jv2m9fFhf8bnNa-yQH3g,
复制代码 代码如下:expires_in:7200}
参数说明如下
其中的
N2L7KXa084WvelONYjkJ_traBMCCvy_UKmpUUzlrQ0EA2yNp3Iz6eSUrRG0bhaR_viswd50vDuPkY5nG43d1gbm-olT2KRMxOsVE08RfeD9lvK9lMguNG9kpIkKGZEjIf8Jv2m9fFhf8bnNa-yQH3g
就是access token。
或者使用官方的接口调试工具,地址为:
使用网页调试工具调试自定义菜单接口
点击检查问题得,得到
这样也获得了access token
五、组织菜单内容
目前自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代 替。请注意,创建自定义菜单后,由于微信客户端缓存,需要24小时微信客户端才会展现出来。建议测试时可以尝试取消关注公众账号后再次关注,则可以看到创 建后的效果。
目前自定义菜单接口可实现两种类型按钮,如下:
click:
用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event 的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;
view:
用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的url值 (即网页链接),达到打开网页的目的,建议与网页授权获取用户基本信息接口结合,获得用户的登入个人信息。
接口调用请求说明
http请求方式:POST(请使用https协议) _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:视频, url:赞一下我们, key:V1001_GOOD }] }] }
参数说明
返回结果
正确时的返回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:方倍工作室,sub_button:[{type:click,name:公司简 介,key:company}, {type:click,name:趣味游戏,key:游戏}, {type:click,name:讲个笑话,key:笑话}]}]}
将以下代码保存为menu.php,并且在浏览器中运行该文件(比如 ),将直接向微信服务器提交菜单
php $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:瑞雪, sub_button:[ { type:click, name:公司简介, key:company }, { type:click, name:趣味游戏, key:游戏 }, { type:click, name:讲个笑话, key:笑话 }] }] }; $url =
或者使用官方的调试接口 使用网页调试工具调试该接口
提交成功后,重新关注后即可看到菜单。菜单效果类似如下:
七、响应菜单点击事件
在消息接口中处理event事件,其中的click代表菜单点击,通过响应菜单结构中的key值回应消息,view事件无须响应,将直接跳转过去
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 =>默认菜单回复, Description =>您正在使用的是<span style=font-family: Arial, Helvetica, sans-serif;>洋洋的博客</span><span style=font-family: Arial, Helvetica, sans-serif;>, </span> PicUrl =>首条标题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; } } ?>
八、菜单中获取OpenID
由于菜单中只能填写固定的url地址,对于想要菜单中获取用户的OpenID的情况,可以使用OAuth2.0授权的方式来实现。
URL中填写的地址为一个固定的回调地址。原理方法可以参考 微信公众平台开发(99) 自定义菜单获取OpenID
<?php /* 洋洋的博客 */ define(TOKEN, weixin); $wechatObj = new wechatCallbackapiTest(); if (isset($_GET[echostr])) { $wechatObj->valid(); }else{ $wechatObj->responseMsg(); } class wechatCallbackapiTest { public function valid() { $echoStr = $_GET[echostr]; if($this->checkSignature()){ header(content-type:text); echo $echoStr; exit; } } private function checkSignature() { $signature = $_GET[signature]; $timestamp = $_GET[timestamp]; $nonce = $_GET[nonce]; $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr, SORT_STRING); $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); $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $keyword = trim($postObj->Content); $time = time(); $textTpl = <xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> <FuncFlag>0</FuncFlag> </xml>; if($keyword == ? $keyword == ?) { $msgType = text; $contentStr = 当前时间是:.date(Y-m-d H:i:s,time()); $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); echo $resultStr; } }else{ echo ; exit; } } } ?>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。