├── .DS_Store ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── index.js ├── lib ├── face.js ├── history.js ├── translate.js └── weather.js ├── package.json └── test ├── face.test.js ├── history.test.js ├── translate.test.js └── weather.test.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netpi/spiders/06ed5eddc1fd24f92e8bca7e52b169aab99b6126/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Commenting this out is preferred by some people, see 24 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 25 | node_modules 26 | 27 | # Users Environment Variables 28 | .lock-wscript 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Night Hunter 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | test: 2 | ./node_modules/.bin/mocha 3 | 4 | cov test-cov: 5 | ./node_modules/.bin/istanbul cover _mocha 6 | 7 | .PHONY: test cov test-cov 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## wechat-tools 让您的公众平台有可以回复‘天气预报’、‘历史上的今天’ 等 2 | 源码地址 [netpi/wechat-tools](https://github.com/netpi/wechat-tools) 3 | 4 | 5 | 推荐微信公众平台的开发者配合使用 [node-webot/wechat](https://github.com/node-webot/wechat) 6 | 7 | ### 功能预览 8 | 9 | 1 ,天气预报 (获取中国任意城市 三天内的天气预报) 10 | 11 | 2 ,历史上的今天 (获取历史上的今天 发生的大事件) 12 | 13 | 3 ,翻译助手(自动检查语言并且翻译-支持12种语言) 14 | 15 | 4 ,人脸识别(分析某一张照片上的人脸信息) 16 | ## 安装 17 | ``` 18 | npm install wechat-tools --save; 19 | ``` 20 | ## 测试 21 | 22 | ``` 23 | make test ; 24 | 25 | ``` 26 | ### 1 天气预报 (获取中国任意城市 三天内的天气预报) 27 | 此为共享 ak = uD67wmZzhi3RFcmTkGoks2Dr,实际应用时建议去[百度开发者](http://developer.baidu.com/map/index.php)自行申请ak 28 | 29 | ```js 30 | var wt = request('wechat-tools'); 31 | var ak = 'uD67wmZzhi3RFcmTkGoks2Dr';// 32 | var city = '北京'; 33 | wt.weather(ak,city,function(err , data){ 34 | if(err){ 35 | throw err; 36 | }else{ 37 | console.log(data); 38 | } 39 | }); 40 | ``` 41 | #### console.log(data); 结果如下图 42 | ![参考图片](http://pistatic.qiniudn.com/images/weather01.png?imageView2/1/w/500/) 43 | ### 2 历史上的今天 (获取历史上的今天 发生的大事件) 44 | ```js 45 | wt.history(function (err,data) { 46 | if(err){ 47 | throw err; 48 | }else{ 49 | console.log(data); 50 | } 51 | }) 52 | ``` 53 | #### console.log(data); 结果如下图 54 | ![参考图片](http://pistatic.qiniudn.com/images/history01.png?imageView2/1/w/400/) 55 | 56 | ### 3 翻译助手(自动检查语言并且翻译-支持12种语言) 57 | 58 | 支持语言种类: 59 | 中文、英语、日语、韩语、德语、法语、俄语、泰语、意大利语、西班牙语、葡萄牙语、阿拉伯语 60 | 61 | 62 | 翻译服务会自动检测源语言语种,并根据源语言的语种按照规则设置目标语言的语种。当源语言为非中文时,目标语言自动设置为中文。当源语言为中文时,目标语言自动设置为英文。 63 | 64 | #### 英译汉 65 | ```js 66 | var wt = request('wechat-tools'); 67 | var ak = 'uD67wmZzhi3RFcmTkGoks2Dr'; 68 | var word = '周末放假'; // 要翻译的词汇 69 | wt.translate(ak, word, function(err, data) { 70 | if (err) { 71 | throw err; 72 | } else { 73 | console.log(data);// --> The weekend holiday 74 | }; 75 | }); 76 | ``` 77 | #### 汉译英 78 | ```js 79 | 80 | var wt = request('wechat-tools'); 81 | var ak = 'uD67wmZzhi3RFcmTkGoks2Dr'; 82 | var word = 'The weekend holiday'; // 要翻译的单词 83 | wt.translate(ak, word, function(err, data) { 84 | if (err) { 85 | throw err; 86 | } else { 87 | console.log(data);// --> 周末度假 88 | }; 89 | }); 90 | 91 | ``` 92 | 93 | ### 4 人脸识别 (分析某一张照片上的人脸信息) 94 | 95 | 建议去 [face++](http://www.faceplusplus.com.cn/) 官网申请api_key、api_secret 96 | 97 | ```js 98 | 99 | var wt = request('wechat-tools'); 100 | 101 | var option = { 102 | api_key : '0ef14fa726ce34d820c5a44e57fef470', 103 | api_secret : '4Y9YXOMSDvqu1Ompn9NSpNwWQFHs1hYD', 104 | imgurl : 'http://cn.faceplusplus.com/static/resources/python_demo/1.jpg' 105 | }; 106 | 107 | wt.face(option , function (err,data) { 108 | if(err){ 109 | // err ... 110 | }else{ 111 | var face1 = JSON.parse(data).face[0]; 112 | console.log(face1.attribute.age); // => { range: 7, value: 33 } (33岁 偏差 7) 113 | console.log(face1.attribute.gender); // => { confidence: 99.94, value: 'Male' } (女 可信度99.94/%) 114 | console.log(face1.attribute.race); // => { confidence: 99.6939, value: 'White' } (白种人 可信度99.6939%) 115 | } 116 | }); 117 | ``` 118 | 详细结果分析参看 [face++ api文档](http://www.faceplusplus.com.cn/detection_detect/) 119 | 120 | ## 应用 121 | ![参考图片](http://pistatic.qiniudn.com/images/history-code.jpg?imageView2/1/w/300/) 122 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | function wechattools() {} 2 | wechattools.weather = require('./lib/weather'); 3 | wechattools.history = require('./lib/history'); 4 | wechattools.translate = require('./lib/translate'); 5 | wechattools.face = require('./lib/face'); 6 | 7 | module.exports = wechattools; -------------------------------------------------------------------------------- /lib/face.js: -------------------------------------------------------------------------------- 1 | var urllib =require('urllib'); 2 | 3 | var face =function (opt , callback) { 4 | 5 | var ak = opt.api_key; 6 | var sk = opt.api_secret; 7 | var imgurl = opt.imgurl; 8 | urllib.request('https://apicn.faceplusplus.com/v2/detection/detect', { 9 | method: 'POST', 10 | data: { 11 | api_key: ak, 12 | api_secret: sk, 13 | url: imgurl 14 | } 15 | }, function(urllib_err, data) { 16 | var error = null; 17 | if (urllib_err) { 18 | 19 | error = urllib_err; 20 | } else { 21 | var face_error = JSON.parse(data.toString()).error; 22 | if(face_error){ 23 | error = data; 24 | }else if(!JSON.parse(data.toString()).face[0]){ 25 | error = {'error' : 'no face'}; 26 | } 27 | callback(error, data.toString()); 28 | } 29 | }); 30 | }; 31 | module.exports = face; 32 | -------------------------------------------------------------------------------- /lib/history.js: -------------------------------------------------------------------------------- 1 | var urllib = require('urllib'); 2 | var history = function(callback) { 3 | urllib.request('http://www.rijiben.com/', function(error, data, res1) { 4 | var err = null; 5 | // 返回的数据 6 | var rdata = ''; 7 | if (error) { 8 | err = error; 9 | } else { 10 | var re = /)/; 11 | var str = data.toString().match(re)[0]; 12 | str = str.replace(/<[^<>]+>/g, '').replace(/\s\s\s/g, "").replace(/(图)/g, ""); 13 | var attr = str.split("  "); 14 | var date = new Date(); 15 | var m = date.getMonth() + 1; 16 | var d = date.getDate(); 17 | rdata = "\ue513 历史上的" + m + "月" + d + "日\n\n"; 18 | for (var i = 0; i < attr.length - 1; i++) { 19 | var attr2 = attr[i].trim().split(/\s/); 20 | // rdata +='\ue148'; 21 | rdata += attr2[0].substring(0, 5) + " "; 22 | rdata += attr2[1] + "\n\n"; 23 | } 24 | } 25 | callback(err, rdata); 26 | }); 27 | }; 28 | module.exports = history; -------------------------------------------------------------------------------- /lib/translate.js: -------------------------------------------------------------------------------- 1 | var urllib = require('urllib'); 2 | 3 | var translate = function(ak, data, callback) { 4 | var url = 'http://openapi.baidu.com/public/2.0/bmt/translate?client_id='+ak+'&q='+data+'&from=auto&to=auto'; 5 | urllib.request(url, function(error, data, res1) { 6 | 7 | var str = ""; 8 | var err = null; 9 | var result = null; 10 | if (error) { 11 | err = error.toString(); 12 | } 13 | else if(JSON.parse(data).error_code){ 14 | err = data; 15 | }else{ 16 | result = JSON.parse(data).trans_result[0].dst; 17 | } 18 | callback(err,result); 19 | }); 20 | }; 21 | module.exports = translate; -------------------------------------------------------------------------------- /lib/weather.js: -------------------------------------------------------------------------------- 1 | var urllib = require('urllib'); 2 | 3 | var weather = function(ak, city, callback) { 4 | var url = 'http://api.map.baidu.com/telematics/v3/weather?location=' + city.toString() + '&output=json&ak=' + ak; 5 | urllib.request(url, function(error, data, res1) { 6 | 7 | var str = ""; 8 | var err = null; 9 | if (error) { 10 | this.err = error.toString(); 11 | } 12 | if (JSON.parse(data).status === 'success') { 13 | str += JSON.parse(data).results[0].currentCity + '\n'; 14 | var weatherAttr = JSON.parse(data).results[0].weather_data; 15 | str += weatherAttr[0].date + '\n'; 16 | str += weatherAttr[0].temperature + '\n'; 17 | str += weatherAttr[0].weather + '\n'; 18 | str += weatherAttr[0].wind + '\n'; 19 | str += '\n'; 20 | 21 | str += weatherAttr[1].date + '\n'; 22 | str += weatherAttr[1].temperature + '\n'; 23 | str += weatherAttr[1].weather + '\n'; 24 | str += weatherAttr[1].wind + '\n'; 25 | str += '\n'; 26 | 27 | str += weatherAttr[2].date + '\n'; 28 | str += weatherAttr[2].temperature + '\n'; 29 | str += weatherAttr[2].weather + '\n'; 30 | str += weatherAttr[2].wind + '\n'; 31 | } else { 32 | this.err = data; 33 | } 34 | callback(this.err, str.toString()); 35 | }); 36 | }; 37 | module.exports = weather; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wechat-tools", 3 | "version": "0.0.6", 4 | "description": "wechat 回复小工具 ,包括天气预报、历史今天、翻译工具、人脸识别 等实用功能", 5 | "main": "index.js", 6 | "keywords": [ 7 | "wechat", 8 | "weixin" 9 | ], 10 | "author": "netpi", 11 | "dependencies": { 12 | "urllib": "^1.5.2" 13 | }, 14 | "devDependencies": { 15 | "istanbul": "^0.3.2", 16 | "mocha": "^2.0.1", 17 | "should": "^4.1.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/face.test.js: -------------------------------------------------------------------------------- 1 | var wt = require('../index'); 2 | var should = require('should'); 3 | 4 | describe('test/face.test.js', function() { 5 | describe('vaild result', function() { 6 | it('should have properties ', function(done) { 7 | var option = { 8 | api_key: '0ef14fa726ce34d820c5a44e57fef470', 9 | api_secret: '4Y9YXOMSDvqu1Ompn9NSpNwWQFHs1hYD', 10 | imgurl: 'http://c.hiphotos.baidu.com/image/pic/item/aec379310a55b31951a0887141a98226cffc175c.jpg' 11 | }; 12 | wt.face(option, function(err, data) { 13 | if (err) { 14 | done(); 15 | } else { 16 | var face1 = JSON.parse(data).face[0]; 17 | face1.attribute.should.have.properties('age', 'gender', 'race'); 18 | done(); 19 | } 20 | }); 21 | }); 22 | 23 | describe('vaild err', function() { 24 | it('err api_key => err.should.be.an.instanceof(Object)', function(done) { 25 | var option = { 26 | api_key: 'err api_key', 27 | api_secret: 'err api_secret', 28 | imgurl: 'http://c.hiphotos.baidu.com/image/pic/item/aec379310a55b31951a0887141a98226cffc175c.jpg' 29 | }; 30 | wt.face(option, function(err, data) { 31 | err.should.be.an.instanceof(Object); 32 | done(); 33 | }); 34 | }); 35 | it('no face imageurl =>err.error.should.be.eql(\'no face\')', function(done) { 36 | var option = { 37 | api_key: '0ef14fa726ce34d820c5a44e57fef470', 38 | api_secret: '4Y9YXOMSDvqu1Ompn9NSpNwWQFHs1hYD', 39 | //no face url ;face++找不到face的url 40 | imgurl: 'http://mmbiz.qpic.cn/mmbiz/s7dKUUicDUVutPZ2BiaymBXicVTNPIKuk2J5z19bicJkbmpliaORoMuAhUgCxzgN1yAM3RfHoZibNSkD4icdlurWicAgCg/0' 41 | }; 42 | wt.face(option, function(err, data) { 43 | err.error.should.be.eql('no face'); 44 | done(); 45 | }); 46 | }); 47 | it('err imageurl =>err.should.be.an.instanceof(Object)', function(done) { 48 | var option = { 49 | api_key: '0ef14fa726ce34d820c5a44e57fef470', 50 | api_secret: '4Y9YXOMSDvqu1Ompn9NSpNwWQFHs1hYD', 51 | imgurl: 'bad url' //bad url 52 | }; 53 | wt.face(option, function(err, data) { 54 | err.should.be.an.instanceof(Object); 55 | done(); 56 | }); 57 | }); 58 | }); 59 | }); 60 | }); -------------------------------------------------------------------------------- /test/history.test.js: -------------------------------------------------------------------------------- 1 | var wt = require('../index'); 2 | var should = require('should'); 3 | 4 | describe('test/history.test.js', function() { 5 | describe('valid result', function() { 6 | it('should.be.type string', function(done) { 7 | wt.history(function(err, data) { 8 | if (err) {} else { 9 | data.should.be.type('string'); 10 | } 11 | done(); 12 | }); 13 | }); 14 | }); 15 | }); -------------------------------------------------------------------------------- /test/translate.test.js: -------------------------------------------------------------------------------- 1 | var wt = require('../index'); 2 | var should = require('should'); 3 | describe('test/translate.test.js', function() { 4 | describe('valid result', function() { 5 | it('should.be.type.result String', function(done) { 6 | wt.translate('uD67wmZzhi3RFcmTkGoks2Dr', '子曰', function(err, data) { 7 | if (err) {} else { 8 | data.should.be.type('string'); 9 | } 10 | done(); 11 | }); 12 | }); 13 | }); 14 | describe('valid api err', function() { 15 | it('should.be.type.result String', function(done) { 16 | wt.translate('err api', '子曰', function(err, data) { 17 | err.should.be.an.instanceof(Object); 18 | done(); 19 | }); 20 | }); 21 | }); 22 | }); -------------------------------------------------------------------------------- /test/weather.test.js: -------------------------------------------------------------------------------- 1 | var wt = require('../index'); 2 | var should = require('should'); 3 | describe('test/weather.test.js', function() { 4 | describe('valid result', function() { 5 | it('should.be.type String', function(done) { 6 | wt.weather('uD67wmZzhi3RFcmTkGoks2Dr', '北京', function(err, data) { 7 | if (err) {} else { 8 | data.should.be.type('string'); 9 | } 10 | done(); 11 | }); 12 | }); 13 | }); 14 | describe('valid api err', function() { 15 | it('err.should.be.an.instanceof(Object) ', function(done) { 16 | wt.weather('err api', '北京', function(err, data) { 17 | err.should.be.an.instanceof(Object); 18 | done(); 19 | }); 20 | }); 21 | }); 22 | }); --------------------------------------------------------------------------------