国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

NodeJS實現(xiàn)微信公眾號關(guān)注后自動回復功能

2019-11-19 16:27:33
字體:
供稿:網(wǎng)友

一 實先自動回復功能的邏輯步驟

  1 處理POST類型的控制邏輯,接收XML的數(shù)據(jù)包;

  2 解析XML數(shù)據(jù)包(獲得數(shù)據(jù)包的消息類型或者是事件類型);

  3 拼裝我們定義好的消息;

  4 包裝成XML格式;

  5 在5秒內(nèi)返回回去

二 代碼實操

  本節(jié)代碼參照上節(jié)課繼續(xù)修改和完善,目錄結(jié)構(gòu)跟之前相同,新引入的模塊raw-body使用npm install安裝一下即可,app.js啟動文件和util.js不做變動,主要修改一下generator.js文件,以及在generator.js同級目錄下新建wechat.js文件和tools.js文件。

  wechat.js文件是將前一節(jié)generator.js文件中票據(jù)部分的代碼抽離出來單獨放在一個文件中,具體代碼如下:

'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'};//利用構(gòu)造函數(shù)生成實例 完成票據(jù)存儲邏輯function weChat(opts) {  var that = this;  this.appID = opts.appID;  this.appSecret = opts.appSecret;  this.getAccessToken = opts.getAccessToken;  this.saveAccessToken = opts.saveAccessToken;  //獲取票據(jù)的方法  this.getAccessToken()    .then(function(data) {      //從靜態(tài)文件獲取票據(jù),JSON化數(shù)據(jù),如果有異常,則嘗試更新票據(jù)      try {        data = JSON.parse(data);      } catch (e) {        return that.updateAccessToken();      }      //判斷票據(jù)是否在有效期內(nèi),如果合法,向下傳遞票據(jù),如果不合法,更新票據(jù)      if (that.isValidAccessToken(data)) {        Promise.resolve(data);      } else {        return that.updateAccessToken();      }    })    //將拿到的票據(jù)信息和有效期信息存儲起來    .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) {  //進行判斷,如果票據(jù)不合法,返回false  if (!data || !data.access_token || !data.expires_in) {    return false;  }  //拿到票據(jù)和過期時間的數(shù)據(jù)  var access_token = data.access_token;  var expires_in = data.expires_in;  //獲取當前時間  var now = (new Date().getTime());  //如果當前時間小于票據(jù)過期時間,返回true,否則返回false  if (now < expires_in) {    return true;  } else {    return false;  };};//在weChat的原型鏈上增加更新票據(jù)的方法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發(fā)起請求    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;      //把新票據(jù)的有效時間賦值給data      data.expires_in = expires_in;      resolve(data);    })  })};//向外暴露weChatmodule.exports = weChat;

  generator.js文件進行精簡后,添加判斷對xml數(shù)據(jù)的格式化方法以及判斷事件,添加關(guān)注事件測試信息,具體代碼如下:

'use strict';// 引入模塊var sha1 = require('sha1');var getRawBody = require('raw-body');var weChat = require('./wechat');var tools = require('./tools');// 建立中間件函數(shù)并暴露出去module.exports = function(opts) {  //實例化weChat()函數(shù)  //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對象 去拼裝它的數(shù)據(jù) 最終拿到一個buffer的xml數(shù)據(jù)      //通過yield關(guān)鍵字 獲取到post過來的原始的XML數(shù)據(jù)      var data = yield getRawBody(this.req, {        length: this.length,        limit: '1mb',        encoding: this.charset      });      //console.log(data.toString());打印XML數(shù)據(jù)(當微信公眾號有操作的時候 終端可以看到返回的XML數(shù)據(jù))      //tools為處理XML數(shù)據(jù)的工具包 使用tools工具包的parseXMLAsync方法 把XML數(shù)據(jù)轉(zhuǎn)化成數(shù)組對象      var content = yield tools.parseXMLAsync(data);      //console.log(content);打印轉(zhuǎn)化后的數(shù)組對象      //格式化content數(shù)據(jù)為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();          //設(shè)置回復狀態(tài)是200          that.status = 200;          //設(shè)置回復的類型是xml格式          that.type = 'application/xml';          //設(shè)置回復的主體          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數(shù)據(jù)的工具文件:

'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進行循環(huán)遍歷    for (var i = 0; i < keys.length; i++) {      //拿到每個key對應(yīng)的value值      var item = result[keys[i]];      //拿到key      var key = keys[i];      //判斷item是否為數(shù)組或者長度是否為0      if (!(item instanceof Array) || item.length === 0) {        //如果item不是數(shù)組或者長度為0 則跳過繼續(xù)向下解析        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 則說明它是一個數(shù)組      else {        //把message的key設(shè)置為空數(shù)組        message[key] = [];        //對數(shù)組進行遍歷        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;

  完成這節(jié)的代碼后,當關(guān)注微信測試公眾號的時候,會自動回復『你好,同學!』的提示信息。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 新宾| 黄陵县| 辽阳市| 卓资县| 柳林县| 江山市| 屏边| 玉屏| 凤冈县| 西昌市| 从化市| 泰来县| 科技| 枣强县| 冷水江市| 江华| 汨罗市| 五常市| 泗水县| 兴文县| 榆中县| 莎车县| 吴忠市| 科技| 新郑市| 淮滨县| 衢州市| 阳江市| 乌海市| 青阳县| 聂荣县| 财经| 岫岩| 丰台区| 南投市| 集贤县| 潞西市| 西峡县| 金昌市| 沙洋县| 密云县|