上一篇讲到如何成为开发者,这一篇继续,那么设计到自定义菜单和对微信事件的监听,例如说监听用户发来的消息,给用户发推送等等,监听用户的关注和取消关注的事件。上一篇介绍到,cnode大神们提供的node-wechat,node-wechat-api,方便了广大开发者,不过用的时候还是研究了一下,才看懂了,估计太差了(冷汗),也记录一些使用心得给大家,首先安装他们吧。。
npm -install wechat --save nmp -install wechat-api --save
微信一个梗,如果使用操作栏里的自定义菜单则微信不会再转发响应的事件到我们设置的服务器url中,一句话,操作菜单里的自定义菜单是给普通微信公众号人员使用的,那作为开发人员只有一条路,使用代码进行,这里用到wechat-api。
var WechatAPI = require('wechat-api'); //公众号初始化api var wxOpenApi = new WechatAPI(constant.WX_OPEN_APPID, constant.WX_OPEN_APPSECRET, function (callback) { // 传入一个获取全局token的方法 //代码就不贴了,这里用到的是从数据库读取token的方式,token是事先请求好放在数据库的 });
我们看下源码中,WechatAPI的构造函数,在api_common.js中是这样的:
var API = function (appid, appsecret, getToken, saveToken) { this.appid = appid; this.appsecret = appsecret; this.getToken = getToken || function (callback) { callback(null, this.store); }; this.saveToken = saveToken || function (token, callback) { this.store = token; if (process.env.NODE_ENV === 'production') { console.warn('Don\'t save token in memory, when cluster or multi-computer!'); } callback(null); }; //这里设置了一些微信请求的前缀 this.prefix = 'https://api.weixin.qq.com/cgi-bin/'; this.mpPrefix = 'https://mp.weixin.qq.com/cgi-bin/'; this.fileServerPrefix = 'http://file.api.weixin.qq.com/cgi-bin/'; this.payPrefix = 'https://api.weixin.qq.com/pay/'; this.merchantPrefix = 'https://api.weixin.qq.com/merchant/'; this.customservicePrefix ='https://api.weixin.qq.com/customservice/'; this.defaults = {}; // set default js ticket handle this.registerTicketHandle(); };
传入了一个获取token和设置token的方法,如果不传,那么将每次请求信的token来完成操作,虽然这样做也可以,不过不建议。
下面看下设置menu的方法,createMenu。
exports.createMenu = function (menu, callback) { this.preRequest(this._createMenu, arguments); }; /*! * 创建自定义菜单的未封装版本 */ exports._createMenu = function (menu, callback) { var url = this.prefix + 'menu/create?access_token=' + this.token.accessToken; this.request(url, postJSON(menu), wrapper(callback)); };
preRequest方法呢在api_common.js中主要作用是验证token是否过期,过期的话从新获取token后进行请求。postJson是将http请求的头部设置dataType为json,使用在utils.js
最关键的是wrapper,先看源码
exports.wrapper = function (callback) { return function (err, data, res) { callback = callback || function () {}; if (err) { err.name = 'WeChatAPI' + err.name; return callback(err, data, res); } if (data && data.errcode) { err = new Error(data.errmsg); err.name = 'WeChatAPIError'; err.code = data.errcode; return callback(err, data, res); } callback(null, data, res); }; };
这里的callback形式是callback(err, data, res),不过例子上没有将,如果不看源码的话写的时候容易写错。
使用如下:
/* * ***** 菜单操作 * */ function createMenu(req, res) { var menu = { "button": [ { "type": "view", "name": "我的课表", "url":"xxxxxx" },{ "name": "关于", "sub_button": [ { "type": "view", "name": "下载应用", "url": "", "sub_button": [ ] }, { "type": "view", "name": "商务合作", "url": "x", "sub_button": [ ] } ] }] } //这里看callback的格式 wxOpenApi.createMenu(menu, function (error, data, result) { if (!error) { res.success("success"); } else { res.error(error); } }); }
菜单设置完毕,去公众号看下,还可以??。