WeChat公式アカウントフォロー後の自動返信機能をNodeJSを使って実装する方法を詳しく紹介

黄舟
リリース: 2017-05-31 10:16:45
オリジナル
1834 人が閲覧しました

この記事では、主に WeChat 公開アカウントをフォローした後に自動返信機能を実装するための NodeJS を詳しく紹介します。興味のある友達は、まず自動返信機能のロジックを参照してください。 POST タイプの制御ロジックを処理し、

XML

データ パケットを受信します。 2 XML データ パケットを解析します (データ パケットのメッセージ タイプまたは event タイプを取得します)。

4 XML 形式に圧縮する; 5 5 秒以内に返す

2 番目のコードの練習

このセクションのコードは、前のレッスンに基づいて引き続き変更および改善されます。

ディレクトリ構造

は同じです。以前と同様に、新しいインポートされたモジュール raw-body は、npm inst

all

を使用してインストールできます。app.js スタートアップ ファイルと util.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 + &#39;&appid=&#39; + appID + &#39;&secret=&#39; + 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 データに判定を追加するメソッドと判定イベントを整形し、アテンションイベントのテスト情報を追加します。具体的なコードは次のとおりです:

&#39;use strict&#39;;
// 引入模块
var sha1 = require(&#39;sha1&#39;);
var getRawBody = require(&#39;raw-body&#39;);
var weChat = require(&#39;./wechat&#39;);
var tools = require(&#39;./tools&#39;);

// 建立中间件函数并暴露出去
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(&#39;&#39;);
    // 进行加密
    var sha = sha1(str);
    //使用this.method对请求方法进行判断
    if (this.method === &#39;GET&#39;) {
      // 如果是get请求 判断加密后的值是否等于签名值
      if (sha === signature) {
        this.body = echostr + &#39;&#39;;
      } else {
        this.body = &#39;wrong&#39;;
      };
    } else if (this.method === &#39;POST&#39;) {
      //如果是post请求 也是先判断签名是否合法 如果不合法 直接返回wrong
      if (sha !== signature) {
        this.body = &#39;wrong&#39;;
        return false;
      };
      //通过raw-body模块 可以把把this上的request对象 也就是http模块中的request对象 去拼装它的数据 最终拿到一个buffer的xml数据
      //通过yield关键字 获取到post过来的原始的XML数据
      var data = yield getRawBody(this.req, {
        length: this.length,
        limit: &#39;1mb&#39;,
        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 === &#39;event&#39;) {
        //如果是订阅事件
        if (message.Event === &#39;subscribe&#39;) {
          //获取当前时间戳
          var now = new Date().getTime();
          //设置回复状态是200
          that.status = 200;
          //设置回复的类型是xml格式
          that.type = &#39;application/xml&#39;;
          //设置回复的主体
          that.body = &#39;<xml>&#39; +
            &#39;<ToUserName><![CDATA[&#39; + message.FromUserName + &#39;]]></ToUserName>&#39; +
            &#39;<FromUserName><![CDATA[&#39; + message.ToUserName + &#39;]]></FromUserName>&#39; +
            &#39;<CreateTime>&#39; + now + &#39;</CreateTime>&#39; +
            &#39;<MsgType><![CDATA[text]]></MsgType>&#39; +
            &#39;<Content><![CDATA[你好,同学!]]></Content>&#39; +
            &#39;</xml>&#39;;
          return;
        }
      }
    }

  }
};
ログイン後にコピー
tools.js は XML データを処理するためのツール ファイルです:
&#39;use strict&#39;;
//引入模块
var xml2js = require(&#39;xml2js&#39;);
var Promise = require(&#39;bluebird&#39;);
//导出解析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 === &#39;object&#39;) {
    //如果是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 === &#39;object&#39;) {
          //如果val为对象 则进一步进行遍历
          message[key] = formatMessage(val);
        } else {
          //如果不是对象 就把值赋给当前的key放入message里 并去除收尾空格
          message[key] = (val || &#39;&#39;).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;
ログイン後にコピー
完了後このセクションのコードは、WeChat テスト公開アカウントをフォローすると、自動的に「こんにちは、クラスメート!」と返信します。 』というプロンプトメッセージ。

以上がWeChat公式アカウントフォロー後の自動返信機能をNodeJSを使って実装する方法を詳しく紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート