UNPKG

weixin-device

Version:
374 lines (352 loc) 12.2 kB
var request = require('request'); var async = require('async'); var slice = [].slice; var wxDevice = function(options){ if(typeof options === "undefined"){ throw new Error('undefined is not a valid options.'); } if(typeof options.access_token === "undefined") { access_token = wxDevice.getAccessToken; } if(!wxDevice.access_token){ if(options.access_token && typeof options.access_token === "string"){ wxDevice.access_token = options.access_token; }else if(typeof options.access_token === "function"){ wxDevice.status = 'running'; generateGetAccessTokenFn(options.access_token); }else if(options.app_id && options.app_secret){ wxDevice.status = 'running'; wxDevice.app_id = options.app_id; wxDevice.app_secret = options.app_secret; generateGetAccessTokenFn(); }else { throw new Error('options is invalid'); } if(wxDevice.atFn) { var getAT = function(){ if(!wxDevice.access_token && wxDevice.status === 'running'){ wxDevice.atFn(); setTimeout(getAT, 1000); } } getAT(); } } return wxDevice; }; wxDevice.status = 'complete'; function generateGetAccessTokenFn(fn){ wxDevice.atFn = function(cb){ cb = cb || function(){}; if(fn){ if(fn.length == 0 ){ wxDevice.access_token = fn(); wxDevice.status = 'complete'; cb(null, wxDevice.access_token); }else { wxDevice.access_token = fn(function(err, _at){ wxDevice.status = 'complete'; wxDevice.access_token = _at; cb(null, _at); }); } }else { wxDevice.getAccessToken(wxDevice.app_id, wxDevice.app_secret, function(err, ret){ if(ret && ret.access_token) wxDevice.access_token = ret.access_token; wxDevice.status = 'complete'; cb(err, ret && ret.access_token); }); } }; } /** * 获取 access_token */ wxDevice.getAccessToken = function(app_id, app_secret, cb){ var args = slice.call(arguments); cb = cb || function(){}; request.get('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='+app_id+'&secret='+app_secret, function(err, res, body){ replyCallback(err, body, cb, wxDevice.getDeviceId, args); }); }; /** * 发送消息给设备 */ wxDevice.transmsg = function(options, cb){ var args = slice.call(arguments); var data = options.data || {}; var access_token = options.access_token || this.access_token; cb = cb || function(){}; if(!access_token) return cb({msg: 'need access_token'}); if(!data.device_type) return cb({msg: 'need device_type'}); if(!data.device_id) return cb({msg: 'need device_id'}); if(!data.open_id) return cb({msg: 'need open_id'}); if(!data.content) return cb({msg: 'need content'}); data.content = (new Buffer(data.content)).toString('base64'); request.post({ url: "https://api.weixin.qq.com/device/transmsg?access_token=" + access_token, json: data }, function(err, res, body){ replyCallback(err, body, cb, wxDevice.transmsg, args); }); }; /** * 获取设备二维码 */ wxDevice.createQrcode = function(options, cb){ var args = slice.call(arguments); var data = options.data || []; var access_token = options.access_token || this.access_token; cb = cb || function(){}; if(!access_token) return cb({msg: 'need access_token'}); if(!data || data.length == 0) return cb({msg:"need device_id_list"}); request.post({ url: "https://api.weixin.qq.com/device/create_qrcode?access_token=" + access_token, json: { device_num: data.length, device_id_list: data } }, function(err, res, body){ replyCallback(err, body, cb, wxDevice.createQrcode, args); }); }; /** * 设备授权 */ wxDevice.authorizeDevice = function(options, cb){ var args = slice.call(arguments); var data = options.data || {}; var access_token = options.access_token || this.access_token; cb = cb || function(){}; if(!access_token) return cb({msg: 'need access_token'}); parseDeviceList(data, function(err, json){ if(err) return cb(err); request.post({ url: "https://api.weixin.qq.com/device/authorize_device?access_token=" + access_token, json: json }, function(err, res, body){ replyCallback(err, body, cb, wxDevice.authorizeDevice, args); }); }); }; function parseDeviceList(data, cb){ if(!data.device_list || data.device_list.length == 0) return cb({msg: 'need device_list'}); var list = []; var ids = []; for(var i=0; i<data.device_list.length; i++){ var device = data.device_list[i]; if(device.id) ids.push(device.id); list.push({ id: device.id, mac: device.mac || '', connect_protocol: device.connect_protocol || '3', auth_key: device.auth_key, close_strategy: device.close_strategy || '1', conn_strategy: device.conn_strategy || '1', crypt_method: device.crypt_method || '1', auth_ver: device.auth_ver || '1', manu_mac_pos: device.manu_mac_pos || '-1', ser_mac_pos: device.ser_mac_pos || '-1' }); } if(ids.length > 0 && ids.length != list.length) return cb('device_id either all or not'); if(data.op_type == "1") { data.device_list = list; data.device_num = list.length; cb(null, data); }else { async.map(list, function(device, callback){ if(device.id){ return callback(null, device); }else { wxDevice.getDeviceId(wxDevice.access_token, function(err, obj){ if(err) return callback(err); device.id = obj.deviceid; device.qrticket = obj.qrticket; return callback(null, device); }); } }, function(err, ret){ if(err) return cb(err); data.device_list = ret; data.device_num = ret.length; data.op_type = '0'; if(ids.length == 0) data.op_type = '1'; return cb(null, data); }); } } /** * 设备状态 */ wxDevice.getDeviceStatus = function(options, cb){ var args = slice.call(arguments); var data = options.data || {}; var access_token = options.access_token || this.access_token; cb = cb || function(){}; if(!access_token) return cb({msg: 'need access_token'}); if(!data.device_id) return cb({msg: 'need device_id'}); request.get('https://api.weixin.qq.com/device/get_stat?access_token=' + access_token + '&device_id=' + data.device_id, function(err, res, body){ replyCallback(err, body, cb, wxDevice.getDeviceStatus, args); }); }; /** * 验证二维码 */ wxDevice.verifyQrcode = function(options, cb){ var args = slice.call(arguments); var data = options.data || {}; var access_token = options.access_token || this.access_token; cb = cb || function(){}; if(!access_token) return cb({msg: 'need access_token'}); if(!data.ticket) return cb({msg: 'need a ticket'}); request.post({ url: "https://api.weixin.qq.com/device/verify_qrcode?access_token=" + access_token, json: data }, function(err, res, body){ replyCallback(err, body, cb, wxDevice.verifyQrcode, args); }); }; /** * 获取设备绑定的openID */ wxDevice.getBindOpenId = function(options, cb){ var args = slice.call(arguments); var data = options.data || {}; var access_token = options.access_token || this.access_token; cb = cb || function(){}; if(!access_token) return cb({msg: 'need access_token'}); if(!data.device_type) return cb({msg: 'need a device_type'}); if(!data.device_id) return cb({msg: 'need a device_id'}); request.get('https://api.weixin.qq.com/device/get_openid?access_token='+access_token+'&device_type='+data.device_type+'&device_id='+data.device_id, function(err, res, body){ replyCallback(err, body, cb, wxDevice.getBindOpenId, args); }); }; /** * 获取用户绑定的设备ID */ wxDevice.getBindDeviceId = function(options, cb){ var args = slice.call(arguments); var data = options.data || {}; var access_token = options.access_token || this.access_token; cb = cb || function(){}; if(!access_token) return cb({msg: 'need access_token'}); if(!data.openid) return cb({msg: 'need a openid'}); request.get('https://api.weixin.qq.com/device/get_bind_device?access_token='+access_token+'&openid='+data.openid, function(err, res, body){ replyCallback(err, body, cb, wxDevice.getBindOpenId, args); }); }; /** * 绑定设备,需要微信 H5 页面生成的 ticket 凭证 */ wxDevice.bind = function(options, cb){ var args = slice.call(arguments); var data = options.data || {}; var access_token = options.access_token || this.access_token; cb = cb || function(){}; if(!access_token) return cb({msg: 'need access_token'}); if(!data.ticket) return cb({msg: 'need a ticket'}); if(!data.device_id) return cb({msg: 'need a device_id'}); if(!data.openid) return cb({msg: 'need a openid'}); request.post({ url: 'https://api.weixin.qq.com/device/bind?access_token=' + access_token, json: data }, function(err, res, body){ replyCallback(err, body, cb, wxDevice.bind, args); }) }; /** * 解绑设备,需要微信 H5 页面生成的 ticket 凭证 */ wxDevice.unbind = function(options, cb){ var args = slice.call(arguments); var data = options.data || {}; var access_token = options.access_token || this.access_token; cb = cb || function(){}; if(!access_token) return cb({msg: 'need access_token'}); if(!data.ticket) return cb({msg: 'need a ticket'}); if(!data.device_id) return cb({msg: 'need a device_id'}); if(!data.openid) return cb({msg: 'need a openid'}); request.post({ url: 'https://api.weixin.qq.com/device/unbind?access_token=' + access_token, json: data }, function(err, res, body){ replyCallback(err, body, cb, wxDevice.unbind, args); }); }; /** * 强制绑定用户和设备 */ wxDevice.compelBind = function(options, cb){ var args = slice.call(arguments); var data = options.data || {}; var access_token = options.access_token || this.access_token; cb = cb || function(){}; if(!access_token) return cb({msg: 'need access_token'}); if(!data.device_id) return cb({msg: 'need a device_id'}); if(!data.openid) return cb({msg: 'need a openid'}); request.post({ url: 'https://api.weixin.qq.com/device/compel_bind?access_token=' + access_token, json: data, }, function(err, res, body){ replyCallback(err, body, cb, wxDevice.compelBind, args); }); }; /** * 强制解绑用户和设备 */ wxDevice.compelUnbind = function(options, cb){ var args = slice.call(arguments); var data = options.data || {}; var access_token = options.access_token || this.access_token; cb = cb || function(){}; if(!access_token) return cb({msg: 'need access_token'}); if(!data.device_id) return cb({msg: 'need a device_id'}); if(!data.openid) return cb({msg: 'need a openid'}); request.post({ url: 'https://api.weixin.qq.com/device/compel_unbind?access_token=' + access_token, json: data, }, function(err, res, body){ replyCallback(err, body, cb, wxDevice.compelBind, args); }); }; /** * 生成 device_id */ wxDevice.getDeviceId = function(access_token, cb){ var args = slice.call(arguments); if(typeof access_token == 'function'){ cb = access_token; access_token = null; } if(!access_token) access_token = this.access_token; cb = cb || function(){}; if(!access_token) return cb({msg: 'need access_token'}); request.get("https://api.weixin.qq.com/device/getqrcode?access_token=" + access_token, function(err, res, body){ replyCallback(err, body, cb, wxDevice.getDeviceId, args); }); } function replyCallback(){ var args = slice.call(arguments); var body = args[1]; if(body && typeof body === "string"){ try { body = JSON.parse(body); }catch(e){ console.log(e); } } var cb = args[2]; var fn = args[3]; if(args[0]) return cb(args[0]); if(body && ((typeof body.errcode != 'undefined' && body.errcode != '0') || (body.base_resp && body.base_resp.errcode != '0'))){ if(body.errcode == 42001 && wxDevice.atFn) { return wxDevice.atFn(function(){ fn.apply(wxDevice, args[4]); }); } return cb(body); } cb(null, body); } module.exports = wxDevice;