详解nodejs微信公众号开发——3.封装消息响应模块


Posted in NodeJs onApril 10, 2017

上一篇文章:nodejs微信公众号开发(2)自动回复,实现了简单的关注回复。采用拼接字符串的形式,并不是很方便,这里我们将其封装承接口。

1. ejs模板引擎

不使用拼接字符串的方式,那么模板引擎就是较好的选择。Nodejs开源模板的选择很多,程序中使用 EJS,有Classic ASP/PHP/JSP的经验用起EJS来的确可以很自然,也就是说,你能够在 <%...%> 块中安排 JavaScript 代码,利用最传统的方式 <%=输出变量%>(另外 <%-输出变量是不会对 & 等符号进行转义的).

2. heredoc

在php、python中都有heredoc方式的字符串定义方法,JavaScript也实现了heredoc模块,主要解决大量字符串拼接问题。
新建模板文件tpl.js:

'use strict'

var ejs = require('ejs');
var heredoc = require('heredoc');

var tpl = heredoc(function(content){/*
  <xml>
    <ToUserName><![CDATA[<%= toUserName %>]]></ToUserName>
    <FromUserName><![CDATA[<%= fromUserName %>]]></FromUserName>
    <CreateTime><%= createTime%></CreateTime>
    <MsgType><![CDATA[<%= msgType %>]]></MsgType>
    <% if(msgType ==='text') { %>
      <Content><![CDATA[<%= content %>]]></Content>
    <% }else if(msgType ==='image'){ %>
      <Image>
        <MediaId><![CDATA[<%= content.mediaId %>]]></MediaId>
      </Image>
    <% }else if(msgType ==='voice'){ %>
      <Voice>
        <MediaId><![CDATA[<%= content.mediaId %>]]></MediaId>
      </Voice>
    <% } %>else if(msgType ==='video'){ %>
      <Video>
        <MediaId><![CDATA[<%= content.mediaId %>]]></MediaId>
        <Title><![CDATA[<%= content.title %>]]></Title>
        <Description><![CDATA[<%= content.description %>]]></Description>
      </Video>   
    <% } %>else if(msgType ==='music'){ %>
      <Music>
        <Title><![CDATA[<%= content.title %>]]></Title>
        <Description><![CDATA[<%= content.description %>]]></Description>
        <MusicUrl><![CDATA[<%= content.musicUrl %>]]></MusicUrl>
        <HQMusicUrl><![CDATA[<%= content.hqMusicUrl %>]]></HQMusicUrl>
        <ThumbMediaId><![CDATA[<%= content.thumbMediaId %>]]></ThumbMediaId>  
      </Music>
    <% } %>else if(msgType ==='news'){ %>
      <ArticleCount><%= content.length %></ArticleCount>
      <Articles>
        <% content.forEach(function(item){ %>
        <item>
          <Title><![CDATA[<%= item.title %>]]></Title> 
          <Description><![CDATA[<%= item.description %>]]></Description>
          <PicUrl><![CDATA[<%= item.picUrl %>]]></PicUrl>
          <Url><![CDATA[<%= item.url %>]]></Url>
        </item>
        <% }) %>
      </Articles>
    <% } %>  
  </xml>
*/});

var compiled = ejs.compiled(tpl);

exports = module.exports = {
  compiled:compiled
};

3. 处理接收到的消息

修改generator.js中之前直接回复消息的那部分代码,我们将处理回复内容的逻辑交给业务层,等其处理完毕,继续执行下面的代码,封装消息内容成xml并回复出去。

var message = util.formatMessage(content.xml);
    
this.weixin = message; //挂载消息

yield handler.call(this,next);  //转到业务层逻辑

wechat.replay.call(this); //真正回复

4.业务层的处理逻辑

app.js里面中间件的使用方式修改为:

var weixin = require('./weixin');
...
app.use(wechat(config.wechat,weixin.reply));

weixin.replygenerator.js中的handler,我们将公众号业务成的逻辑都写在weixin.js里面,如回复消息、将来的爬取电影网站信息、支付等。

exports.reply = function* (next){
  var message = this.weixin;

  if(message.magType === 'event'){
    if(message.Event === 'subscribe'){
      if(message.EventKey) console.log('扫描二维码关注:'+message.EventKey+' '+message.ticket);
      this.body = '终于等到你,还好我没放弃';
    }else if(message.Event === 'unsubscribe'){
      console.log(message.FromUserName +' 悄悄地走了...');
    }
  }else{
    //
  }

  yield next;
}

5.回复消息

我们在Wechat原型链上增加replay方法:

Wechat.prototype.replay = function(){
  var content = this.body;
  var message = this.weixin;

  var xml = util.tpl(content,message);

  this.status = 200;
  this.type = 'application/xml';
  this.body = xml;
}

这样实现了wechat.replay.call(this); 的回复消息功能。

6.总结

上面代码已经基本实现了消息的封装,回复规则和回复内容写在业务层代码weixin.js中,里面简单的实现了关注和取关的事件处理。

由于koa框架是基于ES6,里面充斥了大量的Promisegenaratoryield等内容,对ES6不了解的,可以学习一下此篇文章:ECMAScript6快速入手攻略

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
nodejs分页类代码分享
Jun 17 NodeJs
详解nodejs微信公众号开发——1.接入微信公众号
Apr 10 NodeJs
详解nodejs异步I/O和事件循环
Jun 07 NodeJs
基于nodejs实现微信支付功能
Dec 20 NodeJs
Nodejs中crypto模块的安全知识讲解
Jan 03 NodeJs
nodeJS服务器的创建和重新启动的实现方法
May 12 NodeJs
基于nodejs res.end和res.send的区别
May 14 NodeJs
nodejs 十六进制字符串型数据与btye型数据相互转换
Jul 30 NodeJs
NodeJS搭建HTTP服务器的实现步骤
Oct 12 NodeJs
NodeJs操作MongoDB教程之分页功能以及常见问题
Apr 09 NodeJs
关于NodeJS中的循环引用详解
Jul 23 NodeJs
nodejs各种姿势断点调试的方法
Jun 18 NodeJs
详解nodejs微信公众号开发——2.自动回复
Apr 10 #NodeJs
详解nodejs微信公众号开发——1.接入微信公众号
Apr 10 #NodeJs
使用 NodeJS+Express 开发服务端的简单介绍
Apr 07 #NodeJs
初识NodeJS服务端开发入门(Express+MySQL)
Apr 07 #NodeJs
nodejs服务搭建教程 nodejs访问本地站点文件
Apr 07 #NodeJs
nodejs爬虫遇到的乱码问题汇总
Apr 07 #NodeJs
详解nodejs爬虫程序解决gbk等中文编码问题
Apr 06 #NodeJs
You might like
用PHP制作静态网站的模板框架(二)
2006/10/09 PHP
php目录管理函数小结
2008/09/10 PHP
win7 64位系统 配置php最新版开发环境(php+Apache+mysql)
2014/08/15 PHP
静态html文件执行php语句的方法(推荐)
2016/11/21 PHP
php 查找数组元素提高效率的方法详解
2017/05/05 PHP
php实现的中秋博饼游戏之绘制骰子图案功能示例
2017/11/06 PHP
PHP7基于curl实现的上传图片功能
2018/05/11 PHP
EasyUI的treegrid组件动态加载数据问题的解决办法
2011/12/11 Javascript
jQuery.Validate验证库的使用介绍
2013/04/26 Javascript
JS获取图片实际宽高及根据图片大小进行自适应
2013/08/11 Javascript
JS实现图片的不间断连续滚动的简单实例
2016/06/03 Javascript
KnockoutJS 3.X API 第四章之事件event绑定
2016/10/10 Javascript
AngularJS通过ng-route实现基本的路由功能实例详解
2016/12/13 Javascript
vue双花括号的使用方法 附练习题
2017/11/07 Javascript
jQuery 防止相同的事件快速重复触发方法
2018/02/08 jQuery
详解angular脏检查原理及伪代码实现
2018/06/08 Javascript
微信小程序自定义多列选择器使用详解
2019/06/21 Javascript
[02:58]魔廷新尊——痛苦女王至宝语音台词节选
2020/06/14 DOTA
Python正则表达式常用函数总结
2017/06/24 Python
python中logging包的使用总结
2018/02/28 Python
python3.6.3+opencv3.3.0实现动态人脸捕获
2018/05/25 Python
Python变量类型知识点总结
2019/02/18 Python
python opencv 图像拼接的实现方法
2019/06/27 Python
Python 3.6 中使用pdfminer解析pdf文件的实现
2019/09/25 Python
python 协程 gevent原理与用法分析
2019/11/22 Python
Python制作数据预测集成工具(值得收藏)
2020/08/21 Python
Python尾递归优化实现代码及原理详解
2020/10/09 Python
用60行代码实现Python自动抢微信红包
2021/02/04 Python
HTML5语音识别标签写法附图
2013/11/18 HTML / CSS
致长跑运动员广播稿
2014/01/31 职场文书
KTV的创业计划书范文
2014/02/02 职场文书
学校春季防火方案
2014/06/08 职场文书
习近平在党的群众路线教育实践活动总结大会上的讲话全文
2014/10/25 职场文书
中学感恩教育活动总结
2015/05/05 职场文书
关于销售人员的年终工作总结要点
2019/08/15 职场文书
Python Django获取URL中的数据详解
2021/11/01 Python