UNPKG

koa2-wechat2

Version:

koa2 middleware for wechat

951 lines (815 loc) 25.5 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Wechat; var _requestPromise = require('request-promise'); var _requestPromise2 = _interopRequireDefault(_requestPromise); var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs); var _util = require('./util'); var util = _interopRequireWildcard(_util); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var prefix = 'https://api.weixin.qq.com/cgi-bin/'; var mpPrefix = 'https://mp.weixin.qq.com/cgi-bin/'; var api = { accessToken: prefix + 'token?grant_type=client_credential', temporary: { upload: prefix + 'media/upload?', fetch: prefix + 'media/get?' }, permanent: { fetch: prefix + 'material/get_material?', del: prefix + 'material/del_material?', upload: prefix + 'material/add_material?', uploadnews: prefix + 'material/add_news?', update_news: prefix + 'material/update_news?', uploadimg: prefix + 'media/uploadimg?', count: prefix + 'material/get_materialcount?', batch: prefix + 'material/batchget_material?' }, tag: { create: prefix + 'tags/create?', fetch: prefix + 'tags/get?', update: prefix + 'tags/update?', delete: prefix + 'tags/delete?', user: prefix + 'user/tag/get?', batch: prefix + 'tags/members/batchtagging?', batchUn: prefix + 'tags/members/batchuntagging?', getIdList: prefix + 'tags/getidlist?' }, user: { remark: prefix + 'user/info/updateremark?', fetch: prefix + 'user/info?', batchFetch: prefix + 'user/info/batchget?', list: prefix + 'user/get?' }, mass: { sendAll: prefix + 'message/mass/sendall?', openIds: prefix + 'message/mass/send?', delete: prefix + 'message/mass/delete?', preview: prefix + 'message/mass/preview?', check: prefix + 'message/mass/get?' }, menu: { create: prefix + 'menu/create?', get: prefix + 'menu/get?', delete: prefix + 'menu/delete?', current: prefix + 'get_current_selfmenu_info?' }, qrcode: { create: prefix + 'qrcode/create?', show: mpPrefix + 'showqrcode?' }, shortUrl: { create: prefix + 'shorturl?' }, ticket: { get: prefix + 'ticket/getticket?' } /** * Wechat logic, api function return promise * @param {[object]} opts [config] */ };function Wechat(opts) { this.appID = opts.appID; this.appSecret = opts.appSecret; this.getAccessToken = opts.getAccessToken; this.saveAccessToken = opts.saveAccessToken; this.getTicket = opts.getTicket; this.saveTicket = opts.saveTicket; this.fetchAccessToken(); } Wechat.prototype.fetchAccessToken = function () { var that = this; if (this.access_token && this.expires_in) { if (this.isValidAccessToken(this)) { return Promise.resolve(this); } } return this.getAccessToken().then(function (data) { try { data = JSON.parse(data); } catch (e) { return that.updateAccessToken(); } if (that.isValidAccessToken(data)) { return Promise.resolve(data); } else { return that.updateAccessToken(); } }).then(function (data) { that.access_token = data.access_token; that.expires_in = data.expires_in; that.saveAccessToken(data); return Promise.resolve(data); }); }; Wechat.prototype.isValidAccessToken = function (data) { if (!data || !data.access_token || !data.expires_in) { return false; } // let access_token = data.access_token var expires_in = data.expires_in; var now = new Date().getTime(); if (now < expires_in) { return true; } else { return false; } }; Wechat.prototype.updateAccessToken = function () { var appID = this.appID; var appSecret = this.appSecret; var url = api.accessToken + '&appid=' + appID + '&secret=' + appSecret; return new Promise(function (resolve, reject) { (0, _requestPromise2.default)({ url: url, json: true }).then(function (res) { var data = res; var now = new Date().getTime(); var expires_in = now + (data.expires_in - 20) * 1000; data.expires_in = expires_in; resolve(data); }).catch(function (err) { reject(err); }); }); }; //js_api_ticket Wechat.prototype.fetchTicket = function (access_token) { var that = this; return this.getTicket().then(function (data) { try { data = JSON.parse(data); } catch (e) { return that.updateTicket(access_token); } if (that.isValidTicket(data)) { return Promise.resolve(data); } else { return that.updateTicket(access_token); } }).then(function (data) { that.saveTicket(data); return Promise.resolve(data); }); }; Wechat.prototype.isValidTicket = function (data) { if (!data || !data.ticket || !data.expires_in) { return false; } var ticket = data.ticket; var expires_in = data.expires_in; var now = new Date().getTime(); if (ticket && now < expires_in) { return true; } else { return false; } }; Wechat.prototype.updateTicket = function (access_token) { var url = api.ticket.get + ('access_token=' + access_token + '&type=jsapi'); return new Promise(function (resolve, reject) { (0, _requestPromise2.default)({ url: url, json: true }).then(function (res) { var data = res; var now = new Date().getTime(); var expires_in = now + (data.expires_in - 20) * 1000; data.expires_in = expires_in; resolve(data); }).catch(function (err) { reject(err); }); }); }; Wechat.prototype.reply = function () { var content = this.body; var message = this.weixin; var xml = util.tpl(content, message); this.status = 200; this.type = 'application/xml'; this.body = xml; }; Wechat.prototype.uploadMaterial = function (type, material, permanent) { var that = this; var form = {}; var uploadUrl = api.temporary.upload; if (permanent) { uploadUrl = api.permanent.upload; Object.assign(form, permanent); } if (type === 'pic') { uploadUrl = api.permanent.uploadimg; } if (type === 'news') { uploadUrl = api.permanent.uploadnews; form = material; } else { form.media = _fs2.default.createReadStream(material); } return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = uploadUrl + ('access_token=' + data.access_token); if (!permanent) { url += '&type=' + type; } else { form.access_token = data.access_token; } var options = { url: url, method: 'POST', json: true }; if (type === 'news') { options.body = form; } else { options.formData = form; } (0, _requestPromise2.default)(options).then(function (response) { if (response.errcode) { // throw new Error('upload material fails') } resolve(response); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.fetchMaterial = function (mediaId, type, permanent) { var that = this; var fetchUrl = api.temporary.fetch; if (permanent) { fetchUrl = api.permanent.fetch; } return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = fetchUrl + ('access_token=' + data.access_token); var form = {}; var options = { url: url, method: 'POST', json: true }; if (permanent) { form.media_id = mediaId; options.body = form; } else { options.method = 'GET'; if (type === 'video') { url = url.replace('https://', 'http://'); } url += '&media_id=' + mediaId; } if (type === 'news' || type === 'video') { (0, _requestPromise2.default)(options).then(function (_data) { if (_data.errcode) { throw new Error('fetch Material fails'); } resolve(_data); }).catch(function (err) { reject(err); }); } else { resolve(url); } }); }); }; Wechat.prototype.deleteMaterial = function (mediaId) { var that = this; var form = { media_id: mediaId }; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.permanent.del + ('access_token=' + data.access_token); (0, _requestPromise2.default)({ url: url, method: 'POST', body: form, json: true }).then(function (_data) { if (_data.errcode !== 0) { throw new Error('delete Material fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.updateMaterial = function (mediaId, news) { var that = this; var form = { media_id: mediaId }; Object.assign(form, news); return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.permanent.update_news + ('access_token=' + data.access_token); (0, _requestPromise2.default)({ url: url, method: 'POST', body: form, json: true }).then(function (_data) { if (_data.errcode !== 0) { throw new Error('update Material fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.countMaterial = function () { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.permanent.count + ('access_token=' + data.access_token); (0, _requestPromise2.default)({ url: url, method: 'GET', json: true }).then(function (_data) { if (_data.errcode) { throw new Error('count Material fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.batchMaterial = function (options) { var that = this; options.type = options.type || 'image'; options.offset = options.offset || 0; options.count = options.count || 1; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.permanent.batch + ('access_token=' + data.access_token); (0, _requestPromise2.default)({ url: url, method: 'POST', body: options, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('batch Material fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.createTag = function (name) { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.tag.create + ('access_token=' + data.access_token); var form = { tag: { name: name } }; (0, _requestPromise2.default)({ url: url, method: 'POST', body: form, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('create tag fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.fetchTags = function () { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.tag.fetch + ('access_token=' + data.access_token); (0, _requestPromise2.default)({ url: url, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('fetch Tags fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.updateTag = function (id, name) { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.tag.create + ('access_token=' + data.access_token); var form = { tag: { id: id, name: name } }; (0, _requestPromise2.default)({ url: url, method: 'POST', body: form, json: true }).then(function (_data) { if (_data.errcode !== 0) { throw new Error('update Tag fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.deleteTag = function (id) { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.tag.delete + ('access_token=' + data.access_token); var form = { tag: { id: id } }; (0, _requestPromise2.default)({ url: url, method: 'POST', body: form, json: true }).then(function (_data) { if (_data.errcode !== 0) { throw new Error('delete tag fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.getTagUsers = function (tagId, nextOpenId) { var that = this; var form = { tagid: tagId, next_openid: nextOpenId || '' }; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.tag.create + ('access_token=' + data.access_token); (0, _requestPromise2.default)({ url: url, method: 'POST', body: form, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('get tag users fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.batchTags = function (openIds, tagId) { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.tag.batch + ('access_token=' + data.access_token); var form = { openid_list: openIds, tagid: tagId }; (0, _requestPromise2.default)({ url: url, method: 'POST', body: form, json: true }).then(function (_data) { if (_data.errcode !== 0) { throw new Error('batch tags fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.batchUnTags = function (openIds, tagId) { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.tag.batchUn + ('access_token=' + data.access_token); var form = { openid_list: openIds, tagid: tagId }; (0, _requestPromise2.default)({ url: url, method: 'POST', body: form, json: true }).then(function (_data) { if (_data.errcode !== 0) { throw new Error('batch untagging fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.getUserTags = function (openId) { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.tag.getIdList + ('access_token=' + data.access_token); var form = { openid: openId }; (0, _requestPromise2.default)({ url: url, method: 'POST', body: form, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('get user tags fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.updateRemark = function (openId, remark) { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.user.remark + ('access_token=' + data.access_token); var form = { openid: openId, remark: remark }; (0, _requestPromise2.default)({ url: url, method: 'POST', body: form, json: true }).then(function (_data) { if (_data.errcode !== 0) { throw new Error('update remark fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.fetchUserInfo = function (openId, lang) { var that = this; lang = lang || 'zh_CN'; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.user.fetch + ('access_token=' + data.access_token + '&openid=' + openId + '&lang=' + lang); (0, _requestPromise2.default)({ url: url, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('get user info fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.fetchUsersInfo = function (openIds, lang) { var that = this; lang = lang || 'zh_CN'; var form = void 0; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = void 0; var options = { url: url, json: true }; if (Array.isArray(openIds)) { options.url = api.user.batchFetch + ('access_token=' + data.access_token); form = { user_list: openIds }; options.body = form; options.method = 'POST'; } else { options.url = api.user.fetch + ('access_token=' + data.access_token + '&openid=' + openIds + '&lang=' + lang); } (0, _requestPromise2.default)(options).then(function (_data) { if (_data.errcode) { throw new Error('get user info fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.fetchUserList = function (nextOpenId) { var that = this; nextOpenId = nextOpenId || ''; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.user.list + ('access_token=' + data.access_token + '&next_openid=' + nextOpenId); (0, _requestPromise2.default)({ url: url, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('get user info fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.sendByTag = function (type, message, tagId) { var that = this; var msg = { filter: {}, msgtype: type }; if (!tagId) { msg.filter.is_to_all = true; } else { msg.filter = { is_to_all: false, tag_id: tagId }; } msg[type] = message; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.mass.sendAll + ('access_token=' + data.access_token); (0, _requestPromise2.default)({ url: url, method: 'POST', body: msg, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('sendAll by Tag fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.sendByOpenIds = function (type, message, openIds) { var that = this; var msg = { touser: openIds, msgtype: type }; msg[type] = message; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.mass.openIds + ('access_token=' + data.access_token); (0, _requestPromise2.default)({ url: url, method: 'POST', body: msg, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('send by openIds fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.deleteMass = function (msgId, articleIdx) { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.mass.delete + ('access_token=' + data.access_token); var form = { msg_id: msgId, article_idx: articleIdx || '' }; (0, _requestPromise2.default)({ url: url, method: 'POST', body: form, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('delete mass fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.previewMass = function (type, message, openId) { var that = this; var msg = { touser: openId, msgtype: type }; msg[type] = message; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.mass.preview + ('access_token=' + data.access_token); (0, _requestPromise2.default)({ url: url, method: 'POST', body: msg, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('preview mass by openid fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; //TODO fails Wechat.prototype.checkMass = function (msgId) { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.mass.preview + ('access_token=' + data.access_token); var form = { msg_id: msgId }; (0, _requestPromise2.default)({ url: url, method: 'POST', body: form, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('check mass status fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.createMenu = function (menus) { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.menu.create + ('access_token=' + data.access_token); var form = { button: menus }; (0, _requestPromise2.default)({ url: url, method: 'POST', body: form, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('create menu fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.getMenu = function () { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.menu.get + ('access_token=' + data.access_token); (0, _requestPromise2.default)({ url: url, json: true }).then(function (_data) { if (_data.errcode !== 0) { throw new Error('get menu fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.deleteMenu = function () { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.menu.delete + ('access_token=' + data.access_token); (0, _requestPromise2.default)({ url: url, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('delete menu fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.getCurrentMenu = function () { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.menu.current + ('access_token=' + data.access_token); (0, _requestPromise2.default)({ url: url, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('get current menu fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.createQrcode = function (qr) { var that = this; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.qrcode.create + ('access_token=' + data.access_token); (0, _requestPromise2.default)({ url: url, method: 'POST', body: qr, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('create qrcode fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); }; Wechat.prototype.showQrcode = function (ticket) { var encodedTicket = encodeURI(ticket); return api.qrcode.show + ('ticket=' + encodedTicket); }; Wechat.prototype.createShortUrl = function (action, longUrl) { var that = this; action = action || 'long2short'; return new Promise(function (resolve, reject) { that.fetchAccessToken().then(function (data) { var url = api.shortUrl.create + ('access_token=' + data.access_token); var form = { action: action, long_url: longUrl }; (0, _requestPromise2.default)({ url: url, method: 'POST', body: form, json: true }).then(function (_data) { if (_data.errcode) { throw new Error('create shortUrl fails'); } resolve(_data); }).catch(function (err) { reject(err); }); }); }); };