微信公衆號有個規則,一旦開啓了開發者模式,其餘的常規功能就都必須經過接口調用完成。好比說自定義菜單功能,必須經過發送post請求的方式生成。本章就經過關注到取消關注的整個過程來談一談nodejs是怎麼樣與微信交互的。這些功能的入口就是你在測試公衆號裏面填寫的URL(如下用/login/wechat代替)。javascript
掃碼關注微信公衆號後,微信會調用你的接口/login/wechat,而且附帶一段xml信息,首先你須要獲取一些簽名,經過加密、排序比對是否與你填寫的TOKEN一致,若是一致則進行xml的解析。node解析xml時必須先引用模塊。因此,先引入xml解析模塊java
//xml解析模塊 var XMLJS = require('xml2js'); //解析,將xml解析爲json var parser = new XMLJS.Parser(); //重組,將json重組爲xml var builder = new XMLJS.Builder();
經過req的監聽data,來獲取微信發送過來的xml包。如下是某個新用戶關注公衆號後微信向你的後臺接口(上一篇中提到的/yourapi)發送的xml包數據,通過解析後,他的結構以下:node
tousername:收信人【此處爲公衆微信號】git
fromusername:發信人【此處爲用戶openid】github
createTime:發送時間數據庫
msgtype:消息類型【event(響應事件)、text(推送消息)、image(推送圖文消息)等】json
event:消息名稱【此處爲關注】設計模式
eventkey:自定義的key,在設置網頁時能夠自定義後文中會講到api
以上就是當一個用戶關注後微信往你接口發送的數據包。上面對咱們有用的是fromusername,即關注人的openid,咱們在關注時獲取了用戶的該openid後能夠經過微信提供的特定接口(https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN)獲取用戶的頭像,性別,暱稱等信息,爲你的app創建一個可靠的資料庫。微信
//微信事件推送的入口 app.post('/yourapi', function(req, res, next) { //獲取參數 var query = req.query; //簽名 var signature = query.signature; //輸出的字符,你填寫的TOKEN var echostr = query.echostr; //時間戳 var timestamp = query['timestamp']; //隨機字符串 var nonce = query.nonce; var oriArray = new Array(); oriArray[0] = nonce; oriArray[1] = timestamp; oriArray[2] = appConfig.token; //排序參數 oriArray.sort(); var original = oriArray[0]+oriArray[1]+oriArray[2]; //加密 var scyptoString = sha1(original); //判斷是否與你填寫TOKEN相等 if (signature == scyptoString) { //獲取xml數據 req.on("data", function(data) { //將xml解析 parser.parseString(data.toString(), function(err, result) { var body = result.xml; var messageType = body.MsgType[0]; //用戶點擊菜單響應事件 if(messageType === 'event') { var eventName = body.Event[0]; (EventFunction[eventName]||function(){})(body, req, res); //自動回覆消息 }else if(messageType === 'text') { EventFunction.responseNews(body, res); //第一次填寫URL時確認接口是否有效 }else { res.send(echostr); } }); }); } else { //認證失敗,非法操做 res.send("Bad Token!"); } }); //微信客戶端各種回調用接口 var EventFunction = { //關注 subscribe: function(result, req, res) { //存入openid 經過微信的接口獲取用戶的信息同時存入數據庫。 }, //註銷 unsubscribe: function(openid, req, res) { //刪除對應id }, //打開某個網頁 VIEW: function() { //根據需求,處理不一樣的業務 }, //自動回覆 responseNews: function(body, res) { //組裝微信須要的json var xml = {xml: { ToUserName: body.FromUserName, FromUserName: body.ToUserName, CreateTime: + new Date(), MsgType: 'text', Content: '編輯@+您想說的話,咱們能夠收到' }}; var reciviMessage = body.Content[0] if(/^\@.*/.test(reciviMessage)) { xml.xml.Content = '已經收到您的建議,會及時處理!' }
//將json轉爲xml xml = builder.buildObject(xml);
//發送給微信 res.send(xml); } }
此處,適合採用JS設計模式中的策略模式,在subscribe方法裏面寫上你本身的業務,經過發送帶openid參數的請求,能夠在用戶關注微信號的時候將其幾本資料存入數據庫,而且創建會話。這樣在用戶接下來打開你的網頁的時候就無需再次認證,只須要比對openid而後查詢數據庫就好了。