欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解nodejs微信公众号开发——3.封装消息响应模块

程序员文章站 2022-04-29 12:49:31
上一篇文章:,实现了简单的关注回复。采用拼接字符串的形式,并不是很方便,这里我们将其封装承接口。 1. ejs模板引擎 不使用拼接字符串的方式,那么模板引擎就是...

上一篇文章:,实现了简单的关注回复。采用拼接字符串的形式,并不是很方便,这里我们将其封装承接口。

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快速入手攻略

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。