为什么使用koa2搭建微信第三方公众平台的原因


Posted in Javascript onMay 16, 2018

在写之前我想先说说koa,koa相比express,在执行流程,以及组件方面优秀的多,koa本身没有提供过多的扩展组建,但是它便捷的组建扩展,可以让你自由的发挥,可以想写其他语言一样并行执行代码,如果说promise解放了繁琐的callback,那么 koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的回调函数嵌套,并极大地提升错误处理的效率。koa 不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手,nodejs的天生的异步处理流程,使得它很适合微信公众号这种频繁的消息互动,再加上pm2的多进程管理,可以说已经很大程度的满足大号的消息转发互动已经公众号内部红包玩法。

在使用koa2搭建微信第三方公众平台是,首先要解决的是如果获取微信返回的xml流,以及如何返回对应的XML体给微信。
由于本身koa不是一个框架,所以得益于网上众多的中间件,自己搭建了一个类似于express的框架,本框架已经开源,详情请看我的git地址:https://github.com/yxz1025/koa-lana,所有的微信接发消息均在此框架中,请读者自行下载!

好了,首先,我们看看如何获取微信返回的xml流:

======tool.js=====
//截获微信返回的xml流文件
const Promise = require('bluebird');
//普通post流转化为promise
var Tool = {
  convertPost: function(req) {
    let post_data = "";
    return new Promise(function(resolve, reject){
      req.on('data', function(chunk) {
        post_data += chunk;
      });

      req.on('end', function() {
        resolve(post_data);
      });
    });

  },
};
module.exports = Tool;

=====weichat.js======
//微信响应主体文件
const router = require('koa-router')();
const parseMessage = require('../common/parseMessage');
const config = require('../config');
const WXBizMsgCrypt = require('wechat-crypto');
const middleware = require('../model/middleware');
const validator = require('validator');
const Aes = require('../common/aes');
const Tool = require('../common/tool');
const cryptor = new WXBizMsgCrypt(config.component_config.token, config.component_config.key, config.component_config.component_appid);

//第三方授权路径 /:appid/callback  /wechat/100234/callback
router.post('/:appid/callback', async function(ctx, next) {
  let post_data = "";
  let req = ctx.req;
  post_data = await Tool.convertPost(req);
  let xml = parseMessage(post_data);
  let signature = cryptor.getSignature(ctx.query.timestamp, ctx.query.nonce, xml.encrypt);
  if (ctx.query.msg_signature != signature) {
    ctx.body = 'Auth failed!'; // 指纹码不匹配时返回错误信息,禁止后面的消息接受及发送
  }
  let message = middleware.decryptXml(xml);
  let appid = ctx.params.appid;
  message.appId = appid;
  //发送消息队列
  switch (message.msgType) {
    case 'text':
      //测试
      if (message.toUserName == "gh_3c884a361561") {
        if (message.content == "TESTCOMPONENT_MSG_TYPE_TEXT") {
          let text = middleware.text(message, message.content + "_callback");
          let reply = middleware.encryptXml(text);
          return ctx.body = reply;
        }
        let content = message.content;
        if (content.indexOf("QUERY_AUTH_CODE") != -1) {
          ctx.body = "";
          let code_li = content.split(":");
          await middleware.customSend(message.fromUserName, code_li[1]);
          return;
        }
      }
      let keywords = validator.trim(message.content).toLowerCase();
      let member_config = await middleware.getMemberConfig(message.toUserName, keywords);
      if (!member_config) {
        await middleware.sendMnsQuene(message);
        return ctx.body = "success";
      }else{
         //匹配成功
        message.packetsId = parseInt(member_config.hongbaoId);
        message.keywords = keywords;
        await middleware.sendMnsQuene(message);

        let data = {
          title: member_config.news_title || '点我领红包',
          description: member_config.description || '第一轮红包雨开始了,手快有,手慢无!',
          picurl: member_config.picurl || 'http://7xqomp.com2.z0.glb.qiniucdn.com/17269743.png'
        };
        let key = {
          fromUserName: message.fromUserName,
          toUserName: message.toUserName,
          keywords: keywords,
          appId: appid
        };
        key = JSON.stringify(key);
        key = Aes.encypt(key);
        key = Aes.base64_encode(key);

        //获取授权域名
        let auth_url = await middleware.packetDomain();
        data.url = "http://" + appid + "." + auth_url + "/redPackets/koulin?key=" + key;
        let news = middleware.news(message, [data]);
        let reply = middleware.encryptXml(news);
        ctx.body = reply; 
        return;       
      }
      break;
    case 'event':
      await middleware.sendMnsQuene(message);
      //测试专用
      if (message.toUserName == "gh_3c884a361561") {
        let text = middleware.text(message, message.event + "from_callback");
        let reply = middleware.encryptXml(text);
        ctx.body = reply;
        return;
      }
      break;
    default:
      await middleware.sendMnsQuene(message);
      ctx.body = "success";
      return;

  };
});
module.exports = router;

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

Javascript 相关文章推荐
使用Modello编写JavaScript类
Dec 22 Javascript
Three.js源码阅读笔记(基础的核心Core对象)
Dec 27 Javascript
JavaScript Promise启示录
Aug 12 Javascript
JavaScript模块化之使用requireJS按需加载
Apr 12 Javascript
webpack+vue中使用别名路径引用静态图片地址
Nov 20 Javascript
基于bootstrap写的一点localStorage本地储存
Nov 21 Javascript
深入理解Node module模块
Mar 26 Javascript
微信小程序引用iconfont图标的方法
Oct 22 Javascript
新手快速上手webpack4打包工具的使用详解
Jan 28 Javascript
Vue组件内部实现一个双向数据绑定的实例代码
Apr 04 Javascript
详解使用WebPack搭建React开发环境
Aug 06 Javascript
JQuery实现折叠式菜单的详细代码
Jun 03 jQuery
详解基于Koa2开发微信二维码扫码支付相关流程
May 16 #Javascript
AngularJS标签页tab选项卡切换功能经典实例详解
May 16 #Javascript
解决Mac node版本升级失败的问题
May 16 #Javascript
在Mac下彻底卸载node和npm的方法
May 16 #Javascript
完美解决linux下node.js全局模块找不到的情况
May 16 #Javascript
AngularJS中的作用域实例分析
May 16 #Javascript
element-ui 限制日期选择的方法(datepicker)
May 16 #Javascript
You might like
php一些公用函数的集合
2008/03/27 PHP
php定时删除文件夹下文件(清理缓存文件)
2013/01/23 PHP
php生成唯一数字id的方法汇总
2015/11/18 PHP
Yii2第三方类库插件Imagine的安装和使用
2017/07/06 PHP
php判断电子邮件是否正确方法
2018/12/04 PHP
JavaScript 验证浏览器是否支持javascript的方法小结
2009/05/17 Javascript
JS解析XML的实现代码
2009/11/12 Javascript
javascript检测页面是否缩放的小例子
2013/05/16 Javascript
jquery ajax修改全局变量示例代码
2013/11/08 Javascript
利用jq让你的div居中的好方法分享
2013/11/21 Javascript
JavaScript程序员应该知道的45个实用技巧
2014/03/04 Javascript
推荐9款炫酷的基于jquery的页面特效
2014/12/07 Javascript
js实现跨域的几种方法汇总(图片ping、JSONP和CORS)
2015/10/25 Javascript
jquery插件uploadify实现带进度条的文件批量上传
2015/12/13 Javascript
jQuery Ajax使用FormData对象上传文件的方法
2016/09/07 Javascript
快速搭建React的环境步骤详解
2017/11/06 Javascript
JS常用排序方法实例代码解析
2020/03/03 Javascript
Python学习资料
2007/02/08 Python
Python实现随机生成有效手机号码及身份证功能示例
2017/06/05 Python
Python实现自动上京东抢手机
2018/02/06 Python
python下解压缩zip文件并删除文件的实例
2018/04/24 Python
python 实现在Excel末尾增加新行
2018/05/02 Python
Python实现快速计算词频功能示例
2018/06/25 Python
python 处理微信对账单数据的实例代码
2019/07/19 Python
python调用API接口实现登陆短信验证
2020/05/10 Python
Python执行时间的几种计算方法
2020/07/31 Python
印度尼西亚最大的电商平台:Tokopedia(印尼版淘宝)
2017/12/02 全球购物
优纳科技软件测试面试题
2012/05/15 面试题
《落花生》教学反思
2014/02/25 职场文书
3的组成教学反思
2014/04/30 职场文书
解除劳动合同证明书模板
2014/11/20 职场文书
民主评议党员个人自我评价
2015/03/03 职场文书
MYSQL主从数据库同步备份配置的方法
2021/05/26 MySQL
Java实现聊天机器人完善版
2021/07/04 Java/Android
Python函数中apply、map、applymap的区别
2021/11/27 Python
解决IIS7下无法绑定https主机的问题
2022/04/29 Servers