• 技术文章 >web前端 >js教程

    如何操作Koa2微信公众号实现消息管理

    php中世界最好的语言php中世界最好的语言2018-05-29 11:15:19原创1378
    接收消息

    当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。

    2.1 接收普通消息数据格式

    XML的结构基本固定,不同的消息类型略有不同。

    用户发送文本消息时,微信公众账号接收到的XML数据格式如下所示:

    <xml>
     <ToUserName><![CDATA[toUser]]></ToUserName>
     <FromUserName><![CDATA[fromUser]]></FromUserName>
     <CreateTime>createTime</CreateTime>
     <MsgType><![CDATA[text]]></MsgType>
     <Content><![CDATA[this is a test]]></Content>
     <MsgId>1234567890123456</MsgId>
    </xml>

    用户发送图片消息时,微信公众账号接收到的XML数据格式如下所示:

    <xml> 
     <ToUserName><![CDATA[toUser]]></ToUserName>
     <FromUserName><![CDATA[fromUser]]></FromUserName>
     <CreateTime>1348831860</CreateTime> 
     <MsgType><![CDATA[image]]></MsgType> 
     <PicUrl><![CDATA[this is a url]]></PicUrl>
     <MediaId><![CDATA[media_id]]></MediaId> 
     <MsgId>1234567890123456</MsgId>
    </xml>

    其他消息消息类型的结构请查阅【微信公众平台开发文档】

    对于POST请求的处理,koa2没有封装获取参数的方法,需要通过自己解析上下文context中的原生node.js请求对象request。我们将用到row-body这个模块来拿到数据。

    2.2 先来优化之前的代码

    这一节的代码紧接着上一届实现的代码,在上一届的基础上轻微改动了下。

    'use strict'
    const Koa = require('koa')
    const app = new Koa()
    const crypto = require('crypto')
    // 将配置文件独立到config.js
    const config = require('./config')
    app.use(async ctx => {
     // GET 验证服务器
     if (ctx.method === 'GET') {
      const { signature, timestamp, nonce, echostr } = ctx.query
      const TOKEN = config.wechat.token
      let hash = crypto.createHash('sha1')
      const arr = [TOKEN, timestamp, nonce].sort()
      hash.update(arr.join(''))
      const shasum = hash.digest('hex')
      if (shasum === signature) {
       return ctx.body = echostr
      }
      ctx.status = 401
      ctx.body = 'Invalid signature'
     } else if (ctx.method === 'POST') { // POST接收数据
      // TODO
     }
    });
    app.listen(7001);

    这儿我们在只在GET中验证了签名值是否合法,实际上我们在POST中也应该验证签名。

    将签名验证写成一个函数

    function getSignature (timestamp, nonce, token) {
     let hash = crypto.createHash('sha1')
     const arr = [token, timestamp, nonce].sort()
     hash.update(arr.join(''))
     return hash.digest('hex')
    }

    优化代码,再POST中也加入验证

    ...
    app.use(async ctx => {
     const { signature, timestamp, nonce, echostr } = ctx.query
     const TOKEN = config.wechat.token
     if (ctx.method === 'GET') {
      if (signature === getSignature(timestamp, nonce, TOKEN)) {
       return ctx.body = echostr
      }
      ctx.status = 401
      ctx.body = 'Invalid signature'
     }else if (ctx.method === 'POST') {
      if (signature !== getSignature(timestamp, nonce, TOKEN)) {
       ctx.status = 401
       return ctx.body = 'Invalid signature'
      }
      // TODO
     }
    });
    ...

    到这儿我们都没有开始实现接受XML数据包的功能,而是在修改之前的代码。这是为了演示在实际开发中的过程,写任何代码都不是一步到位的,好的代码都是改出来的。

    2.3 接收公众号普通消息的XML数据包

    现在开始进入本节的重点,接受XML数据包并转为JSON

    $ npm install raw-body --save
    ...
    const getRawBody = require('raw-body')
    ...
    // TODO
    // 取原始数据
    const xml = await getRawBody(ctx.req, {
     length: ctx.request.length,
     limit: '1mb',
     encoding: ctx.request.charset || 'utf-8'
    });
    console.log(xml)
    return ctx.body = 'success' // 直接回复success,微信服务器不会对此作任何处理

    给你的测试号发送文本消息,你可以在命令行看见打印出如下数据

    <xml>
     <ToUserName><![CDATA[gh_9d2d49e7e006]]></ToUserName>
     <FromUserName><![CDATA[oBp2T0wK8lM4vIkmMTJfFpk6Owlo]]></FromUserName>
     <CreateTime>1516940059</CreateTime>
     <MsgType><![CDATA[text]]></MsgType>
     <Content><![CDATA[JavaScript之禅]]></Content>
     <MsgId>6515207943908059832</MsgId>
    </xml>

    恭喜,到此你已经可以接收到XML数据了。

    以上就是如何操作Koa2微信公众号实现消息管理的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:Koa2 实现 公众
    上一篇:jQuery实现新闻播报滚动及淡入淡出效果示例 下一篇:怎样使用js实现鼠标单击Tab表单切换
    Web大前端开发直播班

    相关文章推荐

    • 浅析Angular+rxjs怎么实现拖拽功能?• 值得了解的几个实用JavaScript优化小技巧• JavaScript学习理解之JSON(总结分享)• 你能搞懂JS的this指向问题吗?看看这篇文章• 一起聊聊JavaScript函数式编程

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网