详解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(三)--- Node.js模块
May 25 NodeJs
Nodejs学习笔记之测试驱动
Apr 16 NodeJs
NodeJs读取JSON文件格式化时的注意事项
Sep 25 NodeJs
用nodejs搭建websocket服务器
Jan 23 NodeJs
NodeJs使用Mysql模块实现事务处理实例
May 31 NodeJs
nodejs利用ajax实现网页无刷新上传图片实例代码
Jun 06 NodeJs
让nodeJS支持ES6的词法----babel的安装和使用方法
Jul 31 NodeJs
Nodejs+angularjs结合multiparty实现多图片上传的示例代码
Sep 29 NodeJs
nodejs中安装ghost出错的原因及解决方法
Oct 23 NodeJs
nodejs基于WS模块实现WebSocket聊天功能的方法
Jan 12 NodeJs
nodejs实现聊天机器人功能
Sep 19 NodeJs
nodejs中使用worker_threads来创建新的线程的方法
Jan 22 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
Classes and Objects in PHP5-面向对象编程 [1]
2006/10/09 PHP
在线增减.htpasswd内的用户
2006/10/09 PHP
加强版phplib的DB类
2008/03/31 PHP
php HtmlReplace输入过滤安全函数
2010/07/03 PHP
php判断输入是否是纯数字,英文,汉字的方法
2015/03/05 PHP
[原创]php使用curl判断网页404(不存在)的方法
2016/06/23 PHP
Laravel 中使用 Vue.js 实现基于 Ajax 的表单提交错误验证操作
2017/06/30 PHP
PHP空值检测函数与方法汇总
2017/11/19 PHP
php根据地址获取百度地图经纬度的实例方法
2019/09/03 PHP
音乐播放用的的几个函数
2006/09/07 Javascript
JavaScript实现向右伸出的多级网页菜单效果
2015/08/25 Javascript
javascript适合移动端的日期时间拾取器
2015/11/10 Javascript
jQuery获取DOM节点实例分析(2种方式)
2015/12/15 Javascript
JavaScript中两个字符串的匹配
2016/06/08 Javascript
JS对HTML表格进行增删改操作
2016/08/22 Javascript
JS正则表达式验证中文字符
2017/05/08 Javascript
vue-cli 如何打包上线的方法示例
2018/05/08 Javascript
vue-cli 3.x 配置Axios(proxyTable)跨域代理方法
2018/09/19 Javascript
微信小程序自定义可滑动顶部TabBar选项卡实现页面切换功能示例
2019/05/14 Javascript
vue项目中锚点定位替代方式
2019/11/13 Javascript
跟老齐学Python之一个免费的实验室
2014/09/14 Python
python使用marshal模块序列化实例
2014/09/25 Python
Python使用爬虫爬取静态网页图片的方法详解
2018/06/05 Python
flask利用flask-wtf验证上传的文件的方法
2020/01/17 Python
详解css3 flex弹性盒自动铺满写法
2020/09/17 HTML / CSS
详解通过变换矩阵实现canvas的缩放功能
2019/01/14 HTML / CSS
什么叫做SQL注入,如何防止
2016/10/04 面试题
J2ee常用的设计模式?说明工厂模式
2015/05/21 面试题
网络编辑岗位职责范本
2014/02/10 职场文书
优秀团员自我评价范文
2014/04/23 职场文书
企业员工辞职信范文
2015/05/12 职场文书
课文《燕子》教学反思
2016/02/17 职场文书
2019年图书室自查报告范本
2019/10/12 职场文书
Nginx配置并兼容HTTP实现代码解析
2021/03/31 Servers
pytorch 如何使用float64训练
2021/05/24 Python
剑指Offer之Java算法习题精讲二叉树的构造和遍历
2022/03/21 Java/Android