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

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

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

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 = '' +

'' +

'' +

'' + now + '' +

'' +

'' +

'';

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;

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值