Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
369 changes: 353 additions & 16 deletions lib/common.js

Large diffs are not rendered by default.

78 changes: 50 additions & 28 deletions lib/wechat.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,22 @@ var tpl = ['<xml>',
'<MusicUrl><![CDATA[<%-content.musicUrl || content.url %>]]></MusicUrl>',
'<HQMusicUrl><![CDATA[<%-content.hqMusicUrl || content.hqUrl %>]]></HQMusicUrl>',
'</Music>',
'<% } else if (msgType === "voice") { %>',
'<Voice>',
'<MediaId><![CDATA[<%-content.mediaId%>]]></MediaId>',
'</Voice>',
'<% } else if (msgType === "image") { %>',
'<Image>',
'<MediaId><![CDATA[<%-content.mediaId%>]]></MediaId>',
'</Image>',
'<% } else if (msgType === "video") { %>',
'<Video>',
'<MediaId><![CDATA[<%-content.mediaId%>]]></MediaId>',
'<ThumbMediaId><![CDATA[<%-content.thumbMediaId%>]]></ThumbMediaId>',
'</Video>',
'<% } else { %>',
'<Content><![CDATA[<%-content%>]]></Content>',
'<% } %>',
'<FuncFlag><%=funcFlag%></FuncFlag>',
'</xml>'].join('');

var compiled = ejs.compile(tpl);
Expand Down Expand Up @@ -73,6 +85,29 @@ var formatMessage = function (result) {
return message;
};

var reply = function (content, fromUsername, toUsername) {
var info = {};
var type = 'text';
info.content = content || '';
if (Array.isArray(content)) {
type = 'news';
} else if (typeof content === 'object') {
if (content.hasOwnProperty('type')) {
type = content.type;
info.content = content.content;
} else {
type = 'music';
}
} else {
type = 'text';
}
info.msgType = type;
info.createTime = new Date().getTime();
info.toUsername = toUsername;
info.fromUsername = fromUsername;
return compiled(info);
};

var respond = function (handler) {
return function (req, res, next) {
getMessage(req, function (err, result) {
Expand All @@ -83,29 +118,9 @@ var respond = function (handler) {
var message = formatMessage(result);
var callback = handler.getHandler(message.MsgType);
req.weixin = message;
res.reply = function (content, funcFlag) {
var info = {};
var type = 'text';
info.content = content || '';
if (Array.isArray(content)) {
type = 'news';
} else if (typeof content === 'object') {
if (content.type === 'text') {
type = 'text';
info.content = content.content;
} else {
type = 'music';
}
} else {
type = 'text';
}
info.msgType = type;
info.createTime = new Date().getTime();
info.funcFlag = funcFlag ? 1 : 0;
info.toUsername = message.FromUserName;
info.fromUsername = message.ToUserName;
res.reply = function (content) {
res.writeHead(200);
res.end(compiled(info));
res.end(reply(content, message.ToUserName, message.FromUserName));
};

var done = function () {
Expand Down Expand Up @@ -198,7 +213,8 @@ Handler.prototype.getHandler = function (type) {
next();
};
};
['text', 'image', 'location', 'voice', 'link', 'event'].forEach(function (method) {

['text', 'image', 'voice', 'video', 'location', 'link', 'event'].forEach(function (method) {
Handler.prototype[method] = function (fn) {
return this.setHandler(method, fn);
};
Expand Down Expand Up @@ -268,15 +284,20 @@ var middleware = function (token, handle) {
*/

/**
* 位置推送处理
* @param {Function} fn 处理位置推送的回调函数,接受参数为(location, req, res, next)。
* 声音推送处理
* @param {Function} fn 处理图片推送的回调函数,接受参数为(image, req, res, next)。
*/

/**
* 声音推送处理
* 视频推送处理
* @param {Function} fn 处理声音推送的回调函数,接受参数为(voice, req, res, next)。
*/

/**
* 位置推送处理
* @param {Function} fn 处理位置推送的回调函数,接受参数为(location, req, res, next)。
*/

/**
* 链接推送处理
* @param {Function} fn 处理链接推送的回调函数,接受参数为(link, req, res, next)。
Expand All @@ -286,11 +307,12 @@ var middleware = function (token, handle) {
* 事件推送处理
* @param {Function} fn 处理事件推送的回调函数,接受参数为(event, req, res, next)。
*/
['text', 'image', 'location', 'voice', 'link', 'event'].forEach(function (method) {
['text', 'image', 'voice', 'video', 'location', 'link', 'event'].forEach(function (method) {
middleware[method] = function (fn) {
return (new Handler())[method](fn);
};
});

module.exports = middleware;
module.exports.toXML = compiled;
module.exports.reply = reply;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"xml2js": "0.2.6",
"ejs": ">=0.8.3",
"bufferhelper": ">=0.2.0",
"urllib": ">=0.3.4"
"formstream": ">=0.0.7",
"urllib": ">=0.5.3"
},
"devDependencies": {
"supertest": "*",
Expand Down
156 changes: 156 additions & 0 deletions test/common.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,162 @@ describe('common.js', function () {
done();
});
});

it('createTmpQRCode should not ok', function (done) {
api.createTmpQRCode(123, 1800, function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});

it('createLimitQRCode should not ok', function (done) {
api.createLimitQRCode(123, function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});

it('showQRCodeURL should not ok', function () {
api.showQRCodeURL('ticket').should.be.equal('https://api.weixin.qq.com/cgi-bin/showqrcode?ticket=ticket');
});

it('getGroups should not ok', function (done) {
api.getGroups(function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});

it('createGroup should not ok', function (done) {
api.createGroup('new group', function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});

it('updateGroup should not ok', function (done) {
api.updateGroup(123, 'new group', function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});

it('moveUserToGroup should not ok', function (done) {
api.moveUserToGroup('openid', 123, function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});

it('getUser should not ok', function (done) {
api.getUser('openid', function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});

it('getFollowers should not ok', function (done) {
api.getFollowers(function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});

it('getFollowers with nextOpenId should not ok', function (done) {
api.getFollowers('openid', function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});

it('sendText should not ok', function (done) {
api.sendText('openid', 'Hellow World', function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});

it('sendImage should not ok', function (done) {
api.sendImage('openid', 'imageId', function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});

it('sendVoice should not ok', function (done) {
api.sendVoice('openid', 'imageId', function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});

it('sendVideo should not ok', function (done) {
api.sendVideo('openid', 'mediaId', 'thumbMediaId', function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});

it('sendMusic should not ok', function (done) {
var music = {
"title":"MUSIC_TITLE", // 可选
"description":"MUSIC_DESCRIPTION", // 可选
"musicurl":"MUSIC_URL",
"hqmusicurl":"HQ_MUSIC_URL",
"thumb_media_id":"THUMB_MEDIA_ID"
};

api.sendMusic('openid', music, function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});

it('sendNews should not ok', function (done) {
var articles = [
{
"title":"Happy Day",
"description":"Is Really A Happy Day",
"url":"URL",
"picurl":"PIC_URL"
}
];

api.sendNews('openid', articles, function (err, data, res) {
should.exist(err);
err.name.should.be.equal('WeChatAPIError');
err.message.should.be.equal('invalid credential');
done();
});
});
});

describe('mock', function () {
Expand Down
Loading