资讯专栏INFORMATION COLUMN

【Node.js 微信公众号实战】4.Node.js 微信消息管理

lewinlee / 663人阅读

摘要:消息推送也是微信公众号开发更为有趣的功能,涉及到文本消息图片消息语音消息视频消息音乐消息以及图文消息。在文件中创建文件用于消息的管理。

一、写在前面的话

  当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应。

  消息推送也是微信公众号开发更为有趣的功能,涉及到文本消息、图片消息、语音消息、视频消息、音乐消息以及图文消息。并且最为有趣的功能当属消息加解密了,当然由于篇文章篇幅的原因我会在下一篇文章中去着重说明。

二、微信消息管理

1.捕获消息信息

  在文章的第一句话中,为我们指明了微信消息产生的请求方式为 POST,因此首先我们就去对 Node.js 的 Post 请求进行监听。

  在我们的 app.js 文件中添加一个POST监听,并将获取的结果输出:

//用于处理所有进入 3000 端口 post 的连接请求
app.post("/",function(req,res){
    var buffer = [];
    //监听 data 事件 用于接收数据
    req.on("data",function(data){
        buffer.push(data);
    });
    //监听 end 事件 用于处理接收完成的数据
    req.on("end",function(){
    //输出接收完成的数据   
         console.log(Buffer.concat(buffer).toString("utf-8"));
    });
});

  随后将 Node.js 启动后映射至外网,关注我们的微信公众号,在控制台中则会看到:

  打开 微信帮助文档 ,点击左侧菜单的消息管理,选择其子菜单 接收事件推送,如图:

  从上图我们不难看出,微信 接收事件推送 确实很多,而我们最终目标是要实现,在用户触发事件时返回其相应的回复消息。因此我们总结一下我们要实现的步骤:

解析 XML ,使用 Event 参数判断事件类型

返回相应的事件信息

总结完实现步骤后,我们就开始动手实现第一个被动回复消息吧。

2.以关注事件为例,实现第一个被动回复

  解析 XML 我这里使用了 第三方的包 xml2js(npm install xml2js ),并在 wechat.js 中引入。

 parseString = require("xml2js").parseString;//引入xml2js包

  为 WeChat 对象添加一个消息处理的方法 handleMsg,将 app.js 中捕获 POST 实现的写入在其代码块中,并使用 xml2js 解析,代码如下

/**
 * 微信消息
 */
WeChat.prototype.handleMsg = function(req,res){
    var buffer = [];
    //监听 data 事件 用于接收数据
    req.on("data",function(data){
        buffer.push(data);
    });
    //监听 end 事件 用于处理接收完成的数据
    req.on("end",function(){
        var msgXml = Buffer.concat(buffer).toString("utf-8");
        //解析xml
        parseString(msgXml,{explicitArray : false},function(err,result){
            if(!err){
                //打印解析结果
                console.log(result);
            }else{
                 //打印错误信息
                console.log(err);
            }
        })
    });
}

  在 app.js 中调用 handleMsg 方法

//用于处理所有进入 3000 端口 post 的连接请求
app.post("/",function(req,res){
    wechatApp.handleMsg(req,res);
});

  完成了代码的编写后,将公众号重新关注

最后打印为一个 JSON 格式的结果,也就是预示着我们第1步工作已经完成。下面开始我们的第2步,微信被动回复。

  在文章的第一句话的后边提到 开发者可以在响应包(Get)中返回特定XML结构,那么这个特定的 XML 结构在哪呢?再次打开微信帮助文档 ,点击左侧菜单的消息管理,选择其子菜单 被动回复消息,如图:

  直接来到 回复文本消息:

  拿到回复文本消息格式后,我们就来为关注我们公众号的同学打声招呼吧。在 wechat 文件中 创建 msg.js 文件用于消息的管理。

并在 msg.js 中添加处理文本消息的接口,并在 wechat.js 中引用

"use strict" //设置为严格模式

//回复文本消息
exports.txtMsg = function(toUser,fromUser,content){
    var xmlContent =  "";
        xmlContent += "";
        xmlContent += ""+ new Date().getTime() +"";
        xmlContent += "";
        xmlContent += "";
    return xmlContent;
}

修改 wechat.js 中 handleMsg 方法

/**
 * 微信消息
 */
WeChat.prototype.handleMsg = function(req,res){
    var buffer = [];
    //监听 data 事件 用于接收数据
    req.on("data",function(data){
        buffer.push(data);
    });
    //监听 end 事件 用于处理接收完成的数据
    req.on("end",function(){
        var msgXml = Buffer.concat(buffer).toString("utf-8");
        //解析xml
        parseString(msgXml,{explicitArray : false},function(err,result){
            if(!err){
                   result = result.xml;
                   var toUser = result.ToUserName; //接收方微信
                   var fromUser = result.FromUserName;//发送仿微信
                   //判断事件类型
                   switch(result.Event.toLowerCase()){
                      case "subscribe":
                             //回复消息
                             res.send(msg.txtMsg(fromUser,toUser,"欢迎关注 hvkcoder 公众号,一起斗图吧"));
                             break;
                   }
            }else{
                 //打印错误信息
                console.log(err);
            }
        })
    });
}

   没错就是这么简单。这里有个逻辑是这样的 toUser 表示接收方,也就是咱们的微信公众号;fromUser 表示发送方,也就是触发事件的用户。而我们要回复用户时,此时 接收方 就是 触发事件的用户,而发送方则是 我们的微信公众号。这块比较绕,大家可以慢慢去理解。

  由于我们还没有对微信的素材管理进行讲解,这里我们暂时跳过 图片消息、语音消息、视频消息、以及音乐消息。直接实现图文消息的推送。

3.图文消息

  在 msg.js 文件中添加图文XML模板

//回复图文消息
exports.graphicMsg = function(toUser,fromUser,contentArr){
     var xmlContent =  "";
        xmlContent += "";
        xmlContent += ""+ new Date().getTime() +"";
        xmlContent += "";
        xmlContent += ""+contentArr.length+"";
        xmlContent += "";
        contentArr.map(function(item,index){
            xmlContent+="";
            xmlContent+="<![CDATA["+ item.Title +"]]>";
            xmlContent+="";
            xmlContent+="";
            xmlContent+="";
            xmlContent+="";
        });
        xmlContent += "";
    return xmlContent;
}
}

  更改 wechat.js 文件中的 handleMsg 方法,将图消息推送响应在点击事件中

  case "click":
                                var contentArr = [
                                    {Title:"Node.js 微信自定义菜单",Description:"使用Node.js实现自定义微信菜单",PicUrl:"http://img.blog.csdn.net/20170605162832842?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHZrQ29kZXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast",Url:"http://blog.csdn.net/hvkcoder/article/details/72868520"},
                                    {Title:"Node.js access_token的获取、存储及更新",Description:"Node.js access_token的获取、存储及更新",PicUrl:"http://img.blog.csdn.net/20170528151333883?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHZrQ29kZXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast",Url:"http://blog.csdn.net/hvkcoder/article/details/72783631"},
                                    {Title:"Node.js 接入微信公众平台开发",Description:"Node.js 接入微信公众平台开发",PicUrl:"http://img.blog.csdn.net/20170605162832842?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHZrQ29kZXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast",Url:"http://blog.csdn.net/hvkcoder/article/details/72765279"}
                                ];
                               //回复图文消息
                               res.send(msg.graphicMsg(fromUser,toUser,contentArr));
                            break;

  点击菜单下的 今日推荐

  图文推送就是这么简单的被我们给实现了。

4.接收普通消息

  微信除了为我们接收事件推送外,千万不要忘了微信还能通过发送文字。而这一节我们也就来玩玩微信接收普通消息。

  打开 微信帮助文档 ,点击左侧菜单的消息管理,选择其子菜单 接收普通消息,如图:

  依然如接收事件推送的套路,不同的是参数发生了改变,但这并步影响我们的开发,只需要几步就能够完美的解决。更改 wechat.js 文件 handleMsg方法,这里我先暂时只针对用户输入的文本消息做处理,其他的跟其类似。

//判断消息类型
                   if(result.MsgType.toLowerCase() === "event"){
                        //判断事件类型
                        switch(result.Event.toLowerCase()){
                            case "subscribe":
                                    //回复消息
                                    var content = "欢迎关注 hvkcoder 公众号,一起斗图吧。回复以下数字:
";
                                        content += "1.你是谁
";
                                        content += "2.关于Node.js
";
                                        content += "回复 “文章”  可以得到图文推送哦~
";
                                    res.send(msg.txtMsg(fromUser,toUser,""));
                                    break;
                            case "click":
                                        var contentArr = [
                                            {Title:"Node.js 微信自定义菜单",Description:"使用Node.js实现自定义微信菜单",PicUrl:"http://img.blog.csdn.net/20170605162832842?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHZrQ29kZXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast",Url:"http://blog.csdn.net/hvkcoder/article/details/72868520"},
                                            {Title:"Node.js access_token的获取、存储及更新",Description:"Node.js access_token的获取、存储及更新",PicUrl:"http://img.blog.csdn.net/20170528151333883?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHZrQ29kZXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast",Url:"http://blog.csdn.net/hvkcoder/article/details/72783631"},
                                            {Title:"Node.js 接入微信公众平台开发",Description:"Node.js 接入微信公众平台开发",PicUrl:"http://img.blog.csdn.net/20170605162832842?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHZrQ29kZXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast",Url:"http://blog.csdn.net/hvkcoder/article/details/72765279"}
                                        ];
                                    //回复图文消息
                                    res.send(msg.graphicMsg(fromUser,toUser,contentArr));
                                    break;
                        }
                   }else{
                       //判断消息类型为 文本消息
                       if(result.MsgType.toLowerCase() === "text"){
                           //根据消息内容返回消息信息
                           switch(result.Content){
                               case "1":
                                        res.send(msg.txtMsg(fromUser,toUser,"Hello !我的英文名字叫 H-VK"));
                                    break;
                               case "2":
                                        res.send(msg.txtMsg(fromUser,toUser,"Node.js是一个开放源代码、跨平台的JavaScript语言运行环境,采用Google开发的V8运行代码,使用事件驱动、非阻塞和异步输入输出模型等技术来提高性能,可优化应用程序的传输量和规模。这些技术通常用于数据密集的事实应用程序"));
                                    break;
                               case "文章":
                                      var contentArr = [
                                            {Title:"Node.js 微信自定义菜单",Description:"使用Node.js实现自定义微信菜单",PicUrl:"http://img.blog.csdn.net/20170605162832842?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHZrQ29kZXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast",Url:"http://blog.csdn.net/hvkcoder/article/details/72868520"},
                                            {Title:"Node.js access_token的获取、存储及更新",Description:"Node.js access_token的获取、存储及更新",PicUrl:"http://img.blog.csdn.net/20170528151333883?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHZrQ29kZXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast",Url:"http://blog.csdn.net/hvkcoder/article/details/72783631"},
                                            {Title:"Node.js 接入微信公众平台开发",Description:"Node.js 接入微信公众平台开发",PicUrl:"http://img.blog.csdn.net/20170605162832842?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHZrQ29kZXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast",Url:"http://blog.csdn.net/hvkcoder/article/details/72765279"}
                                        ];
                                        //回复图文消息
                                        res.send(msg.graphicMsg(fromUser,toUser,contentArr));
                                    break;
                                default :
                                         res.send(msg.txtMsg(fromUser,toUser,"没有这个选项哦"));
                                    break;
                           }
                       }
                   }

  OK !至此我们就完成了微信消息管理的讲解,似乎真的没有什么难度。预留了一章,主要想要去细说一下说消息加解密,因为在网上涉及 Node.js 微信消息加解密的文章确实很少,微信帮助文档给的案例也没有 Node.js 的详细说明。

  最后文章代码部分,由于网上编辑器的代码换行做的不是很好可能有些乱,建议可以去我的 github 上查看源码。

  文章源代码:https://github.com/SilenceHVK... 。对文章有不正确之处,请给予纠正。github源代码请顺手给个 Star,最后感谢您的阅读。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92174.html

相关文章

  • Node.js 微信公众实战】1.Node.js 接入微信公众平台开发

    摘要:打开中文网文档打开微信开发者文档三接入微信公众平台创建项目首先我们在电脑的任意磁盘上创建文件夹,命名随意,我这命名为随后在文件夹中创建两个文件一个是,另一个为。接入验证再次进入微信公众平台在左侧菜单点击基本配置,如图点击修改配置。 一、写在前面的话   Node.js是一个开放源代码、跨平台的JavaScript语言运行环境,采用Google开发的V8运行代码,使用事件驱动、非阻塞和异...

    winterdawn 评论0 收藏0
  • 全栈最后一公里 - Node.js 项目的线上服务器部署与发布

    摘要:没有耐心阅读的同学,可以直接前往学习全栈最后一公里。我下面会罗列一些,我自己录制过的一些项目,或者其他的我觉得可以按照这个路线继续深入学习的项目资源。 showImg(https://segmentfault.com/img/bVMlke?w=833&h=410); 本文技术软文,阅读需谨慎,长约 7000 字,通读需 5 分钟 大家好,我是 Scott,本文通过提供给大家学习的方法,...

    Nosee 评论0 收藏0
  • node打造微信个人机器人

    摘要:是一款开源的微信个人号,进行了一系列的封装,提供简单好用的接口,然后开发者可以在其之上进行微信机器人的开发。注意这行代码实现了登录微信个人号并打印出所收到的消息。大家可以根据自己的需要定制出强大的个人微信号机器人。 现在,日常生活已经离不开微信,本文将会抛砖引玉演示如何使用wechaty操作微信个人号做一些有意思的东西,可以实现自动通过好友请求、关键词回复、自动拉群等功能。大大提高了社...

    xiaolinbang 评论0 收藏0
  • Node.js 微信公众实战】3.Node.js 自定义微信菜单

    摘要:一写在前面的话上一篇文章中,我们使用成功的实现了的获取存储以及更新,这篇文章我们来实现微信的自定义菜单功能。二自定义微信菜单微信文档步骤在开始码代码之前,我们依然是先理清实现的思路,再开始编写实现代码。 一、写在前面的话   上一篇文章中,我们使用 Node.js 成功的实现了access_token 的获取、存储以及更新,这篇文章我们来实现微信的自定义菜单功能。showImg(htt...

    Barry_Ng 评论0 收藏0

发表评论

0条评论

lewinlee

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<