美文网首页eiYo
使用koa2对接微信公众平台

使用koa2对接微信公众平台

作者: 胖乎乎的萝卜 | 来源:发表于2017-03-13 17:47 被阅读4776次

这几天心血来潮,想玩下微信公众平台,看看它是如何对接到个人服务器的。这里简单记录下。

环境:
  node v7.7.1
  koa  v2.0.1

流程

1.在微信公众平台的 开发 -> 基本配置 那填写服务器信息;

2.点击启用后,微信会发 Get 请求到填写的服务器,检查服务器是否有效;

3.服务器验证通过后,公众号每次接收到新消息,都会发 POST 请求到服务器,然后我们就可以在服务器里进行各种处理。

验证服务器

微信开发文档里有写验证的规则(这不是废话么):

verify.png

上面的文字已经写的很直白了,不多说,代码实现如下:

// 验证消息来自微信服务器
const crypto = require('crypto')
module.exports = (ctx) => {
    const token = 'xxxx', // 自定义,与公众号设置的一致
          signature = ctx.query.signature,
          timestamp = ctx.query.timestamp,
          nonce = ctx.query.nonce
        
    // 字典排序
    const arr = [token, timestamp, nonce].sort()

    const sha1 = crypto.createHash('sha1')
    sha1.update(arr.join(''))
    const result = sha1.digest('hex')

    if (result === signature) {
        ctx.body = ctx.query.echostr
    } else {
        ctx.body = { code: -1, msg: "fail"}
    }
}

处理 POST 请求

下面要处理接收消息的 POST 请求。因为消息的格式都是 XML ,所以这里需要引入 xml2js 。

接收 XML 数据

koa2 没有对 XML 格式的参数进行处理,这里需要我们自己来处理下,写的中间件如下:

// xmlTool.js
const xml2js = require('xml2js')

exports.xmlToJson = (str) => {
     return new Promise((resolve, reject) => {
        const parseString = xml2js.parseString
        parseString(str, (err, result) => {
            if (err) {
                reject(err)
            } else {
                resolve(result)
            }
        })
     })
}

exports.jsonToXml = (obj) => {
    const builder = new xml2js.Builder()
    return builder.buildObject(obj)
}

// xmlParse.js
const xml = require('./xmlTool')

module.exports = () => {
    return async (ctx, next) => {
        if (ctx.method == 'POST' && ctx.is('text/xml')) {
            let promise = new Promise(function (resolve, reject) {
                let buf = ''
                ctx.req.setEncoding('utf8')
                ctx.req.on('data', (chunk) => {
                    buf += chunk
                })
                ctx.req.on('end', () => {
                    xml.xmlToJson(buf)
                        .then(resolve)
                        .catch(reject)
                })
            })

            await promise.then((result) => {
                    ctx.req.body = result
                })
                .catch((e) => {
                    e.status = 400
                })

            next()
        } else {
            await next()
        }
    }
}

加上了这个中间件,我们就可以正确接收到 XML 格式的参数了。接收到的参数如下:

// console.log(buf) 
<xml>\n<ToUserName><![CDATA[toUser]]></ToUserName>\n<FromUserName><![CDATA[fromUser]]></FromUserName>\n<C
reateTime>12345678</CreateTime>\n<MsgType><![CDATA[text]]></MsgType>\n<Content><![CDATA[你好]]></Content>\n</x
ml>\n\n

// 转为JSON后
{ ToUserName: [ 'toUser' ],
  FromUserName: [ 'fromUser' ],
  CreateTime: [ '12345678' ],
  MsgType: [ 'text' ],
  Content: [ '你好' ] }

发送消息

接收到消息后,服务器需要在5s内返回消息,如果没内容返回,可以返回 success 或空字符串。下面是返回文本信息的例子:

// wx.js
exports.message = {
    text (msg, content) {
        return xml.jsonToXml({
            xml: {
                ToUserName: msg.FromUserName,
                FromUserName: msg.ToUserName,
                CreateTime: Date.now(),
                MsgType: msg.MsgType,
                Content: content
            }
        })
    }
}

// index.js
const wx = require('./wx')
exports.postHandle = (ctx, next) => {
    let msg,
        MsgType,
        result

    msg = ctx.req.body ? ctx.req.body.xml : ''

    if (!msg) {
        ctx.body = 'error request.'
        return;
    }
    
    MsgType = msg.MsgType[0]

    switch (MsgType) {
        case 'text':
            result = wx.message.text(msg, msg.Content)
            break;
        default: 
            result = 'success'
    }
    ctx.res.setHeader('Content-Type', 'application/xml')
    ctx.res.end(result)
}

这样子就可以返回文本信息啦~到这里已经把基本的流程走完。其他更多的操作可以看官方文档,加以修改就好。

公众号例子如下,目前只是实现了回复相同的文本内容:

qrcode_430.jpg

上面的代码已开源到https://github.com/cirplan/koa2-wechat 上,欢迎围观。

相关文章

  • 使用koa2对接微信公众平台

    这几天心血来潮,想玩下微信公众平台,看看它是如何对接到个人服务器的。这里简单记录下。 流程 1.在微信公众平台的 ...

  • 做微信登录前必须先了解的事情

    1. 微信公众平台与微信开放平台 微信登录分为微信开放平台和微信公众平台微信公众平台:指使用微信内置浏览器登录网站...

  • 章法网络教你学习微信公众平台开发?

    一:认识微信公众平台简介 使用微信公众平台之前,首先需要在微信官方网站注册微信公众账号。微信公众账号分为订阅号、服...

  • 微信公众平台的申请需要做什么

    要想使用微信公众平台就需要申请公众平台,那么微信公众平台的申请过程是怎样的? 微信平台申请需要注意些什么? 1. ...

  • 微信开发(基于PHP)Lesson 2

    微信官方接口分析 1.对接微信公众平台①获取API接口路径: 登录微信公众号(服务号即可)->开发者工具->开发者...

  • 【微信小程序】配置合法域名

    小程序的开发时,在接口对接开始时,需要在微信公众平台配置接口域名否则无法访问接口。 一、打开微信公众平台官网,登录...

  • 微信官方连续两个大动作,这两类人都嗨了!

    最近,微信团队和微信公众平台突然发布了两个公告,让经常使用微信公众号和微信小程序的用户拍手称快! 一、公众平台新增...

  • 公众号付费功能

    前天自己负责编辑的本会《黄河诗词》微信公众号收到平台发来的“公众平台邀请你使用付费功能”的通知,(微信公众...

  • 微达微信第三方平台源码免费下载

    源码简介 :本程序是免费的,大家可以下载学习使用。 适用范围:微信平台源码,微信公众平台源码,微信营销平台源码,微...

  • ios 微信支付集成

    1. 准备 微信平台分为微信公众平台和微信开放平台,公众平台是运营微信公众号的管理系统,开放平台主要针对app、网...

网友评论

  • Zzzz_dd17:我用EGG.js 写的 也是做的是 转发客服 也是要返回XML 格式的数据 但是微信上一直报错 说该公众号服务器出现故障
    胖乎乎的萝卜:这种一般是微信发的请求得不到正确响应~
  • 是龙也要趴着:我看你转换成json后值是数组,能否转成对象?
    是龙也要趴着:xml2json这个库不好用,调用C++库
    胖乎乎的萝卜:@龙LONG显林 需要的话直接用xml2json替换就好
    是龙也要趴着:xml2json用这个库重写一下文章吧
  • 读书的实习者:谢谢博主的分享,如果返回文本信息需要调用别的接口拿到相应的结果才能返回这个文本信息可以实现吗
    胖乎乎的萝卜:可以的哦,如果接口在5s内返回,直接拿了数据返回即可。
    如果接口5s内不能返回,则要先响应。具体看文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140543

    假如服务器无法保证在五秒内处理并回复,必须做出下述回复,这样微信服务器才不会对此作任何处理,并且不会发起重试(这种情况下,可以使用客服消息接口进行异步回复)

  • 5ec66e575529:博主,菜鸟问个问题,为什么获取xml数据要监听data事件才能获取呢(ctx.req.on('data')).ctx.request.body怎么获取不了,是不是bodyPaser中间件不支持?求解答
    5ec66e575529:@哈Q士 原来如此,感谢~
    胖乎乎的萝卜:koa对xml参数是没有处理的,express也是,都要另外加中间件

本文标题:使用koa2对接微信公众平台

本文链接:https://www.haomeiwen.com/subject/fglqnttx.html