微信自定义菜单

2019-03-02 00:05|来源: 网路

组织菜单内容

目前自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。请注意,创建自定义菜单后,由于微信客户端缓存,需要24小时微信客户端才会展现出来。建议测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。

目前自定义菜单接口可实现两种类型按钮,如下:

click: 用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event 的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;

view: 用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的url值 (即网页链接),达到打开网页的目的,建议与网页授权获取用户基本信息接口结合,获得用户的登入个人信息。

 {     "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字节

返回结果

正确时的返回JSON数据包如下:

{"errcode":0,"errmsg":"ok"}

错误时的返回JSON数据包如下(示例为无效菜单名长度):

{"errcode":40018,"errmsg":"invalid button name size"}

<? =  = '' = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=". = https_request(, ( https_request(, =  =, CURLOPT_URL, , CURLOPT_SSL_VERIFYPEER, , CURLOPT_SSL_VERIFYHOST,  (!(, CURLOPT_POST, 1, CURLOPT_POSTFIELDS, , CURLOPT_RETURNTRANSFER, 1 = curl_exec(

或者使用官方的调试接口 使用网页调试工具调试该接口

提交成功后,重新关注后即可看到菜单。


响应菜单点击事件

在消息接口中处理event事件,其中的click代表菜单点击,通过响应菜单结构中的key值回应消息,view事件无须响应,将直接跳转过去

<?php

define("TOKEN", "你的TOKEN");

$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;
    }
}
?>



菜单中获取OpenID

由于菜单中只能填写固定的url地址,对于想要菜单中获取用户的OpenID的情况,可以使用OAuth2.0授权的方式来实现。

URL中填写的地址为一个固定的回调地址。原理方法可以参考 OAuth2.0网页授权


转自:http://my.oschina.net/xinson/blog/297002

相关问答

更多
  • 解决web乱码问题工具类 cookie工具类 session工具类 Servlet文件上传工具类 SpringMVC文件上传工具类 数据库操作工具类 windows进程工具类
  • 不是访问你自己的服务么?追问是自己的服务器,感觉自定义菜单是应该在微信的服务器里运行才可以回答自定义的菜单 微信里只是一个链接 调用的是你自己的服务 你要自己部署一个服务器 有对外的访问ip追问那是菜单设置完成后考虑的事,链接,公网ip我都有,现在只差这个菜单设置了回答哦 终于搞懂了 那个是微信提供了一个管理的界面啊 可以设置菜单名称 链接之类的追问怪我没说明白,我现在有接口代码,问题是不知道怎么让它部署运行回答tomcat部署服务?是少这个么追问不是,微信公众平台开发者模式首先需要接口来链接你自己的服务器 ...
  • 首先声明,不是guanggao ,去看看 jfinalweixin ,超级全的带注释的解决方案。 配置好公众号的 几个参数,直接可用。 自定义菜单本质就是一个json 数据 post 过去就好了,特别简单。
  • 如下: public static String do_post(String url, List name_value_pair) throws IOException { String body = "{}"; DefaultHttpClient httpclient = new DefaultHttpClient(); try { HttpPost httpost = new HttpPost(url); httpost.setEntity(new UrlEncodedFormEntity(name_ ...
  • 自定义菜单并不是你写几个文字就可以了,每个菜单都要设置对应的响应动作,否则发布不生效。 你分别点你设置的每一个二级菜单名字,右边就有两个蓝色大圆钮让你继续设置,上面有简单提示,基本很容易看明白。有发送消息,也有跳转到图文消息。如果有其中一个没有设置,就无法发布成功。 未认证的订阅号只能发送图片,语音,视频,或是跳转到图文消息。 设置好之后,先预览,确认无误,再去发布。
  • 若开启微信开发者模式则需要在绑定微信公众账号的第三方平台上进行设置。 开启微信开发者模式后,自定义菜单不可以通过微信公众平台进行设置的。 开发者模式关闭后,可通过微信公众平台设置自定义菜单。 微信公众平台,简称weChat。曾命名为“官号平台”和“媒体平台”,最终定位为“公众平台”,无疑让我们看到一个微信对后续更大的期望。和新浪微博早期从明星战略着手不同,微信此时已经有了亿级的用户,挖掘自己用户的价值,为这个新的平台增加更优质的内容,创造更好的粘性,形成一个不一样的生态循环,是平台发展初期更重要的方向
  • 这个你申请了原创就有原创模板的啊,就是你截图的,如果申请没通过就只能二次开发,开发出这个功能,也是可以的,要公众号开发可以问我
  • 一:微信公众平台添加一级菜单 1 首先,成功登录微信公众平台; 并进入编辑模式; 2 自定义菜单默认为启用状态, 单击“设置”; 3 单击菜单管理后的“添加”, 4 输入菜单名,(菜单名称不要超过4个汉字或8个字母,否则显示不全) 单击“确认” 5 可同上单击“添加”添加一级菜单, 继续添加一级菜单; 6 注意: 可创建最多3个一级菜单,注意合理规划一级菜单; 二:微信公众平台添加二级菜单 1 若想要添加二级菜单, 鼠标悬浮于相应一级菜单, 会显示“添加”、“修改”、“删除”图标, 单击“添加”图标; 2 ...
  • 做的二次开发,这种比较常用,你会写程序就行,还不清楚可问我
  • 有两种开发方式:完全自己开发和使用第三方平台。 完全自己开发难度稍大,需要有网络应用开发能力,首先读微信公众号开发的官方文档,写得还是比较详细的,然后可以参考一下教程,可以学到不少东西。大概流程就是在自己的服务器上写代码,负责处理微信发来的消息,然后按照一定格式回复消息。 使用第三方平台难度较小,但是自由度也较小,可以直接配置别人写好的功能,自己的需求很多时候已经有现成的可以用。 微信公众号开发现在比较热门,怎么开发需要看公司规模以及准备实现多么复杂的功能。如果公司规模较大,可以支持员工全职开发的话,那当然 ...