├── .env ├── .foreverignore ├── .gitignore ├── .travis.yml ├── Makefile ├── Procfile ├── README.md ├── app.js ├── lib └── support.js ├── logo.png ├── manifest.yml ├── package.json ├── qrcode.jpg ├── rules ├── dialog.yaml └── index.js └── test ├── bootstrap.js ├── mocha.opts └── rule.js /.env: -------------------------------------------------------------------------------- 1 | NODE_ENV=production 2 | DEBUG="webot-example:* -*:verbose" 3 | -------------------------------------------------------------------------------- /.foreverignore: -------------------------------------------------------------------------------- 1 | node_modules/**/*.js 2 | **/.git/** 3 | *.bak 4 | .DS_Store 5 | Makefile 6 | Gruntfile.js 7 | *.styl 8 | *.css 9 | *.gif 10 | *.png 11 | *.jpg 12 | *.min.js 13 | *.jade 14 | *.yaml 15 | *.xml 16 | *.md 17 | **.statictmp/** 18 | **static/**/*.js 19 | templates/** 20 | var/* 21 | *.rdb 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | *.swp 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.8 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | start: 2 | @export DEBUG=webot* && npm start 3 | 4 | clear: 5 | @clear 6 | 7 | test: clear 8 | @export DEBUG="webot* -*verbose" && export WX_TOKEN=test123 && ./node_modules/.bin/mocha 9 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: node app.js 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [微信公共帐号机器人](https://github.com/node-webot/weixin-robot)示例 [](https://travis-ci.org/node-webot/webot-example) 2 | 3 | ## 本地运行 4 | 5 | ```bash 6 | git clone https://github.com/node-webot/webot-example.git 7 | cd webot-example/ 8 | npm install 9 | make start 10 | ``` 11 | 12 | 其中,`make start` 命令会调用 `node app.js` 。 13 | 建议你 fork 一份自己的版本,这样你就可以任意做出更改和调试了。 14 | 15 | 16 | ## 消息调试 17 | 18 | 使用 `webot-cli` [命令行工具](https://github.com/node-webot/webot-cli)来发送测试消息。 19 | 20 | 安装: 21 | 22 | ```bash 23 | npm install webot-cli -g 24 | ``` 25 | 26 | `npm install -g` 代表全局安装 npm 模块,你可能需要 `sudo` 权限。 27 | 28 | 使用: 29 | 30 | ``` 31 | webot help # 查看使用帮助 32 | webot send Hello # 发送一条叫「Hello」的消息 33 | webot send image # 调试图片消息 34 | webot send location # 调试地理位置 35 | webot send event # 调试事件消息 36 | ``` 37 | 38 | `webot-cli` 默认访问的接口地址是 http://127.0.0.1:3000 ,要调试本示例的程序, 39 | 你需要指定 `webot send --des http://127.0.0.1:3000/wechat' 40 | 41 | 42 | ## 在微信上试用此示例 43 | 44 | - 微信账号:webot-test 45 | 46 |  47 | 48 | # 搭建你自己的机器人 49 | 50 | 1. fork 本仓库,修改 package.json 里的各项属性 51 | 2. 修改你自己的 app.js ,填写你在微信后台输入的 token 52 | 3. 参考 rules/index.js ,新建你自己的回复规则 53 | 54 | ## 发布到云平台 55 | 56 | 仓库中的 `Procfile` 为 [heroku](http://www.heroku.com/) 的配置文件。 57 | `manifest.yml` 为 [cloudfoundry](http://www.cloudfoundry.com/) 的示例配置文件。 58 | 59 | # Credit 60 | 61 | [weixin-robot](https://github.com/node-webot/weixin-robot) 的[初始版本](https://github.com/node-webot/weixin-robot/tree/0.0.x)由[@ktmud](https://github.com/ktmud)实现, 62 | [@atian](https://github.com/atian25)重构并扩展为 0.2 版本。目前的测试用例也大部分由他完成。 63 | 64 | [weixin-robot] 使用了 [@JacksonTian](https://github.com/JacksonTian) 的 [wechat](https://github.com/node-webot/wechat) 组件。 65 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var webot = require('weixin-robot'); 3 | 4 | var log = require('debug')('webot-example:log'); 5 | var verbose = require('debug')('webot-example:verbose'); 6 | 7 | // 启动服务 8 | var app = express(); 9 | 10 | // 实际使用时,这里填写你在微信公共平台后台填写的 token 11 | var wx_token = process.env.WX_TOKEN || 'keyboardcat123'; 12 | var wx_token2 = process.env.WX_TOKEN_2 || 'weixinToken2'; 13 | 14 | // 建立多个实例,并监听到不同 path , 15 | var webot2 = new webot.Webot(); 16 | 17 | // 载入webot1的回复规则 18 | require('./rules')(webot); 19 | // 为webot2也指定规则 20 | webot2.set('hello', 'hi.'); 21 | 22 | // 启动机器人, 接管 web 服务请求 23 | webot.watch(app, { token: wx_token, path: '/wechat' }); 24 | // 若省略 path 参数,会监听到根目录 25 | // webot.watch(app, { token: wx_token }); 26 | 27 | // 后面指定的 path 不可为前面实例的子目录 28 | webot2.watch(app, { token: wx_token2, path: '/wechat_2' }); 29 | 30 | // 如果需要 session 支持,sessionStore 必须放在 watch 之后 31 | app.use(express.cookieParser()); 32 | // 为了使用 waitRule 功能,需要增加 session 支持 33 | app.use(express.session({ 34 | secret: 'abced111', 35 | store: new express.session.MemoryStore() 36 | })); 37 | // 在生产环境,你应该将此处的 store 换为某种永久存储。 38 | // 请参考 http://expressjs.com/2x/guide.html#session-support 39 | 40 | // 在环境变量提供的 $PORT 或 3000 端口监听 41 | var port = process.env.PORT || 3000; 42 | app.listen(port, function(){ 43 | log("Listening on %s", port); 44 | }); 45 | 46 | // 微信接口地址只允许服务放在 80 端口 47 | // 所以需要做一层 proxy 48 | app.enable('trust proxy'); 49 | 50 | // 当然,如果你的服务器允许,你也可以直接用 node 来 serve 80 端口 51 | // app.listen(80); 52 | 53 | if(!process.env.DEBUG){ 54 | console.log("set env variable `DEBUG=webot-example:*` to display debug info."); 55 | } 56 | -------------------------------------------------------------------------------- /lib/support.js: -------------------------------------------------------------------------------- 1 | var debug = require('debug'); 2 | var log = debug('webot-example:log'); 3 | 4 | var _ = require('underscore')._; 5 | var request = require('request'); 6 | 7 | /** 8 | * 通过高德地图API查询用户的位置信息 9 | */ 10 | exports.geo2loc = function geo2loc(param, cb){ 11 | var options = { 12 | url: 'http://restapi.amap.com/rgeocode/simple', 13 | qs: { 14 | resType: 'json', 15 | encode: 'utf-8', 16 | range: 3000, 17 | roadnum: 0, 18 | crossnum: 0, 19 | poinum: 0, 20 | retvalue: 1, 21 | sid: 7001, 22 | region: [param.lng, param.lat].join(',') 23 | } 24 | }; 25 | log('querying amap for: [%s]', options.qs.region); 26 | 27 | //查询 28 | request.get(options, function(err, res, body){ 29 | if(err){ 30 | error('geo2loc failed', err); 31 | return cb(err); 32 | } 33 | var data = JSON.parse(body); 34 | if(data.list && data.list.length>=1){ 35 | data = data.list[0]; 36 | var location = data.city.name || data.province.name; 37 | log('location is %s, %j', location, data); 38 | return cb(null, location, data); 39 | } 40 | log('geo2loc found nth.'); 41 | return cb('geo2loc found nth.'); 42 | }); 43 | }; 44 | 45 | /** 46 | * 搜索百度 47 | * 48 | * @param {String} keyword 关键词 49 | * @param {Function} cb 回调函数 50 | * @param {Error} cb.err 错误信息 51 | * @param {String} cb.result 查询结果 52 | */ 53 | exports.search = function(keyword, cb){ 54 | log('searching: %s', keyword); 55 | var options = { 56 | url: 'http://www.baidu.com/s', 57 | qs: { 58 | wd: keyword 59 | } 60 | }; 61 | request.get(options, function(err, res, body){ 62 | if (err || !body){ 63 | return cb(null, '现在暂时无法搜索,待会儿再来好吗?'); 64 | } 65 | var regex = /