作者:陈惠,叩丁狼教育高级讲师。原创文章,转载请注明出处。

本篇文章,我们来做一个最常见的,也是用户最喜欢使用的功能——自定义菜单。
因为菜单只需要点一下就可以获取需要的信息,无需用户手动输入关键字,用户体验相对来说比较好。

菜单效果:

打开开发文档,选择”自定义菜单”的”菜单创建接口”。

注意:
1、自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。
2、一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。
3、创建自定义菜单后,微信是有一定的菜单刷新策略,不会立马看到效果,尽量尝试先取消关注后再次关注,即可以看到创建后的效果。

菜单的类型非常多,文档中列了10种类型,这里不一一说明。

举两个比较常见的类型:
1、click:点击推事件类型,即点击之后微信服务器会推送一个事件类型的消息到我们的URL上,与之前的关注/取消关注类似。
2、view:跳转URL类型,即点击之后可以跳转到指定的网页地址。
现在我们利用click类型的按钮来实现需求:

用户点击”开班信息”按钮后,公众号马上推送最近开班信息,点击”校区地址”按钮后,马上推送地址信息,不需要用户再手动输入关键字。

实现细节:

1.用户点击click类型按钮后,微信服务器会推送一个事件类型的消息到URL上,也就是意味着需要使用之前的MsgType判断是否为event类型。
2.需要判断是什么事件,我们之前判断的是关注事件subscribe,但现在是click类型,所以Event属性我们需要判断是否为click。
3.我们可能会有很多个click类型的按钮,所以需要根据不同的按钮来回复不同的内容,微信为每个click类型的按钮提供了key属性,不同的按钮设置不同的key值,根据key值即可知道当前需要处理的是哪个按钮。

创建菜单:

那么接下来,我们就需要创建自定义菜单了。

开发文档中,已经提供创建菜单的接口地址了,我们需要把菜单转换为json数据传递过去。

下图是官方提供的菜单具体参数:

先把我们的要创建的自定义菜单对应的json数据准备好:

{"button":[{    "type":"click","name":"开班信息","key":"classinfo"},{    "type":"click","name":"校区地址","key":"address"},{"name":"学科介绍","sub_button":[{    "type":"view","name":"Java课程","url":"http://www.wolfcode.cn/zt/java/index.html"},{    "type":"view","name":"Python课程","url":"http://www.wolfcode.cn/zt/python/index.html"}]}]}

这里我是创建了2个click类型的一级菜单,并且有对应的key值,还创建了1个有子菜单的一级菜单, 里面的2个子菜单都是view类型的,点击后直接链接到课程介绍页面。

access_token介绍

接下来,我们注意看这个接口的地址:https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN

地址最后有一个access_token的参数,对于该参数的介绍,在开发文档的”首页”有这么一句话。

公众平台以access_token为接口调用凭据,来调用接口,所有接口的调用需要先获取access_token,也就意味着它就是一个门票,请求接口时需要带上这个门票,如果没有就无法获取需要的信息,access_token在2小时内有效,过期需要重新获取,但1天内获取次数有限,开发者需自行存储,详见获取接口调用凭据(access_token)文档。

这句话说明了我们在调用接口之前,必须先获取到access_token这么一个凭据。

获取access_token

打开文档 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183

文档告诉我们,access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效,而且也有获取的次数限制,所以我们应该把它缓存起来,2个小时内重复使用,另外, 如果access_token要保存在数据库中,至少要保留512个字符空间。

通过文档介绍可知,我们请求指定的接口地址,并且把我们之前分配到的appid与secret作为参数传递过去,即可以获取到有效的access_token。

代码:

public class WeChatUtil {//URL验证时使用的tokenpublic static final String TOKEN = "wolfcode";//appidpublic static final String APPID = "wx59687be81dd3d388";//secretpublic static final String SECRET = "d4624c36b6795d1d99dcf0547af5443d";//创建菜单接口地址public static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";//获取access_token的接口地址public static final String GET_ACCESSTOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";//缓存的access_tokenprivate static String accessToken;//access_token的失效时间private static long expiresTime;/*** 获取accessToken* @return*/public static String getAccessToken(){//判断accessToken是否已经过期,如果过期需要重新获取if(accessToken==null||expiresTime < new Date().getTime()){//发起请求获取accessTokenString result = HttpUtil.get(GET_ACCESSTOKEN_URL.replace("APPID", APPID).replace("APPSECRET", SECRET));//把json字符串转换为json对象JSONObject json = JSON.parseObject(result);//缓存accessTokenaccessToken = json.getString("access_token");//设置accessToken的失效时间long expires_in = json.getLong("expires_in");//失效时间 = 当前时间 + 有效期(提前一分钟)expiresTime = new Date().getTime()+ (expires_in-60) * 1000;}return accessToken;}
}

代码中的HttpUtil是发起http请求的工具类,网上可以找到很多,这里就不贴出来了。

通过getAccessToken方法我们就可以获取到需要的accessToken凭据了。

接下来我们就可以调用创建自定义菜单的接口了,使用main方法直接调用createMenu方法,把菜单的json数据传入即可。当然,想要更灵活的设置菜单,需要写菜单管理的相关页面使用可视化的方式来编辑菜单。

    /*** 创建自定义菜单* @param menu*/public static void createMenu(String menu){String result = HttpUtil.post(CREATE_MENU_URL.replace("ACCESS_TOKEN", getAccessToken()),menu);System.out.println(result);}

接口响应的结果为:{“errcode”:0,”errmsg”:”ok”},代表菜单创建成功,这时候就可以打开公众号测试了,如果不能及时看到新的菜单,应先取消关注再重新关注公众号。

如果响应的结果是其他,代表创建过程出错了,这时候应该对照错误码,查找错误原因。

上面列出的是比较常见的错误,如果上面找不到,需要在全局返回码中搜索。
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433747234

菜单效果:

菜单已经创建成功,我们最后一步就是做业务处理了。

1.InMsgEntity类添加EventKey属性

@Setter
@Getter
@XmlRootElement(name="xml")
@XmlAccessorType(XmlAccessType.FIELD)
public class InMsgEntity {....省略不相关的属性.../*** 消息类型* text 文本消息* image 图片消息* voice 语音消息* video 视频消息* music 音乐消息* event 事件推送*/protected String MsgType;/*** 事件类型* subscribe(订阅)* unsubscribe(取消订阅)* LOCATION(上报地理位置)* CLICK(点击普通的菜单)* VIEW(点击跳转链接的菜单)*/private String Event;//菜单按钮的key值private String EventKey;
}

2.判断菜单key值

    /*** 微信消息处理*/@RequestMapping(value = "/weChat", method = RequestMethod.POST)@ResponseBodypublic Object handleMessage(@RequestBody InMsgEntity msg) {//创建消息响应对象OutMsgEntity out = new OutMsgEntity();//把原来的发送方设置为接收方out.setToUserName(msg.getFromUserName());//把原来的接收方设置为发送方out.setFromUserName(msg.getToUserName());//获取接收的消息类型String msgType = msg.getMsgType();//设置消息创建时间out.setCreateTime(new Date().getTime());//公众号回复的内容String outContent = null;//根据类型设置不同的消息数据if("text".equals(msgType)){//.....}else if("image".equals(msgType)){//.....}else if("event".equals(msgType)){//判断关注事件if("subscribe".equals(msg.getEvent())){out.setContent("欢迎关注![愉快]");//设置消息的响应类型out.setMsgType("text");}else if("click".equals(msg.getEvent())){//获取菜单的key值String key = msg.getEventKey();if("classinfo".equals(key)){outContent = "上海Java基础班第05期于2018/05/10开班\n" +"广州Java基础班第24期于2018/04/02开班";}else if("address".equals(key)){outContent = "北京校区:北京昌平区沙河镇万家灯火装饰城2楼8077号\n" +"广州校区:广州市天河区棠下涌东路大地工业区D栋六楼\n" +"上海校区:上海市青浦区华新镇华隆路1777号E通世界商务园华新园A座4楼402";}//设置消息的响应类型out.setMsgType("text");out.setContent(outContent);}}return out;}

菜单效果演示:

微信公众号开发教程(四)自定义菜单相关推荐

  1. 微信公众号开发教程[011]-自定义菜单以及个性化菜单

    自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单.类型分别有click,view,scancode_push,scancode_waitmsg,pic_sysphoto,pic_pho ...

  2. java 微信自定义菜单开发_微信公众号开发之设置自定义菜单实例代码【java版】...

    本实例是为了实现在管理后台实现微信菜单的添加删除管理. 1.首先我们需要新建一个数据库表用于存放menu菜单项 可包含的字段有id.父类id.name.排序.是否显示.类型(view.click).链 ...

  3. 微信公众号开发教程(一) 验证接入

    作者:陈惠,叩丁狼教育高级讲师.原创文章,转载请注明出处. 微信公众号开发教程(一)验证接入 本篇文章主要介绍了微信公众号开发接入详细流程,希望对刚接触公众号开发的同学有所帮助,有兴趣的同学可多多关注 ...

  4. 视频教程-基于python的微信公众号开发教程-微信开发

    基于python的微信公众号开发教程 微信企业号星级会员.10多年软件从业经历,国家级软件项目负责人,主要从事软件研发.软件企业员工技能培训.已经取得计算机技术与软件资格考试(软考)--"信 ...

  5. 【微信公众号开发】四、公众号按钮设置及自己的微信按钮编辑器

    文章详情:[微信公众号开发]四.公众号按钮设置及自己的微信按钮编辑器 链接:https://www.microanswer.cn/blog/14

  6. 微信公众号开发教程[019]-新版客服

    新版客服是针对之前文章<<微信公众号开发教程[007]-消息管理-客服消息>>里面提到的客服功能而言的.在其基础上做了很多提升. 首先如果公众号曾经使用过旧版多客服功能,则要在 ...

  7. 微信公众号开发教程[012]-素材管理

    一.关于图文消息,我的理解         我理解中,普通<img><iframe>等标签的src属性,可以跨域,哪里的图片都行.但是公众号的聊天会话界面,放的图片,语音,图文 ...

  8. 微信公众号开发java流程_微信公众号开发教程java 编程语言的特点及选择

    微信公众号开发教程java 编程语言的特点及选择 微信公众号为用户提供了相关的工具,来对微信公众号进行一个简单的开发.但是如果想实现一些复杂的功能,其实还是要借助于一些编程语言的使用.所以要了解,在微 ...

  9. .Net6+Furion+Sqlsugar+SenparcSdk开发微信公众号系列之八:自定义菜单

    一.创建接口 1.1.注意事项 自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单. 一级菜单最多4个汉字,二级菜单最多8个汉字,多出来的部分将会以"..."代替. ...

最新文章

  1. 吴恩达家免费 NLP 课程重磅上线!110 个小视频教你做出聊天机器人,粉丝:我要让娃跟吴恩达姓!...
  2. 修改 Oracle 数据库 sequence(序列) 的 increment (步长)
  3. 用于在公网环境下测试的Telnet/SSH服务器
  4. 数据库压测 oracle,sysbench压测Oracle
  5. leetcode132. 分割回文串 II
  6. python 轮廓矩阵_python – 在3D numpy矩阵中绘制给定值的曲面轮廓
  7. Node学习笔记:建立TCP服务器和客户端之间的通信
  8. java证书不通过,java-证书不会偶尔发送
  9. 在python中设置密码登录_在python中生成密码
  10. 一位Java程序员写给女友的情书
  11. 如何利用路由器防止DoS拒绝服务疯狂***
  12. [整理]Linux压缩与解压缩命令整理。
  13. HTML5技术的调研以及贴吧应用总结
  14. Tableau教程——一
  15. ubuntu18.04安装nvidia显卡驱动的正确方法
  16. H5页面打开微信小程序
  17. 学习————运算符!
  18. 三个人的友谊显的有些拥挤了...
  19. 涨价、盈利、IPO?共享充电宝没你想象得好过!
  20. Three.js实现的网站页面金字塔模型显示

热门文章

  1. [Web安全]信息收集
  2. udp通信2--多发多收
  3. 黑苹果0x0501_黑苹果原版安装从零开始---3-clover配置篇
  4. 黑马程序员——java语言基础部分——网络编程
  5. 如何重装Mac OS系统
  6. 他儿子就这样娶到了比尔·盖茨的女儿
  7. Layui导航栏下拉菜单不显示问题
  8. 树上分治算法 + 路径剖分
  9. 6 zzuliPTA家庭土地管理
  10. mysql中IFNULL,NULLIF,ISNULL函数的对比