前言
本篇在上一篇文章(《Egg + Vue + 微信公众号开发(基础框架搭建)》)的基础之上进行
需求:自定义开发微信公众号中,当普通微信用户向公众账号发消息时,微信公众号自动回复相应的内容。
一. 文档
二. 代码展示
1. parseStringXml方法
首先安装 npm i xml2js
,xml2js是用于解析xml文件的扩展,使用后可以将xml格式数据转为json格式。
// app/util/common.js
const { parseString } = require('xml2js');
class Common {
parseStringXml(xml) {
return new Promise((resolve, reject) => {
parseString(xml, async (err, result) => {
if (!err) {
const xmlData = result.xml;
const { MsgType, ToUserName, FromUserName, Event, Content } = xmlData;
const createTime = Date.parse(new Date());
const msgType = MsgType[0]; // 消息类型,event
const toUserName = ToUserName[0]; // 开发人员微信号
const toFromName = FromUserName[0]; // 发送方帐号(一个OpenID)
const event = Event ? Event[0] : ''; // 事件类型,subscribe(订阅)、unsubscribe(取消订阅)
const msgContent = Content ? Content[0] : ''; // 消息内容
resolve({
createTime,
msgType,
toUserName,
toFromName,
event,
msgContent,
});
} else {
console.log('err******', err);
reject(new Error('解析失败'));
}
});
});
}
}
module.exports = new Common();
2. 覆盖egg自带的配置 使支持接收xml参数
// config/config.default.js
// 新增以下配置
config.bodyParser = {
enable: true,
encoding: 'utf8',
formLimit: '100kb',
jsonLimit: '100kb',
strict: true,
queryString: {
arrayLimit: 100,
depth: 5,
parameterLimit: 1000,
},
enableTypes: [ 'json', 'form', 'text' ],
extendTypes: {
text: [ 'text/xml', 'application/xml' ],
},
};
3.contoller
// app/controller/basic_message.js
'use strict';
const { Controller } = require('egg');
const { parseStringXml } = require('../util/common');
class BasicMessageController extends Controller {
async replyMessage() {
const { ctx } = this;
const xml = this.ctx.request.body;
try {
const {
createTime, msgType, toUserName, toFromName, event, msgContent,
} = await parseStringXml(xml);
const dataPool = [
{
msgContent: '你好,您好,嗨',
reply_msg: '您好,请问有什么需要帮您的?☺☺☺'
},
{
msgContent: '歌曲推荐',
reply_msg: '上QQ音乐,找到你喜欢的歌曲,https://y.qq.com/'
}
];
const replyResultFilter = dataPool.filter(item => item.msgContent.includes(msgContent));
const replyResult = replyResultFilter.length !== 0 ? replyResultFilter[0] : {
msgContent: 'No Msg',
reply_msg: '你说的我听不懂,请详细描述一下你的问题!😭'
};
let body = '';
if (msgType === 'event' && event === 'subscribe') {
body = `
<xml>
<ToUserName><![CDATA[${toFromName}]]></ToUserName>
<FromUserName><![CDATA[${toUserName}]]></FromUserName>
<CreateTime>${createTime}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[欢迎关注公众号,下面请开始你的表演!🧐]]></Content>
</xml>
`;
} else if (msgType === 'text') {
const { reply_msg } = replyResult;
body = `
<xml>
<ToUserName><![CDATA[${toFromName}]]></ToUserName>
<FromUserName><![CDATA[${toUserName}]]></FromUserName>
<CreateTime>${createTime}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[${reply_msg}]]></Content>
<MediaId><![CDATA[media_id]]></MediaId>
</xml>
`;
} else if (msgType === 'event' && event === 'unsubscribe') {
this.ctx.logger.info(`微信号为:“${toFromName}”的用户取消订阅!`);
}
ctx.body = body;
} catch (e) {
console.log(e);
}
}
}
module.exports = BasicMessageController;
4. 路由
// app/router.js
'use strict';
module.exports = app => {
const { router, controller, middleware } = app;
// .......
router.post('/wechat', controller.basicMessage.replyMessage);
};