g.js
'use strict' var sha1 = require('sha1') var getRawBody = require('raw-body') var Wechat = require('./wechat') var util = require('./util') module.exports = function(opts,handler){ var wechat = new Wechat(opts) return function* (next){ var that = this var token = opts.token var signature = this.query.signature var nonce = this.query.nonce var timestamp = this.query.timestamp var echostr = this.query.echostr var str = [token,timestamp,nonce].sort().join('') var sha = sha1(str) if(this.method ==='GET'){ if (sha === signature) { this.body = echostr+'' }else{ this.body = 'wrong' } } else if(this.method === 'POST') { if (sha !== signature) { this.body = 'wrong' return false } var data = yield getRawBody(this.req,{ length:this.length, limit:'1mb', encoding:this.charset }) //console.log(data.toString()) var content = yield util.parseXMLAsync(data) console.log(content) var message = util.formatMessage(content.xml) console.log(message) this.weixin = message yield handler.call(this,next) wechat.reply.call(this) } } }
util.js
'use strict'var xml2js = require('xml2js')var Promise = require('bluebird')var tpl =require('./tpl')exports.parseXMLAsync = function(xml){ return new Promise(function(resolve,reject){ xml2js.parseString(xml,{trim:true},function(err,content){ if(err) reject(err) else resolve(content) }) })} function formatMessage(result){ var message = {} if(typeof result === 'object'){ var keys = Object.keys(result) for(var i = 0; i < keys.length;i++){ var item = result[keys[i]] var key = keys[i] if(!(item instanceof Array)|| item.length === 0){ continue } if(item.length === 1){ var val = item[0] if(typeof val === 'object'){ message[key] = formatMessage(val) }else{ message[key] = (val ||'').trim() } } else{ message[key] = [] for(var j = 0,k = item.length; j < k; j++){ message[key].push(formatMessage(item[j])) } } } } return message }exports.formatMessage = formatMessageexports.tpl = function(content,message){ var info = {} var type = 'text' var fromUserName = message.FromUserName var toUserName = message.ToUserName if(Array.isArray(content)){ type = 'news' } type = content.type||type info.content = content info.createTime = new Date().getTime() info.msgType = type info.toUserName = fromUserName info.fromUserName = toUserName return tpl.compiled(info)}