美文网首页程序猿阵线联盟-汇总各类技术干货
Node开发微信公众号(2)——微信回复

Node开发微信公众号(2)——微信回复

作者: Mr绍君 | 来源:发表于2018-05-05 11:34 被阅读47次

开始之前,我们先说一下今天的思路:

当用户关注或者发送消息的时候,微信服务器会给我们发送一个post请求,把用户的信息以及发送信息返回给我们,我们根据用户发送的信息再把相应的内容发送到微信服务器。

整体的思路还是非常清晰的,但是有个问题比较麻烦,就是微信返回和接收的数据格式都是xml,所以我们要对xml进行转换。所以在今天我们会引入几个新的模块。


先在app.js文件中,创建一个post的中间件,来接收服务器发送的请求和数据。

app.post("/", (req,res, next)=> {
    wechat.autoMsg(req, res, next);
})

然后,我们在wechat.js中添加autoMsg方法。

var parseString = require('xml2js').parseString;
WeChat.prototype.autoMsg = function(req, res, next) {
    var buffer = [],
        that = this;

    req.on('data',function(data){
        buffer.push(data);
    });
    req.on('end',function(){
        var msgXml = Buffer.concat(buffer).toString('utf-8');
        parseString(msgXml,{explicitArray : false},function(err,result){
            // 如果有错误直接抛出
            if(err) throw err;
            result = result.xml;

            var toUser = result.ToUserName; 
            var fromUser = result.FromUserName;

            // 判断消息类型
            if(result.MsgType === "event") {
                // 关注微信公众号
                if(result.Event === "subscribe") {
                    var resultXml =  "<xml><ToUserName><![CDATA["+ fromUser +"]]></ToUserName>";
                    resultXml += "<FromUserName><![CDATA["+ toUser +"]]></FromUserName>";
                    resultXml += "<CreateTime>"+ new Date().getTime() +"</CreateTime>";
                    resultXml += "<MsgType><![CDATA[text]]></MsgType>";
                    resultXml += "<Content><![CDATA[欢迎关注,哈哈哈哈哈!]]></Content></xml>";
                    
                    res.send(resultXml);
                }
            }else {
            }
        })
    })

由于我们接收到的数据是xml的,所以我们引入了xml2js模块,对xml进行转换。(如果想get模块的更多功能,可以直接去npm官网搜索,我这里用的都是api上最基本的用法)

xml格式可以去微信开发文档上直接拷贝,然后自己在凭借一些字符串就行。

这里有几个坑需要注意一下,1.xml格式如果直接是从微信开发文档上复制的,xml会多出一些空格,需要删除,不然xml格式会出错。(如果不放心可以百度一下,xml在线格式化先试一试);
2.xml字符拼接的结果得跟开发文档上的一致,不能有多余的空格和换行。
3.我们接收到的xml信息里面的toUser和fromUser在消息返回给微信服务器的时候,这两个是相反的。也就是说我们关注的时候,服务器给我们的toUser是我们的公众号ID,回复的时候我们返回的toUser,是用户的id。

我们关注一下,查看一下结果。(那个1是之前调试的时候发送的,请忽略)

消息回复跟自动回复写法是一样的,这里就不赘述了。


同样的,我们把代码优化一下,把消息回复封装成一个模块。


// 回复文本消息
exports.textMsg = function(toUser,fromUser,content){
    var xmlContent =  "<xml><ToUserName><![CDATA["+ toUser +"]]></ToUserName>";
        xmlContent += "<FromUserName><![CDATA["+ fromUser +"]]></FromUserName>";
        xmlContent += "<CreateTime>"+ new Date().getTime() +"</CreateTime>";
        xmlContent += "<MsgType><![CDATA[text]]></MsgType>";
        xmlContent += "<Content><![CDATA["+ content +"]]></Content></xml>";
    return xmlContent;
}

// 回复图文消息
exports.graphicMsg = function(toUser,fromUser,contentArr){
    var xmlContent =  "<xml><ToUserName><![CDATA["+ toUser +"]]></ToUserName>";
       xmlContent += "<FromUserName><![CDATA["+ fromUser +"]]></FromUserName>";
       xmlContent += "<CreateTime>"+ new Date().getTime() +"</CreateTime>";
       xmlContent += "<MsgType><![CDATA[news]]></MsgType>";
       xmlContent += "<ArticleCount>"+contentArr.length+"</ArticleCount>";
       xmlContent += "<Articles>";
       contentArr.map(function(item,index){
           xmlContent += "<item>";
           xmlContent += "<Title><![CDATA["+ item.Title +"]]></Title>";
           xmlContent += "<Description><![CDATA["+ item.Description +"]]></Description>";
           xmlContent += "<PicUrl><![CDATA["+ item.PicUrl +"]]></PicUrl>";
           xmlContent += "<Url><![CDATA["+ item.Url +"]]></Url>";
           xmlContent += "</item>";
       });
       xmlContent += "</Articles></xml>";
   return xmlContent;
}

// 回复图片
exports.imgMsg = function(toUser, fromUser, media_id) {
    var xmlContent = "<xml><ToUserName><![CDATA["+ toUser +"]]></ToUserName>";
        xmlContent += "<FromUserName><![CDATA["+ fromUser +"]]></FromUserName>";
        xmlContent += "<CreateTime>"+ new Date().getTime() +"</CreateTime>";
        xmlContent += "<MsgType><![CDATA[image]]></MsgType>";
        xmlContent += "<Image><MediaId>< ![CDATA["+ media_id +"] ]></MediaId></Image></xml>";
    return xmlContent; 
}

// 回复语音
exports.vodeoMsg = function(toUser, fromUser, media_id, title, description) {
    var xmlContent = "<xml><ToUserName><![CDATA["+ toUser +"]]></ToUserName>";
        xmlContent += "<FromUserName><![CDATA["+ fromUser +"]]></FromUserName>";
        xmlContent += "<CreateTime>"+ new Date().getTime() +"</CreateTime>";
        xmlContent += "<MsgType><![CDATA[video]]></MsgType>";
        xmlContent += "<Video><MediaId><![CDATA["+ media_id +"]]></MediaId>";
        xmlContent += "<Title><![CDATA["+ title +"]]></Title>";
        xmlContent += "<Description><![CDATA["+ description +"]]></Description></Video></xml>";
    return xmlContent;  
}

源码地址:https://github.com/yeshaojun/wechatBase
如果喜欢就给我点个小星星吧!

相关文章

网友评论

    本文标题:Node开发微信公众号(2)——微信回复

    本文链接:https://www.haomeiwen.com/subject/ebvzlftx.html