详解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极简入门教程(二):定时器
Oct 25 NodeJs
nodeJs爬虫获取数据简单实现代码
Mar 29 NodeJs
NodeJs的优势和适合开发的程序
Aug 14 NodeJs
nodejs开发——express路由与中间件
Mar 24 NodeJs
NodeJS创建最简单的HTTP服务器
May 15 NodeJs
NodeJS安装图文教程
Apr 19 NodeJs
NodeJs项目中关闭ESLint的方法
Aug 09 NodeJs
nodejs更新package.json中的dependencies依赖到最新版本的方法
Oct 10 NodeJs
nodejs实现范围请求的实现代码
Oct 12 NodeJs
独立部署小程序基于nodejs的服务器过程详解
Jun 24 NodeJs
NodeJS实现一个聊天室功能
Nov 25 NodeJs
nodejs+koa2 实现模仿springMVC框架
Oct 21 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
生成缩略图
2006/10/09 PHP
dedecms中常见问题修改方法总结
2007/03/21 PHP
php中的MVC模式运用技巧
2007/05/03 PHP
php快递单号查询接口使用示例
2014/05/05 PHP
CI框架常用经典操作类总结(路由,伪静态,分页,session,验证码等)
2016/11/21 PHP
js判断输入是否为正整数、浮点数等数字的函数代码
2010/11/17 Javascript
基于jQuery的简单的列表导航菜单
2011/03/02 Javascript
Jquery颜色选择器ColorPicker实现代码
2012/11/14 Javascript
JavaScript中setTimeout的那些事儿
2016/11/14 Javascript
详解使用Vue.Js结合Jquery Ajax加载数据的两种方式
2017/01/10 Javascript
浅谈JavaScript异步编程
2017/01/20 Javascript
JS实现的二叉树算法完整实例
2017/04/06 Javascript
vue中的watch监听数据变化及watch中各属性的详解
2018/09/11 Javascript
3分钟读懂移动端rem使用方法(推荐)
2019/05/06 Javascript
js实现图片实时时钟
2020/01/15 Javascript
微信小程序调用wx.getImageInfo遇到的坑解决
2020/05/31 Javascript
JS如何实现封装列表右滑动删除收藏按钮
2020/07/23 Javascript
[01:20]辉夜杯背景故事宣传片《辉夜传说》
2015/12/25 DOTA
SQLite3中文编码 Python的实现
2017/01/11 Python
Python编程生成随机用户名及密码的方法示例
2017/05/05 Python
python正则表达式re之compile函数解析
2017/10/25 Python
Python3 操作符重载方法示例
2017/11/23 Python
Tensorflow中的placeholder和feed_dict的使用
2018/07/09 Python
django+mysql的使用示例
2018/11/23 Python
Python计算库numpy进行方差/标准方差/样本标准方差/协方差的计算
2018/12/28 Python
python实现按关键字筛选日志文件
2019/12/24 Python
使用pandas实现筛选出指定列值所对应的行
2020/12/13 Python
Clarins娇韵诗美国官网:法国天然护肤品牌
2016/09/26 全球购物
PHP面试题集
2016/12/18 面试题
教师自我剖析材料(群众路线)
2014/09/29 职场文书
个人欠条范本
2015/07/03 职场文书
2016大学生求职自荐信范文
2016/01/28 职场文书
Redis Cluster 集群搭建你会吗
2021/08/04 Redis
浅谈Redis跟MySQL的双写问题解决方案
2022/02/24 Redis
你真的会用Mysql的explain吗
2022/03/31 MySQL
python实现手机推送 代码也就10行左右
2022/04/12 Python