详解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教程 安装express及配置app.js文件的详细步骤
May 11 NodeJs
NodeJS学习笔记之Connect中间件模块(一)
Jan 27 NodeJs
windows下安装nodejs及框架express
Aug 07 NodeJs
NodeJS实现阿里大鱼短信通知发送
Jan 17 NodeJs
使用 NodeJS+Express 开发服务端的简单介绍
Apr 07 NodeJs
nodejs个人博客开发第六步 数据分页
Apr 12 NodeJs
nodejs实现简单的gulp打包
Dec 21 NodeJs
Nodejs连接mysql并实现增、删、改、查操作的方法详解
Jan 04 NodeJs
nodejs require js文件入口,在package.json中指定默认入口main方法
Oct 10 NodeJs
Nodejs 微信小程序消息推送的实现
Jan 20 NodeJs
nodejs处理tcp连接的核心流程
Feb 26 NodeJs
ubuntu系统下使用pm2设置nodejs开机自启动的方法
May 12 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带密码功能并下载远程文件保存本地指定目录 修改加强版
2010/05/16 PHP
php实例分享之html转为rtf格式
2014/06/02 PHP
php实现utf-8转unicode函数分享
2015/01/06 PHP
CodeIgniter框架验证码类库文件与用法示例
2017/03/18 PHP
php mysql PDO 查询操作的实例详解
2017/09/23 PHP
PHP使用ActiveMQ实例
2018/02/05 PHP
PHP生成二维码与识别二维码的方法详解【附源码下载】
2019/03/07 PHP
Laravel中正确地返回HTTP状态码方法示例
2019/09/10 PHP
分享8个Laravel模型时间戳使用技巧小结
2020/02/12 PHP
实现复选框全选/全不选切换
2006/12/23 Javascript
通过jquery实现tab标签浏览效果
2007/02/20 Javascript
JS实多级联动下拉菜单类,简单实现省市区联动菜单!
2007/05/03 Javascript
IE浏览器打印的页眉页脚设置解决方法
2009/12/08 Javascript
JQuery.closest(),parent(),parents()寻找父结点
2012/02/17 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(二)人物行走的实现
2013/01/23 Javascript
js简易namespace管理器 实例代码
2013/06/21 Javascript
JS+CSS实现六级网站导航主菜单效果
2015/09/28 Javascript
jQuery选择器用法实例详解
2015/12/17 Javascript
js 实现数值的千分位及保存小数方法(推荐)
2016/08/01 Javascript
angular源码学习第一篇 setupModuleLoader方法
2016/10/20 Javascript
js每隔两秒输出数组中的一项(实例)
2017/05/28 Javascript
nodejs构建本地web测试服务器 如何解决访问静态资源问题
2017/07/14 NodeJs
js编写简易的计算器
2020/07/29 Javascript
浅谈Pandas 排序之后索引的问题
2018/06/07 Python
django 简单实现登录验证给你
2019/11/06 Python
pytorch-RNN进行回归曲线预测方式
2020/01/14 Python
Python下载的11种姿势(小结)
2020/11/18 Python
深入浅出CSS3 background-clip,background-origin和border-image教程
2011/01/27 HTML / CSS
在阿尔卑斯山或希腊度过快乐假期:Alpine Elements
2019/12/28 全球购物
什么是抽象
2015/12/13 面试题
房屋改造计划书
2014/01/10 职场文书
优秀少先队辅导员先进事迹材料
2014/05/18 职场文书
社区志愿者活动总结
2014/06/26 职场文书
《比尾巴》教学反思
2016/02/24 职场文书
创业计划书之家教中心
2019/09/25 职场文书
Python编解码问题及文本文件处理方法详解
2021/06/20 Python