nodejs微信开发之自动回复的实现


Posted in NodeJs onMarch 17, 2019

上一篇:接入指南

这部分是实现简单的自动回复,当然也是很大一部分功能的实现基础,这里使用了图灵机器人的接口。

效果图如下:

nodejs微信开发之自动回复的实现

当然,这个机器人的效果如何不是我能管得了的事情了,类似图灵机器人,我们还可以实现段子推送,快递查询等一系列功能,这里不一一实现了。

微信的消息处理

对于公众平台,每一次发消息相当于发出一个post请求,但是需要注意的是不管是发出的请求还是收到的回复,他的数据格式都是xml,但是nodejs本身无法处理xml,所以需要对xml数据进行处理。
仍然使用的是body-parser这个库,但是需要引入body-parser-xml:

//解析xml
app.use(bodyParser.xml({
 limit: '1MB',  // Reject payload bigger than 1 MB
 xmlParseOptions: {
  normalize: true,   // Trim whitespace inside text nodes
  normalizeTags: true, // Transform tags to lowercase
  explicitArray: false // Only put nodes in array if >1
 }
}));

这样req.body.xml就是处理好的数据了。

一般文本消息的格式如下所示:

<xml>
 <ToUserName><![CDATA[toUser]]></ToUserName>
 <FromUserName><![CDATA[fromUser]]></FromUserName>
 <CreateTime>1348831860</CreateTime>
 <MsgType><![CDATA[text]]></MsgType>
 <Content><![CDATA[this is a test]]></Content>
 <MsgId>1234567890123456</MsgId>
 </xml>

其中ToUserName是接受者的openid,FromUserName是发送者的openid,CreateTime就是一个整型的时间戳。MsgType就是消息类型,一般有文本(text),图片(image),语音(voice),视频(video),小视频(shortvideo),地理位置(location)以及链接消息(link)。下面就以文本消息为例进行编码。

router.post('/', function (req, res) {

 res.writeHead(200, {'Content-Type': 'application/xml'});

 var data = req.body.xml;
 var resMsg = '<xml>' +
  '<ToUserName><![CDATA[' + data.fromusername + ']]></ToUserName>' +
  '<FromUserName><![CDATA[' + data.tousername + ']]></FromUserName>' +
  '<CreateTime>' + parseInt(new Date().valueOf() / 1000) + '</CreateTime>' +
  '<MsgType><![CDATA[text]]></MsgType>' +
  '<Content><![CDATA['+data.content+']]></Content>' +
  '</xml>';
 res.end(resMsg);
});

只需要将header的content-type设置为xml,返回一个xml的响应,那么公众号就会相应的回复一个消息,这里回复的消息是文本格式。(mac的微信一年没更新了--)

nodejs微信开发之自动回复的实现

如上图,发送消息则会回复一个内容一样的消息,一个简单的自动回复就实现了。

图灵机器人

这个接口的使用十分简单,get请求链接,记得带上apikey的头,然后就会返回响应的内容。我这里请求使用的是nodejs request库。

const request = require('request');
const config = require('../../config');

function getTuringResponse(info) {
 if(typeof info !== 'string') {
  info = info.toString();
 }
 var options = {
  method:'GET',
  url: 'http://apis.baidu.com/turing/turing/turing?key=879a6cb3afb84dbf4fc84a1df2ab7319&info='+info,
  headers: {
   'apikey': config.turingKey
  }
 };
 return new Promise((resolve, reject) => {
  request(options, function (err, res, body) {
   if (res) {
    resolve(body);
   } else {
    reject(err);
   }
  });
 })
}

module.exports = getTuringResponse;

使用promise处理异步返回的结果,避免多次回调,记得把apikey设置为header内容。

公众号机器人

好了,上面是二者分开的讲的,如果看到这应该知道一个聊天机器人的实现是非常简单的了。就是将接口响应的内容返回给用户(?如果不是非要自己实现聊天机器人的话。。。),后台这里也就相当于一个跳板。

turingRobot.js

const request = require('request');
const config = require('../../config');

function getTuringResponse(info) {
 if(typeof info !== 'string') {
  info = info.toString();
 }
 var options = {
  method:'GET',
  url: 'http://apis.baidu.com/turing/turing/turing?key=879a6cb3afb84dbf4fc84a1df2ab7319&info='+info,
  headers: {
   'apikey': config.turingKey
  }
 };
 return new Promise((resolve, reject) => {
  request(options, function (err, res, body) {
   if (res) {
    resolve(body);
   } else {
    reject(err);
   }
  });
 })
}

module.exports = getTuringResponse;

这部分代码很简单了,就是将图灵机器人的接口响应消息返回出来。下面要做的就是将消息返回给用户,这里有一点需要注意的是对于发出的响应,该接口不能直接响应中文字符串,需要进行urlencode。

//autoReply.js
const request = require('request');

function autoReply(requestData, info) {
 switch (requestData.msgtype) {
  case 'text':
   var resMsg = '<xml>' +
    '<ToUserName><![CDATA[' + requestData.fromusername + ']]></ToUserName>' +
    '<FromUserName><![CDATA[' + requestData.tousername + ']]></FromUserName>' +
    '<CreateTime>' + parseInt(new Date().valueOf() / 1000) + '</CreateTime>' +
    '<MsgType><![CDATA[text]]></MsgType>' +
    '<Content><![CDATA['+info+']]></Content>' +
    '</xml>';
   break;
 }

 return resMsg;
}

module.exports = autoReply;

自动回复的模块,主要是返回一个xml字符串,方便发送给用户。

//weixin.js

router.post('/', function (req, res) {

 res.writeHead(200, {'Content-Type': 'application/xml'});

 var content = req.body.xml.content;

 turingRobot(encodeURI(content)).then(function (data) {
  var response = JSON.parse(data);
  var resMsg = autoReply(req.body.xml, response.text);
  res.end(resMsg);
 })
});

好,这下算是完成机器人聊天的功能了。只要将代码部署到leancloud里,就算是成功了。

github地址奉上:https://github.com/xiadd/shorthand 欢迎star

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
将nodejs打包工具整合到鼠标右键的方法
May 11 NodeJs
nodejs实现黑名单中间件设计
Jun 17 NodeJs
基于promise.js实现nodejs的promises库
Jul 06 NodeJs
nodejs教程之制作一个简单的文章发布系统
Nov 21 NodeJs
NodeJs——入门必看攻略
Jun 27 NodeJs
Nodejs 搭建简单的Web服务器详解及实例
Nov 30 NodeJs
nodejs 实现钉钉ISV接入的加密解密方法
Jan 16 NodeJs
nodejs基础知识
Feb 03 NodeJs
详谈Angular路由与Nodejs路由的区别
Mar 05 NodeJs
在Debian(Raspberry Pi)树莓派上安装NodeJS的教程详解
Sep 19 NodeJs
详解从NodeJS搭建中间层再谈前后端分离
Nov 13 NodeJs
一文秒懂nodejs中的异步编程
Jan 28 NodeJs
nodejs微信开发之接入指南
Mar 17 #NodeJs
nodejs微信开发之授权登录+获取用户信息
Mar 17 #NodeJs
详解nodejs 开发企业微信第三方应用入门教程
Mar 12 #NodeJs
详解NodeJS Https HSM双向认证实现
Mar 12 #NodeJs
NodeJs入门教程之定时器和队列
Mar 08 #NodeJs
nodejs npm错误Error:UNKNOWN:unknown error,mkdir 'D:\Develop\nodejs\node_global'at Error
Mar 02 #NodeJs
nodejs同步调用获取mysql数据时遇到的大坑
Mar 02 #NodeJs
You might like
PHP中将ip地址转成十进制数的两种实用方法
2013/08/15 PHP
windows下配置apache+php+mysql时出现问题的处理方法
2014/06/20 PHP
php构造函数的继承方法
2015/02/09 PHP
javascript入门·动态的时钟,显示完整的一些方法,新年倒计时
2007/10/01 Javascript
jquery text,radio,checkbox,select操作实现代码
2009/07/09 Javascript
使用js实现关闭js弹出层的窗口
2014/02/10 Javascript
AngularJS Bootstrap详细介绍及实例代码
2016/07/28 Javascript
js实现上传图片预览方法
2016/10/25 Javascript
Vue监听数组变化源码解析
2017/03/09 Javascript
self.attachevent is not a function的解决方法
2017/04/04 Javascript
Angular 1.x个人使用的经验小结
2017/07/19 Javascript
解决Vue中mounted钩子函数获取节点高度出错问题
2018/05/18 Javascript
vue-image-crop基于Vue的移动端图片裁剪组件示例
2018/08/28 Javascript
Vue高版本中一些新特性的使用详解
2018/09/25 Javascript
Vue中的Props(不可变状态)
2018/09/29 Javascript
Python自定义函数的创建、调用和函数的参数详解
2014/03/11 Python
Python中字符串的常见操作技巧总结
2016/07/28 Python
Python中协程用法代码详解
2018/02/10 Python
Python实现的从右到左字符串替换方法示例
2018/07/06 Python
django框架基于queryset和双下划线的跨表查询操作详解
2019/12/11 Python
Keras 中Leaky ReLU等高级激活函数的用法
2020/07/05 Python
Python读取xlsx数据生成图标代码实例
2020/08/12 Python
python 星号(*)的多种用途
2020/09/21 Python
Matlab使用Plot函数实现数据动态显示方法总结
2021/02/25 Python
浅谈HTML5 Web Worker的使用
2018/01/05 HTML / CSS
Otticanet澳大利亚:最顶尖的世界名牌眼镜, 能得到打折季的价格
2018/08/23 全球购物
ParcelABC西班牙:包裹运送和快递服务
2019/12/24 全球购物
德国珠宝和配件商店:Styleserver
2021/02/23 全球购物
东方通信股份有限公司VC面试题
2014/08/27 面试题
人事专员岗位说明书
2014/07/29 职场文书
2014幼儿园教师个人工作总结
2014/11/08 职场文书
小学五年级语文上册教学计划
2015/01/22 职场文书
工程合作意向书范本
2015/05/09 职场文书
入党培养人考察意见
2015/06/08 职场文书
2016元旦晚会主持人开场白和结束语
2015/12/03 职场文书
在CSS中映射鼠标位置并实现通过鼠标移动控制页面元素效果(实例代码)
2021/04/22 HTML / CSS