您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關NodeJS怎么實現微信公眾號關注后自動回復功能的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
1、js屬于一種解釋性腳本語言;2、在絕大多數瀏覽器的支持下,js可以在多種平臺下運行,擁有著跨平臺特性;3、js屬于一種弱類型腳本語言,對使用的數據類型未做出嚴格的要求,能夠進行類型轉換,簡單又容易上手;4、js語言安全性高,只能通過瀏覽器實現信息瀏覽或動態交互,從而有效地防止數據的丟失;5、基于對象的腳本語言,js不僅可以創建對象,也能使用現有的對象。
一 實先自動回復功能的邏輯步驟
1 處理POST類型的控制邏輯,接收XML的數據包;
2 解析XML數據包(獲得數據包的消息類型或者是事件類型);
3 拼裝我們定義好的消息;
4 包裝成XML格式;
5 在5秒內返回回去
二 代碼實操
本節代碼參照上節課繼續修改和完善,目錄結構跟之前相同,新引入的模塊raw-body使用npm install安裝一下即可,app.js啟動文件和util.js不做變動,主要修改一下generator.js文件,以及在generator.js同級目錄下新建wechat.js文件和tools.js文件。
wechat.js文件是將前一節generator.js文件中票據部分的代碼抽離出來單獨放在一個文件中,具體代碼如下:
'use strict'; // 引入模塊 var Promise = require('bluebird'); var request = Promise.promisify(require('request')); //增加url配置項 var prefix = 'https://api.weixin.qq.com/cgi-bin/'; var api = { accessToken: prefix + 'token?grant_type=client_credential' }; //利用構造函數生成實例 完成票據存儲邏輯 function weChat(opts) { var that = this; this.appID = opts.appID; this.appSecret = opts.appSecret; this.getAccessToken = opts.getAccessToken; this.saveAccessToken = opts.saveAccessToken; //獲取票據的方法 this.getAccessToken() .then(function(data) { //從靜態文件獲取票據,JSON化數據,如果有異常,則嘗試更新票據 try { data = JSON.parse(data); } catch (e) { return that.updateAccessToken(); } //判斷票據是否在有效期內,如果合法,向下傳遞票據,如果不合法,更新票據 if (that.isValidAccessToken(data)) { Promise.resolve(data); } else { return that.updateAccessToken(); } }) //將拿到的票據信息和有效期信息存儲起來 .then(function(data) { //console.log(data); that.access_token = data.access_token; that.expires_in = data.expires_in; that.saveAccessToken(data); }) }; //在weChat的原型鏈上增加驗證有效期的方法 weChat.prototype.isValidAccessToken = function(data) { //進行判斷,如果票據不合法,返回false if (!data || !data.access_token || !data.expires_in) { return false; } //拿到票據和過期時間的數據 var access_token = data.access_token; var expires_in = data.expires_in; //獲取當前時間 var now = (new Date().getTime()); //如果當前時間小于票據過期時間,返回true,否則返回false if (now < expires_in) { return true; } else { return false; }; }; //在weChat的原型鏈上增加更新票據的方法 weChat.prototype.updateAccessToken = function() { var appID = this.appID; var appSecret = this.appSecret; var url = api.accessToken + '&appid=' + appID + '&secret=' + appSecret; return new Promise(function(resolve, reject) { //使用request發起請求 request({ url: url, json: true }).then(function(response) { var data = response.body; var now = (new Date().getTime()); var expires_in = now + (data.expires_in - 20) * 1000; //把新票據的有效時間賦值給data data.expires_in = expires_in; resolve(data); }) }) }; //向外暴露weChat module.exports = weChat;
generator.js文件進行精簡后,添加判斷對xml數據的格式化方法以及判斷事件,添加關注事件測試信息,具體代碼如下:
'use strict'; // 引入模塊 var sha1 = require('sha1'); var getRawBody = require('raw-body'); var weChat = require('./wechat'); var tools = require('./tools'); // 建立中間件函數并暴露出去 module.exports = function(opts) { //實例化weChat()函數 //var wechat = new weChat(opts); return function*(next) { //console.log(this.query); 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); //使用this.method對請求方法進行判斷 if (this.method === 'GET') { // 如果是get請求 判斷加密后的值是否等于簽名值 if (sha === signature) { this.body = echostr + ''; } else { this.body = 'wrong'; }; } else if (this.method === 'POST') { //如果是post請求 也是先判斷簽名是否合法 如果不合法 直接返回wrong if (sha !== signature) { this.body = 'wrong'; return false; }; //通過raw-body模塊 可以把把this上的request對象 也就是http模塊中的request對象 去拼裝它的數據 最終拿到一個buffer的xml數據 //通過yield關鍵字 獲取到post過來的原始的XML數據 var data = yield getRawBody(this.req, { length: this.length, limit: '1mb', encoding: this.charset }); //console.log(data.toString());打印XML數據(當微信公眾號有操作的時候 終端可以看到返回的XML數據) //tools為處理XML數據的工具包 使用tools工具包的parseXMLAsync方法 把XML數據轉化成數組對象 var content = yield tools.parseXMLAsync(data); //console.log(content);打印轉化后的數組對象 //格式化content數據為json對象 var message = tools.formatMessage(content.xml); console.log(message); //打印message //判斷message的MsgType 如果是event 則是一個事件 if (message.MsgType === 'event') { //如果是訂閱事件 if (message.Event === 'subscribe') { //獲取當前時間戳 var now = new Date().getTime(); //設置回復狀態是200 that.status = 200; //設置回復的類型是xml格式 that.type = 'application/xml'; //設置回復的主體 that.body = '<xml>' + '<ToUserName><![CDATA[' + message.FromUserName + ']]></ToUserName>' + '<FromUserName><![CDATA[' + message.ToUserName + ']]></FromUserName>' + '<CreateTime>' + now + '</CreateTime>' + '<MsgType><![CDATA[text]]></MsgType>' + '<Content><![CDATA[你好,同學!]]></Content>' + '</xml>'; return; } } } } };
tools.js是處理XML數據的工具文件:
'use strict'; //引入模塊 var xml2js = require('xml2js'); var Promise = require('bluebird'); //導出解析XML的方法 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); }; }); }); }; //因為value值可能是嵌套多層的 所以先對value值進行遍歷 function formatMessage(result) { //聲明空對象message var message = {}; //對result類型進行判斷 if (typeof result === 'object') { //如果是object類型 通過Object.keys()方法拿到result所有的key 并存入keys變量中 var keys = Object.keys(result); //對keys進行循環遍歷 for (var i = 0; i < keys.length; i++) { //拿到每個key對應的value值 var item = result[keys[i]]; //拿到key var key = keys[i]; //判斷item是否為數組或者長度是否為0 if (!(item instanceof Array) || item.length === 0) { //如果item不是數組或者長度為0 則跳過繼續向下解析 continue; } //如果長度為1 if (item.length === 1) { //拿到value值存入val變量 var val = item[0]; //判斷val是否為對象 if (typeof val === 'object') { //如果val為對象 則進一步進行遍歷 message[key] = formatMessage(val); } else { //如果不是對象 就把值賦給當前的key放入message里 并去除收尾空格 message[key] = (val || '').trim(); } } //如果item的長度既不是0也不是1 則說明它是一個數組 else { //把message的key設置為空數組 message[key] = []; //對數組進行遍歷 for (var j = 0, k = item.length; j < k; j++) { message[key].push(formatMessage(item[j])); } } } } return message; } exports.formatMessage = function(xml) { return new Promise(function(resolve, reject) { xml2js.parseString(xml, { trim: true }, function(err, content) { if (err) { reject(err); } else { resolve(content); }; }); }); }; exports.formatMessage = formatMessage;
完成這節的代碼后,當關注微信測試公眾號的時候,會自動回復『你好,同學!』的提示信息。
感謝各位的閱讀!關于“NodeJS怎么實現微信公眾號關注后自動回復功能”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。