本节主要介绍下在开发公众号消息消息管理中踩过的坑,有与好久才来写一次,文笔不是太好。为了让你发现想要的重点,将以问答的形式进行编写。node
1.为何先开发消息管理模块:json
刚刚开始接触这个,看了api文档后第一感受是乱、多。对应新手来讲这么多东西该从那里下手呢?看了下jssdk部分,由于有腾讯的demo,因此为了学习方面能够直接将代码弄到本地跟着调式就行,主要涉及一些wx.config里面的参数获取逻辑须要整理下。由于以前已经经过postman测试了自定义菜单了,那干脆就接着作人机交互部分-消息接收和回复。api
2.消息管理这块能够作什么事情:promise
总结了一下,消息管理主要作两方面的事情。服务器
第一:与用户进行交互(包括接收用户发来的文本、语言、视频等信息,同时能够对用户发送的信息进行回复)微信
第二:与微信服务器进行交互(对于一些指定的动做,微信会发送信息到后台、部分须要咱们的服务器进行回复。好比:新用户关注公众号、取消关注公众号、上报地理位置事件等)运维
具体能够参考https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140454 中 消息管理->接收事件推送异步
3.接收消息要作一些什么:async
第一:在微信管理平台配置URL, 路径为 开发-》基本配置-》服务器配置(这个要先启动)post
其中URL为本身后台服务器的一个服务,微信将经过post请求将消息发送到这个地方,同时在配置点确认的时候,微信会发送get请求到这个路径进行验证,具体验证逻辑能够参考个人上一篇文章。
这个地方特别要注意:一个get请求一个post请求分别有不一样的目的
第二:搭建本身的服务器,要保证第一点中的URL能正常接收post请求
3.开发消息管理后台遇到了什么坑
第一:晚上不少文章都是别人写的demo,不少代码有误导性。要有本身的思考。同时细看api文档。
第二:我用的node(eggjs),因此遇到了异步的问题,当时看网上不少人都是经过req.on()去监听接收text/xml数据流,而后就直接返回了。在这重申:这些都是坑,及其不负责任,要同步方法。这个异步形成微信根本收不到。
要将监听获取数据流方法同步化。我用了raw-body插件,这个会返回xml格式的字符串,还须要用xml2js转成json (这个须要本身promise封装成同步)便可,接着根据指定格式返回信息给微信
第三:直接将参数赋值给res.body就能够了,不要想的很复杂。
第四:新手建议不要用测试帐号,用正式帐号。为何呢?由于正式帐号能够从管理平台中看到返回给微信的日志,方便查错(高手请忽略)
开发-》运维中心-》日志查询 日志类型选择:公众号被动回复,类型自选便可
4.代码实现
//controller方法,暂时没有分service const rawBody = require('raw-body') var contentType = require('content-type') const tool = require('../../utils/tool.js') //处理方法 async message(){ //获取微信推送过来的消息 const { ctx ,config} = this console.log('message request:', ctx.request.body) var data = await rawBody(ctx.req, { length : ctx.request.headers['content-length'], limit : '1mb', encoding: contentType.parse(ctx.request).parameters.charset }); console.log('data+++:' + data); let jsonData = await tool.parseXMLAsync(data) let getData = jsonData.xml let { ToUserName, FromUserName, MsgType, Content, MsgId } = getData console.log('****************', getData) let rst = `<xml><ToUserName><![CDATA[${FromUserName}]]></ToUserName> <FromUserName><![CDATA[${ToUserName}]]></FromUserName> <CreateTime>1540993144</CreateTime> <MsgType><![CDATA[${ MsgType}]]></MsgType> <Content><![CDATA[${Content}]]></Content> <MsgId>${MsgId}</MsgId> </xml>` ctx.body = rst } //一下为tool.js 简单的封装了xml2js方法,将其同步化 var xml2js = require('xml2js'); //导出解析XML的方法 function parseXMLAsync (xml) { return new Promise(function (resolve, reject) { xml2js.parseString(xml, { explicitArray: true }, function (err, content) { err ? reject(err): resolve(content); }); }); }; module.exports = { parseXMLAsync }