D1V1网源码站

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 3542|回复: 696

[微信&APP] 微信公众平台开发:自定义菜单

[复制链接]

购买VIP,消费全返

微信扫码,惊喜不断

发表于 2017-1-14 15:55:17 | 显示全部楼层 |阅读模式
一、自定义菜单概述
自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的功能。开启自定义菜单后,公众号界面如图所示:
081215272609696.jpg ( X& T2 ^: h! J! p9 q% T
# w' ~7 A+ M6 W; Q6 \
  E3 [  D  M  R9 I% i
6 _! R% z" E" V  y. U- O7 v. |
二、申请自定义菜单

个人订阅号只能编辑生成菜单,无法开发、企业订阅号通过微信认证;可以申请到自定义菜单资格

服务号默认有菜单权限。

. f9 ~8 b5 U  \" u1 D' M5 [
三、获得AppId 和AppSecert
AppId和AppSecret在开发者中心-开发者ID中,可以找到。
292051020278792.jpg
4 n- Z( B/ y: X9 G8 u% S$ I

8 C$ U* `' N  R$ V% H四、获得Access Token

用appid和appsecert获得access token,接口为

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

程序实现如下

[url=][/url]
  r. Z; @! `: _$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"];[url=][/url]
; r+ u& p9 R2 ?& y

( A* V+ j: d8 z) U4 e9 C

你也可以直接在浏览器地址栏中,拼接出地址,执行后,获得如下数据

{"access_token":"N2L7KXa084WvelONYjkJ_traBMCCvy_UKmpUUzlrQ0EA2yNp3Iz6eSUrRG0bhaR_viswd50vDuPkY5nG43d1gbm-olT2KRMxOsVE08RfeD9lvK9lMguNG9kpIkKGZEjIf8Jv2m9fFhf8bnNa-yQH3g","expires_in":7200}; N; B* U) V9 e: k: ~

参数说明如下

参数
说明
access_token
获取到的凭证
expires_in
凭证有效时间,单位:秒

其中的

N2L7KXa084WvelONYjkJ_traBMCCvy_UKmpUUzlrQ0EA2yNp3Iz6eSUrRG0bhaR_viswd50vDuPkY5nG43d1gbm-olT2KRMxOsVE08RfeD9lvK9lMguNG9kpIkKGZEjIf8Jv2m9fFhf8bnNa-yQH3g

就是access token。

或者使用官方的接口调试工具,地址为:

使用网页调试工具调试自定义菜单接口

021958490958196.jpg

点击检查问题得,得到原文 http://www.cnblogs.com/txw1958/p/weixin-58-custom-menu.html

021959502832457.jpg

这样也获得了access token


* q* p9 w2 G1 Q9 E5 S1 C五、组织菜单内容
自定义类型包括如下
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-bi ... _token=ACCESS_TOKEN
请求示例
[url=][/url]
! V8 }9 z; ^* p7 [, Z$ t {     "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"            }]       }] }[url=][/url]" F5 }4 z, G2 e. W& G
. R5 K9 @. G( i) C3 J! u4 D3 g
参数说明
参数是否必须说明
button一级菜单数组,个数应为1~3个
sub_button二级菜单数组,个数应为1~5个
type菜单的响应动作类型,目前有click、view两种类型
name菜单标题,不超过16个字节,子菜单不超过40个字节
keyclick类型必须菜单KEY值,用于消息接口推送,不超过128字节
urlview类型必须网页链接,用户点击菜单可打开链接,不超过256字节
正确时的返回JSON数据包如下:
{"errcode":0,"errmsg":"ok"}
错误时的返回JSON数据包如下(示例为无效菜单名长度):
{"errcode":40018,"errmsg":"invalid button name size"}
3 J* l( B7 y; \7 f* _
7 z8 ], g2 ?/ q7 `" J六、提交菜单内容给服务器
菜单的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":"笑话"}]}]}
7 ^9 I" M8 K+ S" X% M, F/ S

将以下代码保存为menu.php,并且在浏览器中运行该文件(比如 http://127.0.0.1/menu.php),将直接向微信服务器提交菜单,

[url=][/url]% ~: U, n2 J  S4 `  \
<?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;}?>[url=][/url]2 n  u# b: Y5 ]! u3 k5 A8 J' g' m
( |. t. B5 j3 s" Q
或者使用官方的调试接口 使用网页调试工具调试该接口
022005148771356.jpg
022015267521453.jpg
提交成功后,重新关注后即可看到菜单。菜单效果类似如下:原文 http://www.cnblogs.com/txw1958/p/weixin-58-custom-menu.html
052300441261161.jpg 052300492515029.jpg
- \7 o5 u7 A& B$ Z: i5 E1 C
七、响应菜单点击事件
在消息接口中处理event事件,其中的click代表菜单点击,通过响应菜单结构中的key值回应消息,view事件无须响应,将直接跳转过去
[url=][/url]9 e5 m1 O" j6 n4 R
<?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;    }}?>[url=][/url]
: R5 y) f/ R( W7 v

( N. p% D9 |1 A4 {/ m八、菜单中获取OpenID
由于菜单中只能填写固定的url地址,对于想要菜单中获取用户的OpenID的情况,可以使用OAuth2.0授权的方式来实现。
URL中填写的地址为一个固定的回调地址。原理方法可以参考  微信公众平台开发(99) 自定义菜单获取OpenID

( ^  @7 C* B& a  w+ a九、微信自定义菜单生成器
使用方倍工作室的 微信自定义菜单生成器,可以在线生成菜单,地址为 http://menu.fangbei.org/

- r, k3 `% m' q5 @: {十、内容更新及源码下载! X* b  K, T  G  [
yuanma.D1V1.com VIP会员购买源码,消费全返!QQ1184556465
回复

使用道具 举报

购买VIP,消费全返

微信扫码,惊喜不断

发表于 2017-1-14 17:02:59 | 显示全部楼层
前来支持~~~~~~~~~~~~~~~~~~~

yuanma.d1v1.com欢迎你,分享最好的网站商业源码,提供最好的免费空间申请

回复 支持 反对

使用道具 举报

购买VIP,消费全返

微信扫码,惊喜不断

发表于 2017-1-14 18:10:42 | 显示全部楼层
期待中......

yuanma.d1v1.com欢迎你,分享最好的网站商业源码,提供最好的免费空间申请

回复 支持 反对

使用道具 举报

购买VIP,消费全返

微信扫码,惊喜不断

发表于 2017-1-14 19:18:24 | 显示全部楼层
感觉不错

yuanma.d1v1.com欢迎你,分享最好的网站商业源码,提供最好的免费空间申请

回复 支持 反对

使用道具 举报

购买VIP,消费全返

微信扫码,惊喜不断

发表于 2017-1-14 21:37:56 | 显示全部楼层
很给力。。。。很喜欢

yuanma.d1v1.com欢迎你,分享最好的网站商业源码,提供最好的免费空间申请

回复 支持 反对

使用道具 举报

购买VIP,消费全返

微信扫码,惊喜不断

发表于 2017-1-14 23:57:29 | 显示全部楼层
期待中......

yuanma.d1v1.com欢迎你,分享最好的网站商业源码,提供最好的免费空间申请

回复 支持 反对

使用道具 举报

购买VIP,消费全返

微信扫码,惊喜不断

发表于 2017-1-15 02:17:01 | 显示全部楼层
抢楼了,前排第一次啊

yuanma.d1v1.com欢迎你,分享最好的网站商业源码,提供最好的免费空间申请

回复 支持 反对

使用道具 举报

购买VIP,消费全返

微信扫码,惊喜不断

发表于 2017-1-15 03:08:13 | 显示全部楼层
学习一下!十分感谢

yuanma.d1v1.com欢迎你,分享最好的网站商业源码,提供最好的免费空间申请

回复 支持 反对

使用道具 举报

购买VIP,消费全返

微信扫码,惊喜不断

发表于 2017-1-15 03:59:25 | 显示全部楼层
学习了,这就去试试

yuanma.d1v1.com欢迎你,分享最好的网站商业源码,提供最好的免费空间申请

回复 支持 反对

使用道具 举报

购买VIP,消费全返

微信扫码,惊喜不断

发表于 2017-1-15 04:50:37 | 显示全部楼层
不错哦 喜欢 嘿嘿

yuanma.d1v1.com欢迎你,分享最好的网站商业源码,提供最好的免费空间申请

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

客服中心
关闭
加入VIP:点击进入
Email:
1184556465@qq.com
社区VIP用户交流QQ专用群234989379
非VIP请勿加此群
VIP
技术支持
消费全返
客服中心

QQ|D1V1网源码站|手机版|小黑屋|D1V1网源码站 ( 沪ICP备05028199号 )

GMT+8, 2024-11-22 21:13 , Processed in 0.101867 second(s), 31 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表