温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

NodeJS怎么实现微信公众号关注后自动回复功能

发布时间:2021-04-23 11:49:46 来源:亿速云 阅读:319 作者:小新 栏目:web开发

这篇文章给大家分享的是有关NodeJS怎么实现微信公众号关注后自动回复功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

js有什么特点

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怎么实现微信公众号关注后自动回复功能”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI