详解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打包工具整合到鼠标右键的方法
May 11 NodeJs
Google官方支持的NodeJS访问API,提供后台登录授权
Jul 29 NodeJs
Nodejs实现多人同时在线移动鼠标的小游戏分享
Dec 06 NodeJs
NodeJS中利用Promise来封装异步函数
Feb 25 NodeJs
nodejs开发——express路由与中间件
Mar 24 NodeJs
nodejs读取并去重excel文件
Apr 22 NodeJs
利用nodeJs anywhere搭建本地服务器环境的方法
May 12 NodeJs
NodeJS搭建HTTP服务器的实现步骤
Oct 12 NodeJs
详解nodejs 配置文件处理方案
Jan 02 NodeJs
nodejs实现获取本地文件夹下图片信息功能示例
Jun 22 NodeJs
独立部署小程序基于nodejs的服务器过程详解
Jun 24 NodeJs
用Nodejs实现在终端中炒股的实现
Oct 18 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
基于mysql的论坛(6)
2006/10/09 PHP
php fputcsv命令 写csv文件遇到的小问题(多维数组连接符)
2011/05/24 PHP
PHP正则表达式 /i, /is, /s, /isU等介绍
2014/10/23 PHP
PHP中$_SERVER使用说明
2015/07/05 PHP
WordPress中访客登陆实现邮件提醒的PHP脚本实例分享
2015/12/14 PHP
浅谈laravel orm 中的一对多关系 hasMany
2019/10/21 PHP
开发跨浏览器javascript常见注意事项
2009/01/01 Javascript
基于jquery实现的可以编辑选择的下拉框的代码
2010/11/19 Javascript
javascript插入样式实现代码
2012/02/22 Javascript
javascript重复绑定事件造成的后果说明
2013/03/02 Javascript
js replace 与replaceall实例用法详解
2013/08/03 Javascript
js导出table数据到excel即导出为EXCEL文档的方法
2013/10/10 Javascript
jQuery插件开发详细教程
2014/06/06 Javascript
JavaScript多线程详解
2015/08/12 Javascript
特殊日期提示功能的实现方法
2016/06/16 Javascript
微信小程序 教程之wxapp视图容器 swiper
2016/10/19 Javascript
Vue概念及常见命令介绍(1)
2016/12/08 Javascript
jquery.tableSort.js表格排序插件使用方法详解
2020/08/12 Javascript
JS与SQL方式随机生成高强度密码示例
2018/12/29 Javascript
使用 vue 实例更好的监听事件及vue实例的方法
2019/04/22 Javascript
通过实例了解Javascript柯里化流程
2020/03/03 Javascript
[01:02:32]DOTA2-DPC中国联赛 正赛 iG vs PSG.LGD BO3 第二场 2月26日
2021/03/11 DOTA
Django中login_required装饰器的深入介绍
2017/11/24 Python
对python3标准库httpclient的使用详解
2018/12/18 Python
利用pipenv和pyenv管理多个相互独立的Python虚拟开发环境
2020/11/01 Python
CSS3简单实现照片墙
2014/12/12 HTML / CSS
英国领先的高街书籍专家:Waterstones
2018/02/01 全球购物
override和overload的区别
2016/03/09 面试题
西式婚礼证婚词
2014/01/12 职场文书
cf收人广告词
2014/03/14 职场文书
秘书英文求职信
2014/04/16 职场文书
公司联欢会策划方案
2014/05/19 职场文书
政风行风评议工作总结
2014/10/21 职场文书
小学教研工作总结2015
2015/05/13 职场文书
python人工智能human learn绘图可创建机器学习模型
2021/11/23 Python
Spring Boot 底层原理基础深度解析
2022/04/03 Java/Android