diff --git a/README.en.md b/README.en.md new file mode 100644 index 00000000..82952afb --- /dev/null +++ b/README.en.md @@ -0,0 +1,335 @@ +wechat [![NPM version](https://badge.fury.io/js/wechat.png)](http://badge.fury.io/js/wechat) [![Build Status](https://travis-ci.org/node-webot/wechat.png?branch=master)](https://travis-ci.org/node-webot/wechat) [![Dependencies Status](https://david-dm.org/node-webot/wechat.png)](https://david-dm.org/node-webot/wechat) [![Coverage Status](https://coveralls.io/repos/node-webot/wechat/badge.png)](https://coveralls.io/r/node-webot/wechat) +====== + +Wechat is a middleware and SDK of Wechat Official Account Admin Platform (mp.weixin.qq.com). + +This wechat document is translated by [Guo Yu](https://github.com/turingou/), if you have some understanding problems, please feel free open an issue [here](https://github.com/turingou/wechat/issues). + +## Features + +- Auto reply (text, image, videos, music, thumbnails posts are supported) +- CRM message (text, image, videos, music, thumbnails posts are supported) +- Menu settings (CRD are supported) +- QR codes (CR are supported, both temporary and permanent) +- Group settings (CRUD are supported) +- Followers infomation (fetching user's info or followers list) +- Media (upload or download) +- Reply Waiter (good for surveys) +- Sessions +- OAuth API + +API details located [here](http://node-webot.github.io/wechat/api.html) + +## Installation + +``` +npm install wechat +``` + +## Use with Connect/Express + +``` +var wechat = require('wechat'); + +app.use(connect.query()); // Or app.use(express.query()); +app.use('/wechat', wechat('some token', function (req, res, next) { + // message is located in req.weixin + var message = req.weixin; + if (message.FromUserName === 'diaosi') { + // reply with text + res.reply('hehe'); + } else if (message.FromUserName === 'text') { + // another way to reply with text + res.reply({ + content: 'text object', + type: 'text' + }); + } else if (message.FromUserName === 'hehe') { + // reply with music + res.reply({ + type: "music", + content: { + title: "Just some music", + description: "I have nothing to lose", + musicUrl: "http://mp3.com/xx.mp3", + hqMusicUrl: "http://mp3.com/xx.mp3" + } + }); + } else { + // reply with thumbnails posts + res.reply([ + { + title: 'Come to fetch me', + description: 'or you want to play in another way ?', + picurl: 'http://nodeapi.cloudfoundry.com/qrcode.jpg', + url: 'http://nodeapi.cloudfoundry.com/' + } + ]); + } +})); +``` + +*Tips*: you'll have to apply `token` at [Wechat platform (this page is in Chinese)](http://mp.weixin.qq.com/cgi-bin/callbackprofile?type=info&t=wxm-developer-ahead&lang=zh_CN) + +### Reply Messages + +auto reply a message when your followers send a message to you. also text, image, videos, music, thumbnails posts are supported. details API goes [here (official documents)](http://mp.weixin.qq.com/wiki/index.php?title=发送被动响应消息) + +#### Reply with text +``` +res.reply('Hello world!'); +// or +res.reply({type: "text", content: 'Hello world!'}); +``` +#### Reply with Image +``` +res.reply({ + type: "image", + content: { + mediaId: 'mediaId' + } +}); +``` +#### Reply with voice +``` +res.reply({ + type: "voice", + content: { + mediaId: 'mediaId' + } +}); +``` +#### Reply with Video +``` +res.reply({ + type: "video", + content: { + mediaId: 'mediaId', + thumbMediaId: 'thumbMediaId' + } +}); +``` +#### Reply with Music +``` +res.reply({ + title: "Just some music", + description: "I have nothing to lose", + musicUrl: "http://mp3.com/xx.mp3", + hqMusicUrl: "http://mp3.com/xx.mp3" +}); +``` +#### Reply with Thumbnails posts +``` +res.reply([ + { + title: 'Come to fetch me', + description: 'or you want to play in another way ?', + picurl: 'http://nodeapi.cloudfoundry.com/qrcode.jpg', + url: 'http://nodeapi.cloudfoundry.com/' + } +]); +``` + +### WXSession + +Wechat messages are not communicate like traditional C/S model, therefore nothing Cookies will be store in Wechat client. this WXSession is designed to support access user's infomation via `req.wxsession`, with `connect.session` backed. + +It's a simple demo: + +``` +app.use(connect.cookieParser()); +app.use(connect.session({secret: 'keyboard cat', cookie: {maxAge: 60000}})); +app.use('/wechat', wechat('some token', wechat.text(function (info, req, res, next) { + if (info.Content === '=') { + var exp = req.wxsession.text.join(''); + req.wxsession.text = ''; + res.reply(exp); + } else { + req.wxsession.text = req.wxsession.text || []; + req.wxsession.text.push(info.Content); + res.reply('Message got ' + info.Content); + } +}))); +``` + +`req.wxsession` and `req.session` shares same store. width `redis` as persistence database, across processes sharing are supportd. + +### Reply Waiter + +a reply waiter is seems like a telephone menu system. it must be setup before activation. this function is supported upon WXSession. + +``` +var List = require('wechat').List; +List.add('view', [ + ['reply {a}', function (info, req, res) { + res.reply('Im Answer A'); + }], + ['reply {b}', function (info, req, res) { + res.reply('Im Answer B'); + }], + ['reply {c}', 'Im Answer C (the shorthand method)'] +]); +``` + +active the reply waiter we setuped before: + +``` +var app = connect(); +app.use(connect.query()); +app.use(connect.cookieParser()); +app.use(connect.session({secret: 'keyboard cat', cookie: {maxAge: 60000}})); +app.use('/wechat', wechat('some token', wechat.text(function (info, req, res, next) { + if (info.Content === 'list') { + res.wait('view'); // view is the very waiter we setuped before. + } else { + res.reply('hehe'); + // or stop the waiter and quit. + // res.nowait('hehe'); + } +}))); +``` + +if waiter `view` actived, user will receive messages below: + +``` +reply a +reply b +reply c +``` + +reply waiter acquires both function and text as a `callback` action + +``` +List.add('view', [ + ['reply {a}', function (info, req, res, next) { + // we callback as a function + res.reply('Answer A'); + }], + // or text as shorthand + ['reply {c}', 'Answer C'] +]); +``` + +if user's message is not in waiter's trigger texts. this message will be processd in the `else` way and can be stoped by `res.nowait()`, `res.nowait` method actions like `reply` method. + +## Show cases +### Auto-reply robot based on Node.js + +![Node.js API Auto-reply robot](http://nodeapi.diveintonode.org/assets/qrcode.jpg) + +Codes here + +robots can be setup in PAASs like [CloudFoundry](http://www.cloudfoundry.com/), [appfog](https://www.appfog.com/) or [BAE](http://developer.baidu.com/wiki/index.php?title=docs/cplat/rt/node.js). + +## API details +official document locates here [Messages API Guide (in Chinese)](http://mp.weixin.qq.com/wiki/index.php?title=消息接口指南)。 + +wachat 0.6.x supports shorthand methods below: + +``` +app.use('/wechat', wechat('some token', wechat.text(function (message, req, res, next) { + // reply with text + // { ToUserName: 'gh_d3e07d51b513', + // FromUserName: 'oPKu7jgOibOA-De4u8J2RuNKpZRw', + // CreateTime: '1359125035', + // MsgType: 'text', + // Content: 'http', + // MsgId: '5837397576500011341' } +}).image(function (message, req, res, next) { + // message为图片内容 + // { ToUserName: 'gh_d3e07d51b513', + // FromUserName: 'oPKu7jgOibOA-De4u8J2RuNKpZRw', + // CreateTime: '1359124971', + // MsgType: 'image', + // PicUrl: 'http://mmsns.qpic.cn/mmsns/bfc815ygvIWcaaZlEXJV7NzhmA3Y2fc4eBOxLjpPI60Q1Q6ibYicwg/0', + // MediaId: 'media_id', + // MsgId: '5837397301622104395' } +}).voice(function (message, req, res, next) { + // Reply with Voice + // { ToUserName: 'gh_d3e07d51b513', + // FromUserName: 'oPKu7jgOibOA-De4u8J2RuNKpZRw', + // CreateTime: '1359125022', + // MsgType: 'voice', + // MediaId: 'OMYnpghh8fRfzHL8obuboDN9rmLig4s0xdpoNT6a5BoFZWufbE6srbCKc_bxduzS', + // Format: 'amr', + // MsgId: '5837397520665436492' } +}).video(function (message, req, res, next) { + // Reply with Video + // { ToUserName: 'gh_d3e07d51b513', + // FromUserName: 'oPKu7jgOibOA-De4u8J2RuNKpZRw', + // CreateTime: '1359125022', + // MsgType: 'video', + // MediaId: 'OMYnpghh8fRfzHL8obuboDN9rmLig4s0xdpoNT6a5BoFZWufbE6srbCKc_bxduzS', + // ThumbMediaId: 'media_id', + // MsgId: '5837397520665436492' } +}).location(function (message, req, res, next) { + // Reply with Location (geo) + // { ToUserName: 'gh_d3e07d51b513', + // FromUserName: 'oPKu7jgOibOA-De4u8J2RuNKpZRw', + // CreateTime: '1359125311', + // MsgType: 'location', + // Location_X: '30.283950', + // Location_Y: '120.063139', + // Scale: '15', + // Label: {}, + // MsgId: '5837398761910985062' } +}).link(function (message, req, res, next) { + // Reply with Link + // { ToUserName: 'gh_d3e07d51b513', + // FromUserName: 'oPKu7jgOibOA-De4u8J2RuNKpZRw', + // CreateTime: '1359125022', + // MsgType: 'link', + // Title: 'A link', + // Description: 'A link has its desc', + // Url: 'http://1024.com/', + // MsgId: '5837397520665436492' } +}).event(function (message, req, res, next) { + // Reply with Event + // { ToUserName: 'gh_d3e07d51b513', + // FromUserName: 'oPKu7jgOibOA-De4u8J2RuNKpZRw', + // CreateTime: '1359125022', + // MsgType: 'event', + // Event: 'LOCATION', + // Latitude: '23.137466', + // Longitude: '113.352425', + // Precision: '119.385040', + // MsgId: '5837397520665436492' } +}))); +``` + +*Tips*: `text`, `image`, `voice`, `video`, `location`, `link`, `event` must be set at least one. + +### More simple APIs + +Supported in 0.3.x and above. + +``` +app.use('/wechat', wechat('some token').text(function (message, req, res, next) { + // TODO +}).image(function (message, req, res, next) { + // TODO +}).voice(function (message, req, res, next) { + // TODO +}).video(function (message, req, res, next) { + // TODO +}).location(function (message, req, res, next) { + // TODO +}).link(function (message, req, res, next) { + // TODO +}).event(function (message, req, res, next) { + // TODO +}).middlewarify()); +``` + +### Functions Graph +![graph](https://raw.github.com/node-webot/wechat/master/figures/wechat.png) + +*Tips*: Business logic in blue lines. + +## License +The MIT license. + +## Donation +buy me a cup of coffee please. + +[![donate wechat](https://img.alipay.com/sys/personalprod/style/mc/btn-index.png)](https://me.alipay.com/jacksontian) diff --git a/README.md b/README.md index 9f134718..21d2bd62 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ wechat [![NPM version](https://badge.fury.io/js/wechat.png)](http://badge.fury.i 微信公共平台消息接口服务中间件与API SDK +[Wechat document in English](./README.en.md) + ## 功能列表 - 自动回复(文本、图片、语音、视频、音乐、图文) - 客服消息(文本、图片、语音、视频、音乐、图文)