├── node_js ├── routes └── test │ ├── login │ └── test.coffee ├── .travis.yml ├── router.coffee ├── test ├── ym.todo ├── mocha.opts.sample ├── mocha.opts ├── _init.js └── weixin │ └── weixin.coffee ├── config └── config.coffee ├── .gitignore ├── index.js ├── middlewares ├── cors.coffee └── stylus.coffee ├── README.md ├── composer.json ├── server.coffee ├── package.json ├── app.coffee └── helpers └── wx ├── wx.coffee └── md5.js /node_js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /routes/test/login: -------------------------------------------------------------------------------- 1 | { 2 | "ret": "0", 3 | "msg": "ok" 4 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.8 4 | - 1.0 -------------------------------------------------------------------------------- /router.coffee: -------------------------------------------------------------------------------- 1 | app = require './app' 2 | require('./routes/test/test')(app) -------------------------------------------------------------------------------- /test/ym.todo: -------------------------------------------------------------------------------- 1 | ✔ 今天我要做微信登录存储功能 @done (13-03-01 17:35) 2 | ✔ plaintask -------------------------------------------------------------------------------- /test/mocha.opts.sample: -------------------------------------------------------------------------------- 1 | --recursive 2 | --compilers coffee:coffee-script 3 | -r test/_init.js -------------------------------------------------------------------------------- /config/config.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | wx : 3 | user : '微信公众平台账号' 4 | pwd : '微信公众平台密码' 5 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --recursive 2 | --compilers coffee:coffee-script 3 | -r test/_init.js 4 | -R list 5 | -g @ym -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | config/config.coffee 4 | public/uploads/ 5 | test/mocha.opts 6 | 7 | *.sublime-project 8 | *.sublime-workspace 9 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | global.__basename = __dirname; 2 | global.is_reading = new Array(); 3 | require('coffee-script'); 4 | process.env.TZ = 'PRC'; 5 | module.exports = require('./server'); 6 | -------------------------------------------------------------------------------- /test/_init.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = 'test'; 2 | 3 | var app = require('..') 4 | , chai = require('chai') 5 | , request = require('supertest'); 6 | 7 | global.should = chai.should(); 8 | global.request = request(app); 9 | -------------------------------------------------------------------------------- /middlewares/cors.coffee: -------------------------------------------------------------------------------- 1 | module.exports = (req, res, next) -> 2 | res.header 'Access-Control-Allow-Origin', '*' 3 | res.header 'Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS' 4 | res.header 'Access-Control-Allow-Headers', 'Content-Type' 5 | next() -------------------------------------------------------------------------------- /middlewares/stylus.coffee: -------------------------------------------------------------------------------- 1 | stylus = require 'stylus' 2 | nib = require 'nib' 3 | 4 | module.exports = stylus.middleware 5 | src: __dirname + '/../public' 6 | compile: (str, path) -> 7 | stylus(str) 8 | .set('filename', path) 9 | .set('compress', true) 10 | .use(nib()) -------------------------------------------------------------------------------- /test/weixin/weixin.coffee: -------------------------------------------------------------------------------- 1 | describe 'product@account', -> 2 | 3 | str = 'hello ' 4 | 5 | # test to before 6 | before () -> 7 | str+='world' 8 | 9 | it 'should test my mocha with projects', (done) -> 10 | str.should.equal 'hello world' 11 | done() 12 | 13 | describe 'product@ym', -> 14 | 15 | str = 'hello ' 16 | 17 | # test to before 18 | before () -> 19 | str+='world' 20 | 21 | it 'should test my mocha with projects', (done) -> 22 | str.should.equal 'hello world' 23 | done() -------------------------------------------------------------------------------- /routes/test/test.coffee: -------------------------------------------------------------------------------- 1 | wx = require __basename + '/helpers/wx/wx' 2 | http = require 'http' 3 | 4 | module.exports = (app) -> 5 | 6 | app.post '/wx/login', (req, res) -> 7 | msg = req.body.msg 8 | fakeid = req.body.fakeid 9 | wx.login req, (err, results) -> 10 | req.session.is_login = results if results 11 | res.json err if err 12 | data = 13 | msg : msg 14 | fakeid : fakeid 15 | cookie : results.cookie 16 | token : results.token 17 | 18 | wx.sender req, data, (err, results) -> 19 | res.json err if err 20 | res.json results -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Latest Stable Version](https://poser.pugx.org/ym1623/node_wx/version.png)](https://packagist.org/ym1623/node_wx) [![Total Downloads](https://poser.pugx.org/ym1623/node_wx/d/total.png)](https://packagist.org/packages/ym1623/node_wx) [![Build Status](https://travis-ci.org/ym1623/node_wx.png?branch=master)](https://travis-ci.org/ym1623/node_wx) [![Dependencies Status](https://depending.in/ym1623/node_wx.png)](http://depending.in/ym1623/node_wx)[![Dependency Status](https://david-dm.org/ym1623/node_wx.png)](https://david-dm.org/ym1623/node_wx) 2 | # API 3 | # @author: ym 4 | 此項目為微信API核心RESTFUL API. 5 | 项目主页介绍:http://ym1623.github.io/node_wx -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ym1623/node_wx", 3 | "type": "library", 4 | "description": "running nodejs > 0.8", 5 | "keywords": ["node_wx","wx_server"], 6 | "version": "2.1.2", 7 | "homepage": "https://github.com/ym1623/node_wx", 8 | "license": "MIT", 9 | "authors": [ 10 | { 11 | "name": "ym1623", 12 | "email": "yuem1623@gmail.com", 13 | "homepage": "http://ym1623.com", 14 | "role": "Master" 15 | } 16 | ], 17 | "require": { 18 | "nodejs": ">=0.8" 19 | }, 20 | "autoload": { 21 | "psr-0": { 22 | "Monolog": "src" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /server.coffee: -------------------------------------------------------------------------------- 1 | app = require './app' 2 | optimist = require 'optimist' 3 | http = require 'http' 4 | config = require './config/config' 5 | 6 | argv = optimist 7 | .options 'p', 8 | alias: 'port' 9 | default: 8080 10 | .options 'f', 11 | alias: 'force' 12 | .argv 13 | 14 | # 15 | # Server Listening 16 | # 17 | 18 | module.exports = server = http.createServer app 19 | 20 | if process.env.NODE_ENV isnt 'test' or argv.force 21 | server.listen argv.port, -> 22 | console.log "Express server listening on port %d in %s mode", argv.port, app.settings.env 23 | 24 | # 25 | # Router Setting 26 | # 27 | 28 | require './router' 29 | 30 | # 31 | # Error handler 32 | # 33 | 34 | process.on 'uncaughtException', console.dir 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-api", 3 | "version": "0.0.1", 4 | "private": true, 5 | "dependencies": { 6 | "coffee-script": "~1.3.3", 7 | "underscore": "~1.3.3", 8 | "async": "~0.1.22", 9 | "jade": "~0.27.5", 10 | "stylus": "~0.29.0", 11 | "nib": "~0.8.2", 12 | "mysql": "~2.0.0-alpha5", 13 | "express-namespace": "~0.1.1", 14 | "underscore.string": "~2.3.0", 15 | "express-resource": "~1.0.0", 16 | "express": "~3.0.0", 17 | "superagent": "~0.9.7", 18 | "request": "~2.12.0", 19 | "optimist": "~0.3.5", 20 | "readof": "~0.9.5" 21 | }, 22 | "devDependencies": { 23 | "mocha": "~1.3.2", 24 | "chai": "~1.1.1", 25 | "supertest": "~0.5.1" 26 | }, 27 | "scripts": { 28 | "test": "mocha" 29 | }, 30 | "main": "index.js", 31 | "repository": { 32 | "type": "git", 33 | "url": "" 34 | }, 35 | "license": "MIT" 36 | } 37 | -------------------------------------------------------------------------------- /app.coffee: -------------------------------------------------------------------------------- 1 | express = require 'express' 2 | require 'express-resource' 3 | require 'express-namespace' 4 | 5 | config = require './config/config' 6 | cors = require './middlewares/cors' 7 | stylus = require './middlewares/stylus' 8 | session_expires = 72000000 9 | 10 | module.exports = app = express() 11 | 12 | 13 | # 14 | # App Setting 15 | # 16 | 17 | app.configure -> 18 | app.set 'view engine', 'jade' 19 | app.set 'views', __dirname + '/views' 20 | 21 | app.use express.bodyParser() 22 | app.use express.methodOverride() 23 | app.use express.cookieParser() 24 | app.use express.cookieSession 25 | secret: 'this is a screen' 26 | cookie: 27 | expires : new Date(Date.now() + session_expires) 28 | maxAge : session_expires 29 | app.use cors 30 | app.use app.router 31 | app.use stylus 32 | app.use express.static __dirname + '/public' 33 | 34 | app.configure 'development', -> 35 | app.use express.errorHandler 36 | dumpExceptions: true 37 | showStack: true 38 | 39 | app.configure 'production', -> 40 | app.use express.errorHandler() 41 | -------------------------------------------------------------------------------- /helpers/wx/wx.coffee: -------------------------------------------------------------------------------- 1 | request = require 'superagent' 2 | require __basename + '/helpers/wx/md5' 3 | config = require __basename + '/config/config' 4 | http = require 'http' 5 | 6 | module.exports = 7 | login: (req, fn) -> 8 | # return fn null, req.session.is_login if req.session.is_login 9 | wx_usr = config.wx.user 10 | wx_pwd = md5 config.wx.pwd.substr(0, 16) 11 | request 12 | .post('https://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN') 13 | .type('form') 14 | .set('Referer', 'https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response&lang=zh_CN') 15 | .send( 16 | username: wx_usr 17 | pwd: wx_pwd 18 | imgcode : '' 19 | f : 'json' 20 | ) 21 | .end (res) -> 22 | token = res.body.ErrMsg.match(/token=(\d+)/)[1] 23 | cookie = '' 24 | if res.header['set-cookie'] 25 | for rs in res.header['set-cookie'] 26 | cookie += rs.replace(/HttpOnly/g, '') 27 | data = 28 | token : token 29 | cookie : cookie 30 | fn null, data 31 | 32 | sender: (req, options, fn) -> 33 | msg = options.msg 34 | fakeid = options.fakeid 35 | token = options.token 36 | 37 | unless msg 38 | fn error: 'missing msg' 39 | return 40 | 41 | unless fakeid 42 | fn error: 'missing fakeid' 43 | return 44 | 45 | unless token 46 | fn error : 'missing access_token' 47 | 48 | postParams = 49 | type: 1 50 | content: msg 51 | error: false 52 | tofakeid : fakeid 53 | token : token 54 | ajax : 1 55 | 56 | 57 | request 58 | .post('https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response&lang=zh_CN') 59 | .type('form') 60 | .send(postParams) 61 | .set('Cookie', options.cookie) 62 | .set('Referer', 'https://mp.weixin.qq.com/cgi-bin/singlemsgpage') 63 | .end (res) -> 64 | results = JSON.parse res.text 65 | delete req.session.is_login if results['ret'] is '-20000' 66 | fn null, results 67 | 68 | getFriendPage: (req, results, fn) -> 69 | request 70 | .get('https://mp.weixin.qq.com/cgi-bin/contactmanagepage?token='+results.token+'&t=wxm-friend&lang=zh_CN&pagesize=10000&pageidx=0&type=0&groupid=0') 71 | .set('Cookie', results.cookie) 72 | .end (res) -> 73 | console.log res.text 74 | rs = res.text.replace(/document.location.hostname.match.*\[0\]/g, '"'+req.host+'"') 75 | results = rs.match(/