200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 如何使用NodeJS来实现微信公众号关注后自动回复功能的详细介绍

如何使用NodeJS来实现微信公众号关注后自动回复功能的详细介绍

时间:2024-04-17 14:17:28

相关推荐

如何使用NodeJS来实现微信公众号关注后自动回复功能的详细介绍

web前端|js教程

NodeJS,微信公众号,自动回复功能

web前端-js教程

这篇文章主要为大家详细介绍了NodeJS实现微信公众号关注后自动回复功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

简单远控源码,尤雨溪推荐vscode,ubuntu 递归权限,项目发布至tomcat,python 爬虫课,php退出程序,秀山智能化seo推广,网站留言板源码php,手游网模板lzw

一 实先自动回复功能的逻辑步骤

php装逼神器完整版源码,vscode怎样js提示,ubuntu切换dash,tomcat怎么制作网页,爬虫揽客,php写入缓存文件,河北长沙seo优化服务,好评网站源码,投票说明模板lzw

1 处理POST类型的控制逻辑,接收XML的数据包;

wifi认证 php源码,ubuntu快速p图,用tomcat打开本地页面,用爬虫捞数据,php数字转换成符串,seo 挂机 windowlzw

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(luebird);var request = Promise.promisify(require( equest));//增加url配置项var prefix = https://api./cgi-bin/;var api = { accessToken: prefix + oken?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;//把新票据的有效时间赋值给datadata.expires_in = expires_in;resolve(data); }) })};//向外暴露weChatmodule.exports = weChat;

generator.js文件进行精简后,添加判断对xml数据的格式化方法以及判断事件,添加关注事件测试信息,具体代码如下:

use strict;// 引入模块var sha1 = require(sha1);var getRawBody = require( aw-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请求 也是先判断签名是否合法 如果不合法 直接返回wrongif (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();//设置回复状态是200that.status = 200;//设置回复的类型是xml格式that.type = application/xml;//设置回复的主体that.body = \ + <![CDATA[ + message.FromUserName + ]]> + <![CDATA[ + message.ToUserName + ]]> + \ + now + \ + <![CDATA[text]]> + <![CDATA[你好,同学!]]> + \;return; }} } }};

tools.js是处理XML数据的工具文件:

use strict;//引入模块var xml2js = require(xml2js);var Promise = require(luebird);//导出解析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]];//拿到keyvar key = keys[i];//判断item是否为数组或者长度是否为0if (!(item instanceof Array) || item.length === 0) { //如果item不是数组或者长度为0 则跳过继续向下解析 continue;}//如果长度为1if (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;

完成这节的代码后,当关注微信测试公众号的时候,会自动回复『你好,同学!』的提示信息。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。