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

首頁 > 開發 > JS > 正文

NodeJS實現微信公眾號關注后自動回復功能

2024-05-06 16:37:35
字體:
來源:轉載
供稿:網友

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

  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);    })  })};//向外暴露weChatmodule.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;

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 黄骅市| 镇雄县| 霍州市| 友谊县| 连云港市| 饶阳县| 华蓥市| 安岳县| 裕民县| 凤冈县| 阳山县| 绥棱县| 隆林| 昭苏县| 天峨县| 石城县| 辽宁省| 灵武市| 昆山市| 湖南省| 图木舒克市| 临汾市| 依兰县| 临朐县| 普定县| 苍溪县| 綦江县| 衡阳市| 蒲江县| 晋江市| 丹东市| 马公市| 邢台市| 宁陕县| 肥城市| 大关县| 汉寿县| 调兵山市| 海丰县| 阳信县| 陈巴尔虎旗|