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极简入门教程(三):进程
Oct 27 NodeJs
nodejs开发环境配置与使用
Nov 17 NodeJs
解决nodejs中使用http请求返回值为html时乱码的问题
Feb 18 NodeJs
NodeJS学习笔记之Module的简介
Mar 24 NodeJs
详解nodejs微信公众号开发——1.接入微信公众号
Apr 10 NodeJs
基于nodejs 的多页面爬虫实例代码
May 31 NodeJs
浅谈nodejs中的类定义和继承的套路
Jul 26 NodeJs
NodeJS安装图文教程
Apr 19 NodeJs
Nodejs处理异常操作示例
Dec 25 NodeJs
nodejs基础之多进程实例详解
Dec 27 NodeJs
nodejs中request库使用HTTPS代理的方法
Apr 30 NodeJs
使用nodejs实现JSON文件自动转Excel的工具(推荐)
Jun 24 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
为什么《星际争霸》是测试人工智能的理想战场
2019/12/03 星际争霸
PHP仿盗链代码
2012/06/03 PHP
PHP 面向对象详解
2012/09/13 PHP
php实现获取局域网所有用户的电脑IP和主机名、及mac地址完整实例
2014/07/18 PHP
PHP动态生成指定大小随机图片的方法
2016/03/25 PHP
PHP的swoole扩展安装方法详细教程
2016/05/18 PHP
解决PHP程序运行时:Fatal error: Maximum execution time of 30 seconds exceeded in的错误提示
2016/11/25 PHP
安装PHP扩展时解压官方 tgz 文件后没有configure文件无法进行配置编译的问题
2020/08/26 PHP
一款JavaScript压缩工具:X2JSCompactor
2007/06/13 Javascript
使用FlexiGrid实现Extjs表格效果方法分享
2014/12/16 Javascript
纯JS实现旋转图片3D展示效果
2015/04/12 Javascript
MVC Ajax Helper或Jquery异步加载部分视图
2015/11/29 Javascript
javascript瀑布流布局实现方法详解
2016/02/17 Javascript
JS与jQuery实现子窗口获取父窗口元素值的方法
2017/04/17 jQuery
JS实现为动态创建的元素添加事件操作示例
2018/03/17 Javascript
使用JavaScript破解web
2018/09/28 Javascript
详解vue引入子组件方法
2019/02/12 Javascript
vue如何获取自定义元素属性参数值的方法
2019/05/14 Javascript
如何利用nodejs自动定时发送邮件提醒(超实用)
2020/12/01 NodeJs
[06:25]第二届DOTA2亚洲邀请赛主赛事第二天比赛集锦.mp4
2017/04/03 DOTA
python机器学习理论与实战(二)决策树
2018/01/19 Python
Python中数组,列表:冒号的灵活用法介绍(np数组,列表倒序)
2018/04/18 Python
OpenCV HSV颜色识别及HSV基本颜色分量范围
2019/03/22 Python
pytorch实现seq2seq时对loss进行mask的方式
2020/02/18 Python
Keras自定义IOU方式
2020/06/10 Python
python中可以声明变量类型吗
2020/06/18 Python
python3 os进行嵌套操作的实例讲解
2020/11/19 Python
美国领先的家庭智能音响系统品牌:Sonos
2018/07/20 全球购物
英国最受欢迎的母婴精品品牌:JoJo Maman BéBé
2021/02/17 全球购物
最新大学生创业计划书写作攻略
2014/04/02 职场文书
我的小天地教学反思
2014/04/30 职场文书
cf战队收人口号
2014/06/21 职场文书
不听老师话的万能检讨书
2014/10/04 职场文书
美丽的大脚观后感
2015/06/03 职场文书
残联2016年全国助残日活动总结
2016/04/01 职场文书
Python 内置函数速查表一览
2021/06/02 Python