详解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中转换URL字符串与查询字符串详解
Nov 26 NodeJs
nodejs中简单实现Javascript Promise机制的实例
Dec 06 NodeJs
轻松创建nodejs服务器(10):处理上传图片
Dec 18 NodeJs
nodejs实现HTTPS发起POST请求
Apr 23 NodeJs
Nodejs实战心得之eventproxy模块控制并发
Oct 27 NodeJs
Nodejs爬虫进阶教程之异步并发控制
Feb 15 NodeJs
Nodejs如何搭建Web服务器
Mar 28 NodeJs
浅析Nodejs npm常用命令
Jun 14 NodeJs
nodejs模块学习之connect解析
Jul 05 NodeJs
详解IWinter 一个路由转控制器的 Nodejs 库
Nov 15 NodeJs
NodeJs实现简单的爬虫功能案例分析
Dec 05 NodeJs
NodeJS读取分析Nginx错误日志的方法
May 14 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控制linux服务器常用功能 关机 重启 开新站点等
2012/09/05 PHP
php安装swoole扩展的方法
2015/03/19 PHP
PHP实现163邮箱自动发送邮件
2016/03/29 PHP
PHP自定义多进制的方法
2016/11/03 PHP
php 根据URL下载远程图片、压缩包、pdf等文件到本地
2019/07/26 PHP
解决Laravel5.5下的toArray问题
2019/10/15 PHP
入门基础学习 ExtJS笔记(一)
2010/11/11 Javascript
jQuery实现鼠标经过图片变亮其他变暗效果
2015/05/08 Javascript
vue中路由参数传递可能会遇到的坑
2017/12/07 Javascript
关于ES6箭头函数中的this问题
2018/02/27 Javascript
Angularjs 根据一个select的值去设置另一个select的值方法
2018/08/13 Javascript
JavaScript常见事件处理程序实例总结
2019/01/05 Javascript
新手如何快速理解js异步编程
2019/06/24 Javascript
JavaScript实现简单的图片切换功能(实例代码)
2020/04/10 Javascript
[02:11]2014DOTA2 TI专访VG战队Fenrir:队伍气氛良好
2014/07/11 DOTA
Tensorflow之构建自己的图片数据集TFrecords的方法
2018/02/07 Python
python实现支付宝当面付(扫码支付)功能
2018/05/30 Python
python添加模块搜索路径和包的导入方法
2019/01/19 Python
Pandas之MultiIndex对象的示例详解
2019/06/25 Python
Python3爬虫中Splash的知识总结
2020/07/10 Python
解决阿里云邮件发送不能使用25端口问题
2020/08/07 Python
HTML5 Canvas的性能提高技巧经验分享
2013/07/02 HTML / CSS
HTML5公共页面提取作为公用代码的方法
2020/06/30 HTML / CSS
ToysRus日本官网:玩具反斗城
2018/09/08 全球购物
C语言基础笔试题
2013/04/27 面试题
数据库的约束含义
2012/09/09 面试题
linux面试题参考答案(4)
2013/01/28 面试题
出纳工作岗位责任制
2014/02/02 职场文书
办公室岗位职责
2014/02/12 职场文书
行政办公室岗位职责
2014/03/18 职场文书
财产公证书样本
2014/04/04 职场文书
开展警示教育活动总结
2015/05/09 职场文书
环境保护宣传标语大全!
2019/06/28 职场文书
Python+Appium新手教程
2021/04/17 Python
简单聊聊Vue中的计算属性和属性侦听
2021/10/05 Vue.js
详解如何使用Nginx解决跨域问题
2022/05/06 Servers