wechat-lite
Version:
wechat js api
106 lines (100 loc) • 3.02 kB
JavaScript
const url = require('url');
const crypto = require('crypto');
const xml2js = require('xml2js');
const js2xml = require('jstoxml');
const { monitorEventLoopDelay } = require('perf_hooks');
/**
* [parse description]
* @param {[type]} data [description]
* @return {[type]} [description]
* @docs http://mp.weixin.qq.com/wiki/17/f298879f8fb29ab98b2f2971d42552fd.html
*/
function parseMessage(xml) {
return new Promise((resolve, reject) => {
xml2js.parseString(xml, (err, result) => {
if (err) return reject(err);
resolve(Object.keys(result.xml).reduce((item, key) => {
item[key] = result.xml[key][0];
return item;
}, {}));
});
});
};
/**
* [genSignature description]
* @param {[type]} token [description]
* @param {[type]} timestamp [description]
* @param {[type]} nonce [description]
* @return {[type]} [description]
*/
function genSignature(token, timestamp, nonce) {
return crypto
.createHash('sha1')
.update(([]).slice.call(arguments).sort().join(''))
.digest('hex');
}
const parseBody = req => {
return new Promise((resolve, reject) => {
var buffer = ''; req
.on('error', reject)
.on('data', chunk => buffer += chunk)
.on('end', () => resolve(buffer));
});
};
/**
* [WeChatServer]
* @param {[type]} token [description]
* @param {Function} handler [description]
*/
function WeChatServer(token, handler) {
/**
* [send description]
* @param {[type]} reply [description]
* @return {[type]} [description]
* @docs http://mp.weixin.qq.com/wiki/1/6239b44c206cab9145b1d52c67e6c551.html
*/
function sendMsg(message, reply) {
if (!reply) return;
const { FromUserName, ToUserName } = message;
if (typeof reply == 'string') {
reply = {
MsgType: 'text',
Content: reply
};
}
reply = Object.assign(reply, {
FromUserName: ToUserName,
ToUserName: FromUserName,
CreateTime: +new Date,
MsgId: ~new Date,
});
// reply
const res = this;
const data = js2xml.toXML({ xml: reply });
res.setHeader('Content-Type', 'application/xml');
res.setHeader('Content-Length', new Buffer(data).length);
res.end(data);
}
/**
* [function description]
* @param {[type]} req [description]
* @param {[type]} res [description]
* @return {[type]} [description]
*/
return function request(req, res) {
const { query } = url.parse(req.url, true);
const { signature, echostr, timestamp, nonce } = query;
const sign = genSignature(token, timestamp, nonce);
if (!(signature === sign)) return res.end('Invalidate signature');
if (req.method === 'GET') return res.end(echostr);
Promise.resolve(req)
.then(parseBody)
.then(parseMessage)
.then(message => {
const send = sendMsg.bind(res, message);
send(handler.call({ send }, null, message));
}, handler);
};
};
module.exports = WeChatServer;
;