详解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使用mysql模块之获得更新和删除影响的行数的方法
Mar 18 NodeJs
Nodejs极简入门教程(二):定时器
Oct 25 NodeJs
nodejs教程之异步I/O
Nov 21 NodeJs
轻松创建nodejs服务器(4):路由
Dec 18 NodeJs
NodeJS学习笔记之Connect中间件模块(一)
Jan 27 NodeJs
nodejs实现获取当前url地址及url各种参数值
Jun 25 NodeJs
快速掌握Node.js之Window下配置NodeJs环境
Mar 21 NodeJs
浅析 NodeJs 的几种文件路径
Jun 07 NodeJs
浅谈nodejs中的类定义和继承的套路
Jul 26 NodeJs
详解nodejs 配置文件处理方案
Jan 02 NodeJs
基于Koa(nodejs框架)对json文件进行增删改查的示例代码
Feb 02 NodeJs
在NodeJs中使用node-schedule增加定时器任务的方法
Jun 08 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生成shtml类用法实例
2014/12/09 PHP
PHP序列化和反序列化深度剖析实例讲解
2020/12/29 PHP
分享2个jQuery插件--jquery.fileupload与artdialog
2014/12/26 Javascript
jQuery中:checkbox选择器用法实例
2015/01/03 Javascript
javascript中for/in循环及使用技巧
2015/09/01 Javascript
SWFUpload多文件上传及文件个数限制的方法
2016/05/31 Javascript
jQuery 选择器(61种)整理总结
2016/09/26 Javascript
javascript 使用正则test( )第一次是 true,第二次是false
2017/02/22 Javascript
Vue.js 2.0学习教程之从基础到组件详解
2017/04/24 Javascript
解决bootstrap中使用modal加载kindeditor时弹出层文本框不能输入的问题
2017/06/05 Javascript
javascript面向对象程序设计实践常用知识点总结
2019/07/29 Javascript
vue 组件开发原理与实现方法详解
2019/11/29 Javascript
jQuery实现可编辑的表格
2019/12/11 jQuery
使用node.JS中的url模块解析URL信息
2020/02/06 Javascript
小程序实现上传视频功能
2020/08/18 Javascript
python中的计时器timeit的使用方法
2017/10/20 Python
Python之lambda匿名函数及map和filter的用法
2019/03/05 Python
python导入pandas具体步骤方法
2019/06/23 Python
Pytorch之保存读取模型实例
2019/12/30 Python
python tkinter GUI绘制,以及点击更新显示图片代码
2020/03/14 Python
python针对Oracle常见查询操作实例分析
2020/04/30 Python
Python xml、字典、json、类四种数据类型如何实现互相转换
2020/05/27 Python
keras 多gpu并行运行案例
2020/06/10 Python
python中导入 train_test_split提示错误的解决
2020/06/19 Python
python 第三方库paramiko的常用方式
2021/02/20 Python
海信商城:海信电视、科龙空调、容声冰箱官方专卖
2017/02/07 全球购物
澳洲女装时尚在线:Blue Bungalow
2018/05/05 全球购物
中软国际Java程序员笔试题
2014/07/19 面试题
党员2014两会学习心得体会
2014/03/17 职场文书
医药销售自荐书
2014/05/29 职场文书
市场营销策划方案
2014/06/11 职场文书
关于青春的演讲稿500字
2014/08/22 职场文书
2015年个人自我剖析材料
2014/12/29 职场文书
2015羊年春节慰问信
2015/02/14 职场文书
婚庆主持词大全
2015/06/30 职场文书
用Python写一个简易版弹球游戏
2021/04/13 Python