详解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 后缀名判断限制代码
Mar 31 NodeJs
提高NodeJS中SSL服务的性能
Jul 15 NodeJs
轻松创建nodejs服务器(10):处理POST请求
Dec 18 NodeJs
NodeJS学习笔记之Connect中间件模块(二)
Jan 27 NodeJs
nodejs创建web服务器之hello world程序
Aug 20 NodeJs
nodejs基础知识
Feb 03 NodeJs
搭建简单的nodejs http服务器详解
Mar 09 NodeJs
nodejs集成sqlite使用示例
Jun 05 NodeJs
nodejs利用ajax实现网页无刷新上传图片实例代码
Jun 06 NodeJs
Nodejs之http的表单提交
Jul 07 NodeJs
nodejs多版本管理总结
Apr 03 NodeJs
Nodejs文件上传、监听上传进度的代码
Mar 27 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在项目中寻找代码的坏味道(综艺命名)
2012/07/19 PHP
PHP 自定义错误处理函数trigger_error()
2013/03/26 PHP
php导出csv格式数据并将数字转换成文本的思路以及代码分享
2014/06/05 PHP
php访问数组最后一个元素的函数end()用法
2015/03/18 PHP
PHP内核探索之变量
2015/12/22 PHP
lnmp安装多版本PHP共存的方法详解
2018/08/02 PHP
PHP PDOStatement::setAttribute讲解
2019/02/01 PHP
jQuery 1.0.4 - New Wave Javascript(js源文件)
2007/01/15 Javascript
关于document.cookie的使用javascript
2008/04/11 Javascript
jQuery Ajax文件上传(php)
2009/06/16 Javascript
jQuery 回车事件enter使用示例
2014/02/18 Javascript
jQuery表格列宽可拖拽改变且兼容firfox
2014/09/03 Javascript
JS中事件冒泡和事件捕获介绍
2016/12/13 Javascript
通过sails和阿里大于实现短信验证
2017/01/04 Javascript
html5 canvas 详细使用教程
2017/01/20 Javascript
layui弹出层效果实现代码
2017/05/19 Javascript
关于javascript获取内联样式与嵌入式样式的实例
2017/06/01 Javascript
在vue项目中使用element-ui的Upload上传组件的示例
2018/02/08 Javascript
微信小程序与公众号卡券/会员打通的问题
2019/07/25 Javascript
小程序中的箭头函数的具体使用
2020/06/19 Javascript
Python 用Redis简单实现分布式爬虫的方法
2017/11/23 Python
Python绘制3d螺旋曲线图实例代码
2017/12/20 Python
python如何通过实例方法名字调用方法
2018/03/21 Python
pyqt5 键盘监听按下enter 就登陆的实例
2019/06/25 Python
pytorch masked_fill报错的解决
2020/02/18 Python
python数据预处理 :数据抽样解析
2020/02/24 Python
python安装读取grib库总结(推荐)
2020/06/24 Python
基于python模拟TCP3次握手连接及发送数据
2020/11/06 Python
python 实现一个简单的线性回归案例
2020/12/17 Python
定制iPhone和Macbook保护壳:Slick Case
2018/11/21 全球购物
卫校护理专业毕业生求职信
2013/11/26 职场文书
大学生军训自我鉴定
2014/02/12 职场文书
运动会演讲稿100字
2014/08/25 职场文书
2014年党的群众路线学习心得体会
2014/11/05 职场文书
父亲婚礼答谢词
2015/01/04 职场文书
JavaScript设计模式之原型模式详情
2022/06/21 Javascript