上一篇文章:nodejs微信公众号开发——6.自定义菜单,实现了简单自定义菜单的功能,里面每一个菜单的类型都是
click
的,固然它支持更多类型,如view
,scancode_waitmsg
,scancode_push
,pic_sysphoto
,location_select
等,根据实际需求配置。本节主要介绍用户管理的内容 (项目github地:https://github.com/Panfen/wem... )node
公众号里面的用户可能来自四面八方,拥有这不一样的职业、兴趣等类别,能够经过对用户有效的管理,实现精准服务、精准营销。用户管理的内容包含:git
使用这个接口,对公众平台的分组进行查询、建立、修改、删除等操做,也可使用接口在须要时移动用户到某个分组。接口提供的功能包括:github
var api = { ... groups:{ create:prefix+'groups/create?', //access_token=ACCESS_TOKEN 建立分组,POST请求 get:prefix+'groups/get?', //access_token=ACCESS_TOKE 查询全部分组,GET请求 getId:prefix+'groups/getid?', //access_token=ACCESS_TOKEN 查询用户所在分组,POST请求 update:prefix+'groups/update?', //access_token=ACCESS_TOKEN 修改分组名,POST请求 membersUpdate:prefix+'groups/members/update?', //access_token=ACCESS_TOKEN 移动用户分组,POST请求 membersBatchupdate:prefix+'groups/members/batchupdate?', //access_token=ACCESS_TOKEN 批量移动用户分组,POST请求 delete:prefix+'groups/delete?' //access_token=ACCESS_TOKEN 删除分组,POST请求 } }
写到如今,应该对这种api的代码实现很是熟悉了,都是在Wechat
的原型上增长方法:json
Wechat.prototype.createGroup = function(name){ var that = this; return new Promise(function(resolve,reject){ that.fetchAccessToken().then(function(data){ var url = api.groups.create + 'access_token=' + data.access_token; var opts = { group:{ name:name } }; request({method:'POST',url:url,body:opts,json:true}).then(function(response){ var _data = response.body; if(_data.group){ resolve(_data.group); }else{ throw new Error('create group failed: ' + _data.errmsg); } }).catch(function(err){ reject(err); }); }); }); }
一样是简单的增长原型方法:segmentfault
Wechat.prototype.getGroups = function(name){ var that = this; return new Promise(function(resolve,reject){ that.fetchAccessToken().then(function(data){ var url = api.groups.get + 'access_token=' + data.access_token; request({url:url,json:true}).then(function(response){ ... }); }); }); }
注:
"
是"
的十进制表示,由于是测试,我就不改了api
接口提供功能是,发起一次请求根据一个ID删除一个分组,即一次删除一个分组。有些时候咱们但愿一次删除多个分组,咱们能够本身封装支持批量删除的操做:数组
Wechat.prototype.deleteGroups = function(idArr){ var that = this; that.fetchAccessToken().then(function(data){ var queue = []; for(var i = 0; i < idArr.length; i++){ queue.push(_deleteGroup(data.access_token,idArr[i])); } Promise.all(queue).then(function(data){ console.log('data:' + data); }).catch(function(err){ console.log(err) }) }); }
这里的参数idArr
是id
的数组,里面有一个或多个id
值,经过Promise.all()的方法,来处理Promise的集合,_deleteGroup
函数实现了为每个id
构建一个Promise:promise
var _deleteGroup = function(access_token,id){ var url = api.groups.delete + 'access_token=' + access_token; var opts = { group:{ id:id } }; return new Promise(function(resolve,reject){ request({method:'POST',url:url,body:opts,json:true}).then(function(response){ ... }); }); }
注:
这里已经实现了批量删除分组的功能,可是后台报了一个错:TypeError: You may only yield a function, promise, generator, array, or object, but the following object was passed: "undefined"
因为不影响程序运行,主要暂时不知道怎么解决,先mark着。明白缘由的大神请不吝赐教,不胜感激!微信
鉴于移动用户分组和批量移动用户分组功能的类似性,将其实如今一个函数moveUsersToGroup
里面:框架
Wechat.prototype.moveUsersToGroup = function(openid,to_groupid){ var that = this; return new Promise(function(resolve,reject){ that.fetchAccessToken().then(function(data){ var url = ''; var form = {} if(openid && !Array.isArray(openid)) { //单个用户分组 url = api.groups.membersUpdate + 'access_token=' + data.access_token; form = { openid:openid, to_groupid:to_groupid }; }else if(Array.isArray(openid)){ //批量用户分组 url = api.groups.membersBatchupdate + 'access_token=' + data.access_token; form = { openid_list:openid, to_groupid:to_groupid }; } request({method:'POST',url:url,body:form,json:true}).then(function(response){ ... )} }); }); }
测试代码:
将当前用户移动到分组号为114
的分组,
else if(content === '6'){ var msg = yield wechatApi.moveUsersToGroup(message.FromUserName,114); var groups = yield wechatApi.getGroups(); console.log('获取到以下分组:\n'+ JSON.stringify(groups)); }
能够看到,该分组的count
值变成1
。
毫无技术难度的代码:
Wechat.prototype.updateUserRemark = function(openid,remark){ var that = this; return new Promise(function(resolve,reject){ that.fetchAccessToken().then(function(data){ var url = api.user.updateUserRemark + 'access_token=' + data.access_token; var form = { openid:openid, remark:remark }; request({method:'POST',url:url,body:form,json:true}).then(function(response){ ... }); }); }); }
在关注者与公众号产生消息交互后,公众号可得到关注者的OpenID(加密后的微信号,每一个用户对每一个公众号的OpenID是惟一的。对于不一样公众号,同一用户的openid不一样)。公众号可经过本接口来根据OpenID获取用户基本信息,包括昵称
、头像
、性别
、所在城市
、语言
和关注时间
。
获取用户信息的接口分为获取单个用户信息和批量获取用户信息,这个接口请求的地址,请求方式都不一样。咱们将二者实如今一个函数里面:
//获取单个或一批用户信息 Wechat.prototype.fetchUserInfo = function(open_id,lang){ var that = this; var lang = lang || 'zh_CN'; var url = ''; var opts = {} return new Promise(function(resolve,reject){ that.fetchAccessToken().then(function(data){ if(open_id && !Array.isArray(open_id)){ //单个获取 url = api.user.getUserInfo + 'access_token=' + data.access_token +'&openid='+ open_id +'&lang=' +lang; opts = { url:url, json:true } }else if(open_id && Array.isArray(open_id)){ url = api.user.batchGetUserInfo + 'access_token=' + data.access_token; var user_list = []; for(var i=0;i<open_id.length;i++){ user_list.push({ openid:open_id[i], lang:lang }); } opts = { method:'POST', url:url, body:{ user_list:user_list }, json:true } } request(opts).then(function(response){ ... }); }); }); }
测试获取单个用户信息和批量获取信息(模拟):
else if(content === '8'){ var data1 = yield wechatApi.fetchUserInfo(message.FromUserName); console.log(JSON.stringify(data1)); var data2 = yield wechatApi.fetchUserInfo([message.FromUserName]); console.log(JSON.stringify(data2)) }
公众号可经过本接口来获取账号的关注者列表,关注者列表由一串OpenID(加密后的微信号,每一个用户对每一个公众号的OpenID是惟一的)组成。一次拉取调用最多拉取10000个关注者的OpenID,能够经过屡次拉取的方式来知足需求。
Wechat.prototype.getUserOpenIds = function(next_openid){ var that = this; return new Promise(function(resolve,reject){ that.fetchAccessToken().then(function(data){ var url = api.user.getUserOpenIds + 'access_token=' + data.access_token; if(next_openid) url += '&next_openid=' + next_openid; request({url:url,json:true}).then(function(response){ ... }); }); }); }
测试一下吧:
var data1 = yield wechatApi.getUserOpenIds(); console.log(JSON.stringify(data1)); var data2 = yield wechatApi.getUserOpenIds(message.FromUserName); console.log(JSON.stringify(data2));
看到这里的结果是否是有点奇怪?按照文档说明,当next_openid
不填写的时候,是从头开始拉取用户数据;填写next_openid
时,时第一个拉取的OPENID。从结果看出,填写next_openid
时,数据是从next_openid
开始算起的。
其余函数不在这里继续介绍(都是重复性的代码T_T),能够在github上看到完成代码。
列举了参考的几份颇有价值的资料,主要是加深都promise
和koa框架
的理解。