上一篇文章: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框架
的理解。