Node开发微信公众号(3)——微信菜单
开始之前照例说一下实现思路。
要实现微信菜单,我们需要向微信服务器发送一个post请求,并把我们的菜单配置发送给微信服务器。
![](https://img.haomeiwen.com/i2189687/28824635e6d0fdb9.png)
从上图的请求地址我们可以看到,我们可以分为两步来实现,第一步获得access_token这个参数,第二步发送post请求创建菜单。
1.获取access_token
access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。所以说这个access_token是很重要的,而且这个票据只能保存2个小时,2个小时后就失效了,需要重新获取。
我们先将请求地址配置到config上,因为微信上的请求接口他们的前缀都是一样的,所以我们可以把前缀提取出来。
{
"appID": "wxd27649727105b6d2",
"appsecret": "a3f2eb9f5819b0bf4b2a92a81f99baf4",
"token": "wechat",
"prefix": "https://api.weixin.qq.com/",
"diyApi": {
"getAccessToken": "%scgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
"createMenu": "%scgi-bin/menu/create?access_token=%s"
}
}
代码中的%s是一个占位符,用于后面字符替换。然后我们给WeChat加个get请求方法和post请求方法,因为后面会经常用到。
// 获取全局票据
WeChat.prototype.getAccessToken =function() {
var that = this;
return new Promise(function(resolve,reject){
var currentTime = new Date().getTime();
//格式化请求地址,把刚才的%s按顺序替换
var url = util.format(that.diyApi.getAccessToken, that.prefix, that.appID, that.appScrect);
//判断本地存储的 access_token 是否有效
if(accessTokenJson.access_token === "" || accessTokenJson.expires_time < currentTime){
that.requestGet(url).then(function(data){
var result = JSON.parse(data);
if(data.indexOf("errcode") < 0){
accessTokenJson.access_token = result.access_token;
accessTokenJson.expires_time = new Date().getTime() + (parseInt(result.expires_in) - 200) * 1000;
//更新本地存储的
fs.writeFile('./wechat/access_token.json',JSON.stringify(accessTokenJson));
resolve(accessTokenJson.access_token);
}else{
resolve(result);
}
});
}else{
//将本地存储的 access_token 返回
resolve(accessTokenJson.access_token);
}
});
}
// 封装一个get请求方法
WeChat.prototype.requestGet = function(url) {
return new Promise (function(resolve, reject) {
request(url, (error, response, body)=> {
resolve(body);
})
})
}
node原生的请求需要些一些请求头之类的东西,所以这里用了一个新的模块,叫做request。用法也很比较简单,直接上npm上看下一就行。这里的票据是存在本地的access_token.json文件中,当然也可以存数据库,这个看个人需求。
还有一个需要说明的是ES6的Promise用法,简单的说明一下:js的程序执行是单线程的,所以遇到O/I操作会发生阻塞,所以node使用了大量的回调函数。但是回调函数不是特别直观,所以es6提供了Promise用法,也是一种异步调用。
想要深入了解,可以看一下阮一峰的ECMAScript 6 入门,这是一本免费的电子书http://es6.ruanyifeng.com/#docs/intro。
2.创建菜单
微信开发文档提供了几种类型,我们照着写就行。
![](https://img.haomeiwen.com/i2189687/d03ba8916b505eb3.png)
{
"button":[
{
"type":"view",
"name":"个人博客",
"url":"http://xiaoxiagroup.top"
},
{
"type":"click",
"name":"听歌",
"key":"music"
},
{
"name":"小工具",
"sub_button":[{
"type": "scancode_waitmsg",
"name": "扫一扫",
"key": "scancode"
},{
"type": "pic_sysphoto",
"name": "系统拍照发图",
"key": "take_photo"
},{
"type": "location_select",
"name": "发送位置",
"key": "send_location"
}]
}
]
}
封装一个post请求方法。
// 封装一个post请求方法
WeChat.prototype.requestPost = function(url, data) {
return new Promise (function(resolve, reject) {
request.post({url: url, form:data}, function(err,httpResponse,body){
resolve(body);
})
})
}
![](https://img.haomeiwen.com/i2189687/7307267fdbf9851b.png)
至此,微信菜单也完成了。
源码地址:https://github.com/yeshaojun/wechatBase
如果喜欢就给我点个小星星吧!