第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > 微信公众号开发(四)自定义菜单

微信公众号开发(四)自定义菜单

时间:2022-01-03 14:48:21

相关推荐

微信公众号开发(四)自定义菜单

微信公众号开发(四)自定义菜单

1、说明

微信的自定义菜单分为普通菜单和个性化菜单,个性化菜单可以根据地区、性别、语言等为不同的用户展示不同的菜单,定义个性化菜单之前必须定义普通菜单,删除普通菜单则个性化菜单也会删除,自定义菜单有以下需要注意的地方:

自定义菜单最多包括三个一级菜单,每个一级菜单最多包括5个二级菜单。一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”显示。创建自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。

本项目的目录结构如下:

create_menu.php:创建菜单

delete_menu.php:删除菜单

get_menu.php:查询菜单

index.php:接收和处理微信服务器的消息

output_log.php、output_query.php、Utils.php可以参见微信公众号开发(一),主要用于日志的打印,另外Utils.php增加了两函数,分别用于发送请求和获取access_token

Utils.php

<?phpclass Utils{/*** 捕获RUL查询字符串到query.xml*/public static function traceHttp(){$content = date('Y-m-d H:i:s')."\n\rremote_ip:".$_SERVER["REMOTE_ADDR"]."\n\r".$_SERVER["QUERY_STRING"]."\n\r\n\r";$max_size = 1000;$log_filename = "./query.xml";if (file_exists($log_filename) and (abs(filesize($log_filename))) > $max_size){unlink($log_filename);}else {}file_put_contents($log_filename, $content, FILE_APPEND);}/*** 打印日志到log.xml* @param $log_content:日志内容* @param string $type:日志来源,默认‘用户’*/public static function logger($log_content, $type = '用户'){$max_size = 3000;$log_filename = "./log.xml";if (file_exists($log_filename) and (abs(filesize($log_filename)) >$max_size)) {unlink($log_filename);}file_put_contents($log_filename, "$type ".date('Y-m-d H:i:s')."\n\r".$log_content."\n\r",FILE_APPEND);}/*** 获取access_token* @return mixed*/public static function get_access_token(){$appid = "wx07fff9c79a410b69"; //需替换成你的appID$appsecret = "092c0c0c5bd62f66b76ad241612915fb"; //需替换成你的appsecret$url = "https://api./cgi-bin/token?grant_type=client_credential&"."appid=$appid&secret=$appsecret";$output = Utils::https_request($url);$jsoninfo = json_decode($output, true);return $jsoninfo["access_token"];}/*** 发送请求* @param $url:地址* @param null $data:post的数据* @return mixed:请求返回的结果*/public static 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;}}

2、自定义菜单的类型

自定义菜单有8种类型:

click:点击推事件,点击后弹出“获取中...”,微信服务器会通过消息接口推送消息类型为event的结构给开发者,并带上按钮中开发者填写的key值,开发者可用此key值与用户进行交互。view:跳转URL,用户点击后直接打开微信浏览器跳转到该URL的地址。scancode_push:扫码推事件,点击按钮后,微信客户端将调用“扫一扫”功能,完成扫码后在微信浏览器显示扫码结果(如果是URL,则直接进入该URL),且会将扫码结果传送给开发者,此时可以下发消息给用户,但是用户收不到该消息。scancode_waitmsg:扫码推事件且弹出“获取中...”提示框,用户点击按钮后客户端将调用“扫一扫”功能,将扫码结果传给开发者,同时收起“扫一扫”功能,然后弹出“获取中...”提示框,随后可能收到开发者下发的消息。pic_sysphoto:弹出系统拍照发图用户点击按钮后,微信客户端将调起系统相机,完成拍照操作后,会将拍摄的相片发送给开发者,并推送事件给开发者,同时收起系统相机,随后可能会收到开发者下发的消息。pic_photo_or_album:弹出拍照或者相册发图用户点击按钮后,微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。用户选择后即走其他两种流程。pic_weixin:弹出相册发图器用户点击按钮后,微信客户端将调起相册,完成选择操作后,将选择的相片发送给开发者的服务器,并推送事件给开发者,同时收起相册,随后可能会收到开发者下发的消息。location_select:弹出地理位置选择器用户点击按钮后,微信客户端将调起地理位置选择工具,完成选择操作后,将选择的地理位置发送给开发者的服务器,同时收起位置选择工具,随后可能会收到开发者下发的消息。

3、创建普通自定义菜单

创建自定义普通的菜单接口是:https://api./cgi-bin/menu/create?access_token=ACCESS_TOKEN,还需要以post方式将菜单的内容以该接口发送给微信服务器。具体的菜单项的含义请参见自定义菜单文档。

create_menu.php

<?phprequire_once('./Utils.php');//菜单字符串$menujson = '{"button": [{"name": "扫码","sub_button": [{"type": "scancode_waitmsg","name": "扫码带提示","key": "button_0_0"},{"type": "scancode_push","name": "扫码推事件","key": "button_0_1"}]},{"name": "发图","sub_button": [{"type": "pic_sysphoto","name": "系统拍照发图","key": "button_1_0"},{"type": "pic_photo_or_album","name": "拍照或者相册发图","key": "button_1_1"},{"type": "pic_weixin","name": "微信相册发图","key": "button_1_2"}]},{"name": "其他","sub_button": [{"type": "location_select","name": "发送位置","key": "button_2_0"},{"type": "click","name": "单击","key": "button_2_1"},{"type": "view","name": "百度","url": ""}]}]}';$url = $url = "https://api./cgi-bin/menu/create?access_token=".Utils::get_access_token();//创建菜单$result = Utils::https_request($url, $menujson);//返回{"errcode":0,"errmsg":"ok"}表示成功echo $result;

返回结果为{"errcode":0,"errmsg":"ok"}表示成功。注意重新关注公众号才能马上看到效果。截图如下:

再写一个index.php文件来接收服务器推送的消息:

<?php//设置时区date_default_timezone_set("Asia/Shanghai");//定义TOKEN常量,这里的"weixin"就是在公众号里配置的TOKENrequire_once("Utils.php");//打印请求的URL查询字符串到query.xmlUtils::traceHttp();$wechatObj = new wechatCallBackapiTest();$wechatObj->responseMsg();class wechatCallBackapiTest{public function responseMsg(){//获取post过来的数据,它一个XML格式的数据$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];//将数据打印到log.xmlUtils::logger($postStr);if (!empty($postStr)) {//将XML数据解析为一个对象$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);$RX_TYPE = trim($postObj->MsgType);//消息类型分离switch($RX_TYPE){case "event":$result = $this->receiveEvent($postObj);break;case "image":$result = $this->receiveImage($postObj);break;case "location":$result = $this->receiveLocation($postObj);break;default:$result = "";break;}Utils::logger($result, '公众号');echo $result;}else {echo "";exit;}}/** 接收事件消息*/private function receiveEvent($object){switch ($object->Event){case "subscribe": //关注公众号事件$content = "欢迎关注微微一笑很倾城";break;case "unsubscribe":$content = "";break;case "CLICK": //注意这里是大写的CLICK$content = $object->EventKey;break;case "scancode_waitmsg":sleep(2); //方便测试观看效果$content = $object->EventKey." ".$object->ScanCodeInfo->ScanResult;break;case "scancode_push":sleep(2); //方便测试观看效果$content = $object->EventKey." ".$object->ScanCodeInfo->ScanResult;break;case "pic_weixin"://回复无效//$content = $object->Event." ".$object->EventKey;exit;break;case "pic_photo_or_album"://回复无效//$content = $object->Event." ".$object->EventKey;exit;break;case "pic_sysphoto"://回复无效exit;break;case "location_select"://回复无效//$content = "location";exit;break;default:$content = "";break;}$result = $this->transmitText($object, $content);return $result;}/*** 接收图片消息,通过MediaId回复相同的图片给用户*/private function receiveImage($object){$content = array("MediaId"=>$object->MediaId);$result = $this->transmitImage($object, $content);return $result;}/*** 接收位置消息*/private function receiveLocation($object){$content = "你发送的是位置,纬度为:".$object->Location_X.";经度为:".$object->Location_Y.";缩放级别为:".$object->Scale.";位置为:".$object->Label;$result = $this->transmitText($object, $content);return $result;}/*** 回复文本消息*/private function transmitText($object, $content){$xmlTpl = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime><![CDATA[%s]]></CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>";$result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time(), $content);return $result;}/*** 回复图片消息*/private function transmitImage($object, $imageArray){$itemTpl = "<Image><MediaId><![CDATA[%s]]></MediaId></Image>";$item_str = sprintf($itemTpl, $imageArray['MediaId']);$textTpl = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[image]]></MsgType>$item_str</xml>";$result = sprintf($textTpl, $object->FromUserName, $object->ToUserName,time());return $result;}}

点击“单击”菜单后,直接推送了一个CLICK事件过来。

点击“发送位置”,除开推送location_select事件过来之外,还推送一个loaction消息过来。

点击view“百度”菜单,什么也没推送过来,在微信浏览器打开了百度网页。

点击“系统拍照发图”菜单,直接弹出了相机功能,拍完照后直接发送一个图片消息过来,没有事件消息。

点击“”微信相册发图“菜单后,直接弹出相册,选择2张图片发送和,显示发送了一个pic_weixin的事件,然后分别有发送了2个图片消息,可分别对2个图片消息做回复,对事件消息回复无效。

单击”拍照或相册发图“,会弹出选择框供用户选择,除了推送的事件是pic_photo_or_album外,其他选择之后的消息和以上两个一样。

单击”扫码带提示“,则弹出扫码框扫描获得结果之后,会弹出”获取中...“,推送一个事件给开发者,稍候可能会获得开发者回复的消息,如图是我扫描一个百度URL的二维码的结果,直接把扫码结果回复给用户。

点击”扫码推事件“菜单,扫描到结果后,会推送一个事件给开发者,开发者回复消息用户不会接收到,如果是URL,则直接跳转到该URL,否则显示扫码结果。

4、查询自定义菜单

查询自定义菜单接口是https://api./cgi-bin/menu/get?access_token=ACCESS_TOKEN,代码实现如下

get_menu.php

<?php@header('Content-type: text/plain;charset=UTF-8');require_once('./Utils.php');$url = "https://api./cgi-bin/menu/get?access_token=".Utils::get_access_token();//查询菜单$result = Utils::https_request($url);echo $result;

结果返回如下:

5、删除自定义菜单

删除自定义菜单的接口是:https://api./cgi-bin/menu/delete?access_token=ACCESS_TOKEN

delete_menu.php

<?php@header('Content-type: text/plain;charset=UTF-8');require_once('./Utils.php');$url = "https://api./cgi-bin/menu/delete?access_token=".Utils::get_access_token();//删除菜单$result = Utils::https_request($url);echo $result;

返回结果是如下表示成功:

重新关注微信号后可以看见菜单被删除了

关于菜单推送事件字段的含义可以参见自定义菜单事件。

相关博客

微信公众号开发(一)服务器及接口的配置

微信公众号开发(二)基础接口

微信公众号开发(三)获取access_token

微信公众号开发(四)自定义菜单

微信公众号开发(五)个性化菜单

微信公众号开发(六)素材管理

微信公众号开发(七)发送客服消息

微信公众号开发(八)用户管理

微信公众号开发(九)群发消息接口

微信公众号开发(十)模板消息

微信公众号开发(十一)生成带参数二维码

微信公众号开发(十二)OAuth2.0网页授权

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。