详解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 07 NodeJs
nodejs教程 安装express及配置app.js文件的详细步骤
May 11 NodeJs
nodejs中使用monk访问mongodb
Jul 06 NodeJs
抛弃Nginx使用nodejs做反向代理服务器
Jul 17 NodeJs
nodejs中转换URL字符串与查询字符串详解
Nov 26 NodeJs
ubuntu下安装nodejs以及升级的办法
May 08 NodeJs
利用nodejs监控文件变化并使用sftp上传到服务器
Feb 18 NodeJs
nodejs更新package.json中的dependencies依赖到最新版本的方法
Oct 10 NodeJs
Nodejs实现多文件夹文件同步
Oct 17 NodeJs
nodejs dgram模块广播+组播的实现示例
Nov 04 NodeJs
nodejs nedb 封装库与使用方法示例
Feb 06 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之第二天
2006/10/09 PHP
PHP分页显示制作详细讲解
2006/12/05 PHP
phpmailer发送gmail邮件实例详解
2013/06/24 PHP
php 解决substr()截取中文字符乱码问题
2016/07/18 PHP
使用PHPMailer发送邮件实例
2017/02/15 PHP
PHP基于堆栈实现的高级计算器功能示例
2017/09/15 PHP
PHP使用Nginx实现反向代理
2017/09/20 PHP
php封装db类连接sqlite3数据库的方法实例
2017/12/19 PHP
在laravel中使用with实现动态添加where条件
2019/10/10 PHP
自动设置iframe大小的jQuery代码
2013/09/11 Javascript
js实现二代身份证号码验证详解
2014/11/20 Javascript
JavaScript中reduce()方法的使用详解
2015/06/09 Javascript
PHP+jQuery+Ajax+Mysql如何实现发表心情功能
2015/08/06 Javascript
JS实现网页游戏中滑块响应鼠标点击移动效果
2015/10/19 Javascript
javascript中return,return true,return false三者的用法及区别
2015/11/17 Javascript
Jquery-1.9.1源码分析系列(十一)之DOM操作
2015/11/25 Javascript
JavaScript代码生成PDF文件的方法
2016/02/26 Javascript
手机图片预览插件photoswipe.js使用总结
2016/08/25 Javascript
JavaScript中object和Object的区别(详解)
2017/02/27 Javascript
利用vue.js实现被选中状态的改变方法
2018/02/08 Javascript
解决vue 路由变化页面数据不刷新的问题
2018/03/13 Javascript
js实现点击按钮复制文本功能
2020/07/20 Javascript
js动态引入的四种方法
2018/05/05 Javascript
微信小程序模拟cookie的实现
2018/06/20 Javascript
为vue项目自动设置请求状态的配置方法
2019/06/09 Javascript
使用python3+xlrd解析Excel的实例
2018/05/04 Python
从django的中间件直接返回请求的方法
2018/05/30 Python
Flask框架钩子函数功能与用法分析
2019/08/02 Python
python torch.utils.data.DataLoader使用方法
2020/04/02 Python
Python新手学习装饰器
2020/06/04 Python
Joseph官网:英国小众奢侈品牌
2019/05/17 全球购物
怎样写演讲稿
2014/01/04 职场文书
信息专业学生学习的自我评价
2014/02/17 职场文书
酒店收银员岗位职责
2015/04/07 职场文书
MySql 8.0及对应驱动包匹配的注意点说明
2021/06/23 MySQL
Java 数组的使用
2022/05/11 Java/Android