前言
经过前面的准备工作, 我们已经具备了和微信服务器通信的能力. 剩下的无非就是对着微信提供的api接口进行https请求, 不过在此之前我们还要做一件事情, 那就是设置回复模板.(www.hedaoshe.com)
分析
我们可以设想一个情景, 用户在我们陶瓷界面, 会执行一系列操作, 比如关注, 取消关注, 语音输入, 点击菜单等等... 这一系列操作会被微信后台接收到, 再传入到我们服务器. 我们接收到这些操作后, 再对这些操作做出响应.
这些响应在微信被动回复消息里面有详细描述. 也就是我们可以回复6种格式的消息: 图文, 音频, 音乐, 文本, 图片, 视频.
这些消息全是以固定格式被微信接收, 所以我们应该预先设置这些模板, 当我们要回复消息时, 只需要在模板中填入数据就行.
实现
我是以koa2框架实现的, 原理就这样, 各种语言实现也差不多.
class MsgUtil{
static MsgTypeEnum = {
TEXT:'text',
IMAGE:'image',
VOICE:'voice',
VEDIO:'vedio',
MUSIC:'music',
ARTICLE:'news'
}
/**
* @Date: 2020-10-23 11:00:00
* @author: qiud
* @description: 组装消息的固定前缀
* @param {object} xmlObj 微信端发给我们的请求内容
* @param {object} msgType 我们返回的消息类型
* @return {string} 组装的前缀
*/
static _assemblePrefixXml(xmlObj,msgType){
const replyXmlPrefix = `
<xml>
<ToUserName><![CDATA[${xmlObj.FromUserName}]]></ToUserName>
<FromUserName><![CDATA[${xmlObj.ToUserName}]]></FromUserName>
<CreateTime>${new Date().getTime()}</CreateTime>
<MsgType><![CDATA[${msgType}]]></MsgType>`
return replyXmlPrefix
}
/**
* @Date: 2020-10-23 11:00:00
* @author: qiud
* @description: 组装固定后缀
* @return {string} 组装的后缀
*/
static _assembleSuffixXml(){
return `</xml>`
}
/**
* @Date: 2020-10-23 11:00:00
* @author: qiud
* @description: 组装文本消息
* @param {object} xmlObj 微信端发给我们的请求内容
* @param {object} replyMsg 我们返回给客户的文本消息
* @return {string} 组装的后的文本消息
*/
static assembleTextMsg(xmlObj,replyMsg){
let replyXml = ''
replyXml += MsgUtil._assemblePrefixXml(xmlObj,MsgUtil.MsgTypeEnum.TEXT)
replyXml += `<Content><![CDATA[${replyMsg}]]></Content>`
replyXml +=MsgUtil._assembleSuffixXml()
return replyXml
}
/**
* @Date: 2020-10-23 11:00:00
* @author: qiud
* @description: 组装图片消息
* @param {object} xmlObj 微信端发给我们的请求内容
* @param {object} mediaId 我们返回给客户的图片id
* @return {string} 组装的后的图片消息
*/
static assembleImageMsg(xmlObj,mediaId){
let replyXml = ''
replyXml += MsgUtil._assemblePrefixXml(xmlObj,MsgUtil.MsgTypeEnum.IMAGE)
replyXml += `
<Image>
<MediaId><![CDATA[${mediaId}]]></MediaId>
</Image>`
replyXml +=MsgUtil._assembleSuffixXml()
return replyXml
}
//
/**
* @Date: 2020-10-23 11:00:00
* @author: qiud
* @description: 组装语音消息
* @param {object} xmlObj 微信端发给我们的请求内容
* @param {object} mediaId 我们返回给客户的音频id
* @return {string} 组装的后的音频消息
*/
static assembleVoiceMsg(xmlObj,mediaId){
let replyXml = ''
replyXml += MsgUtil._assemblePrefixXml(xmlObj,MsgUtil.MsgTypeEnum.VOICE)
replyXml += `
<Voice>
<MediaId><![CDATA[${mediaId}]]></MediaId>
</Voice>`
replyXml +=MsgUtil._assembleSuffixXml()
return replyXml
}
/**
* @Date: 2020-10-23 11:00:00
* @author: qiud
* @description: 组装视频消息
* @param {object} xmlObj 微信端发给我们的请求内容
* @param {object} obj 我们返回给客户的视频信息,包括标题,描述,视频id
* @return {string} 组装的后的视频消息
*/
static assembleVideoMsg(xmlObj,{title,mediaId,description}){
let replyXml = ''
replyXml += MsgUtil._assemblePrefixXml(xmlObj,MsgUtil.MsgTypeEnum.VEDIO)
replyXml += `
<Video>
<MediaId><![CDATA[${title}]]></MediaId>
<Title><![CDATA[${mediaId}]]></Title>
<Description><![CDATA[${description}]]></Description>
</Video>`
replyXml +=MsgUtil._assembleSuffixXml()
return replyXml
}
/**
* @Date: 2020-10-23 11:00:00
* @author: qiud
* @description: 组装音乐消息
* @param {object} xmlObj 微信端发给我们的请求内容
* @param {object} obj 我们返回给客户的音乐信息,包括标题,描述,音乐链接,高质量音乐链接,封面图id
* @return {string} 组装的后的音乐消息
*/
static assembleMusicMsg(xmlObj,{title,description,musicUrl,highQualityMusicUrl,mediaId}){
let replyXml = ''
replyXml += MsgUtil._assemblePrefixXml(xmlObj,MsgUtil.MsgTypeEnum.MUSIC)
replyXml += `
<Music>
<Title><![CDATA[${title}]]></Title>
<Description><![CDATA[${description}]]></Description>
<MusicUrl><![CDATA[${musicUrl}]]></MusicUrl>
<HQMusicUrl><![CDATA[${highQualityMusicUrl}]]></HQMusicUrl>
<ThumbMediaId><![CDATA[${mediaId}]]></ThumbMediaId>
</Music>`
replyXml +=MsgUtil._assembleSuffixXml()
return replyXml
}
/**
* @Date: 2020-10-23 11:00:00
* @author: qiud
* @description: 组装图文消息
* @param {object} xmlObj 微信端发给我们的请求内容
* @param {Array<Object>} articleArr 我们返回给客户的图文信息
* @return {string} 组装的后的图文消息
*/
static assembleArticlesMsg(xmlObj,articleArr){
let replyXml = ''
replyXml += MsgUtil._assemblePrefixXml(xmlObj,MsgUtil.MsgTypeEnum.ARTICLE)
replyXml += `
<ArticleCount>${articleArr.length}</ArticleCount>
<Articles>`
for(let article of articleArr){
const articleXml = MsgUtil._getArticleItemStr(article)
replyXml = replyXml + articleXml
}
replyXml+=`</Articles>
</xml>`
return replyXml
}
/**
* @Date: 2020-10-23 11:07:17
* @author: qiud
* @description: 我们对图文消息的每篇文章单独组装
* @param {obj} 每篇图文的信息, 包括标题,描述,封面图链接,正文链接
* @return {string} 每篇文章信息
*/
static _getArticleItemStr({title,description,picUrl,url}){
const articleStr = `
<item>
<Title><![CDATA[${title}]]></Title>
<Description><![CDATA[${description}]]></Description>
<PicUrl><![CDATA[${picUrl}]]></PicUrl>
<Url><![CDATA[${url}]]></Url>
</item>
`
return articleStr
}
}
module.exports = {
MsgUtil
}
总结
其实这一节很简单, 就是写6个生成固定格式字符串的拼接方法. 我们进行回顾:
- 客户在陶瓷界面操作
- 微信后台接收到这些操作, 把对应信息交给我们服务器
- 我们服务器根据这些操作调用对应的模板, 填入数据, 返回给微信后台
- 微信把这些信息推送给客户