详解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 相关文章推荐
基于 Docker 开发 NodeJS 应用
Jul 30 NodeJs
使用nodejs下载风景壁纸
Feb 05 NodeJs
nodejs中向HTTP响应传送进程的输出
Mar 19 NodeJs
深入浅析Nodejs的Http模块
Jun 20 NodeJs
NodeJS收发GET和POST请求的示例代码
Aug 25 NodeJs
windows系统下更新nodejs版本的方案
Nov 24 NodeJs
Nodejs 发布自己的npm包并制作成命令行工具的实例讲解
May 15 NodeJs
深入理解NodeJS 多进程和集群
Oct 17 NodeJs
nodejs的安装使用与npm的介绍
Sep 11 NodeJs
Nodejs实现WebSocket代码实例
May 19 NodeJs
Nodejs 数组的队列以及forEach的应用详解
Feb 25 NodeJs
nodejs利用readline提示输入内容实例代码
Jul 15 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实现让页面只能被百度gogole蜘蛛访问的方法
2009/12/29 PHP
PHP生成腾讯云COS接口需要的请求签名
2018/05/20 PHP
PHP使用正则表达式实现过滤非法字符串功能示例
2018/06/04 PHP
PHP中的self关键字详解
2019/06/23 PHP
Laravel 之url参数,获取路由参数的例子
2019/10/21 PHP
JavaScript实现从数组中选出和等于固定值的n个数
2014/09/03 Javascript
jQuery 中$(this).index与$.each的使用指南
2014/11/20 Javascript
window.open()实现post传递参数
2015/03/12 Javascript
javascript实现鼠标拖动改变层大小的方法
2015/04/30 Javascript
微信内置浏览器私有接口WeixinJSBridge介绍
2015/05/25 Javascript
jQuery实现鼠标滚动图片延迟加载效果附源码下载
2016/06/28 Javascript
详解nodejs微信公众号开发——4.自动回复各种消息
2017/04/11 NodeJs
jquery实现企业定位式导航效果
2018/01/01 jQuery
详解在React里使用&quot;Vuex&quot;
2018/04/02 Javascript
vue中使用props传值的方法
2019/05/08 Javascript
vue-cli或vue项目利用HBuilder打包成移动端app操作
2020/07/29 Javascript
DWR内存兼容及无法调用问题解决方案
2020/10/16 Javascript
基于Vant UI框架实现时间段选择器
2020/12/24 Javascript
详解ES6实现类的私有变量的几种写法
2021/02/10 Javascript
解析Python中的生成器及其与迭代器的差异
2016/06/20 Python
FFT快速傅里叶变换的python实现过程解析
2019/10/21 Python
python ImageDraw类实现几何图形的绘制与文字的绘制
2020/02/26 Python
用Python制作mini翻译器的实现示例
2020/08/17 Python
神经网络训练采用gpu设置的方式
2021/03/03 Python
微软日本官方网站:Microsoft日本
2017/11/26 全球购物
泰国办公用品购物网站:OfficeMate
2018/02/04 全球购物
芬兰灯具网上商店:Nettilamppu.fi
2018/06/30 全球购物
解释一下ArrayList Vector和LinkedList的实现和区别
2013/04/26 面试题
合同专员岗位职责
2013/12/18 职场文书
技术副厂长岗位职责
2013/12/26 职场文书
晚会邀请函范文
2014/01/24 职场文书
给妈妈洗脚活动方案
2014/08/16 职场文书
小学生节水倡议书
2015/04/29 职场文书
经营场所证明范本
2015/06/19 职场文书
公司员工培训管理制度
2015/08/04 职场文书
2019年健身俱乐部的创业计划书
2019/08/26 职场文书