V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
oppddd
V2EX  ›  Node.js

用 nestjs 写微信的自动回复消息功能,一直报错?

  •  
  •   oppddd · 2022-11-10 19:49:55 +08:00 · 5642 次点击
    这是一个创建于 778 天前的主题,其中的信息可能已经有所发展或是发生改变。
    1. 为了收到微信服务器的 xml 信息,我写了个 xml 解析的中间件;
    import { Injectable, NestMiddleware } from '@nestjs/common'
    import { Request } from 'express'
    import * as xml2js from 'xml2js'
    
    const parseString = xml2js.parseString
    
    const parseXml = (xml: string): any => {
      return new Promise((resolve, reject) => {
        parseString(xml, { explicitArray: false }, function (err, result) {
          if (!err) {
            resolve(result)
          } else {
            reject(err)
            throw err
          }
        })
      })
    }
    
    @Injectable()
    export class XMLMiddleware implements NestMiddleware {
      use (req: Request, res: any, next: () => void) {
        const buffer = []
        req.on('data', (data) => {
          buffer.push(data)
        })
        req.on('end', async () => {
          console.log(req.query)
          const msgXml = Buffer.concat(buffer).toString('utf-8')
          const xmlData = await parseXml(msgXml)
          req.body = xmlData
          next()
        })
      }
    }
    
    1. 定义的 controller 如下
      @Public()
      @Post('callback')
      async postMsg (@Body() body: {xml: any}, @Req() req: Request, @Res() res: Response) {
        const xml = body.xml
        if (xml.MsgType.toLowerCase() === 'text') {
          const fromUserName = xml.FromUserName
          const toUserName = xml.ToUserName
          const content = xml.Content
          const replyXml = await this.weixinService.sendTextMsg(fromUserName, toUserName, content)
          console.log(replyXml)
          res.type('application/xml')
          res.end(replyXml)
        }
      }
    
    1. 当给微信发送消息的时候,是可以拿到微信服务器的 xml 消息的

    结果如下

    // query 信息
    {
      signature: '5bd7841d375e610c6c78f1219d910acf0e61549d',
      timestamp: '1668078826',
      nonce: '1894931224',
      openid: 'o2gkvuBvc_il-f0As0GjBzlqknJo'
    }
    // body 信息
    {
      xml: {
        ToUserName: 'gh_4440d1e4f1af',
        FromUserName: 'o2gkvuBvc_il-f0As0GjBzlqknJo',
        CreateTime: '1668078825',
        MsgType: 'text',
        Content: '123123',
        MsgId: '23881145195544631'
      }
    }
    
    

    所有实现感觉都没啥问题;但是就是回复不了信息

    返回信息如下

    // 收到 xml 信息
    {
      xml: {
        ToUserName: 'gh_4440d1e4f1af',
        FromUserName: 'o2gkvuBvc_il-f0As0GjBzlqknJo',
        CreateTime: '1668078825',
        MsgType: 'text',
        Content: '123123',
        MsgId: '23881145195544631'
      }
    }
    // 返回给微信服务器的信息;
    <xml><ToUserName><![CDATA[o2gkvuBvc_il-f0As0GjBzlqknJo]]></ToUserName><FromUserName><![CDATA[gh_4440d1e4f1af]]></FromUserName><CreateTime>1668078827925</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[123123]]></Content></xml>
    

    不知道是什么原因导致的回复不了!

    4 条回复    2022-11-11 09:57:16 +08:00
    oppddd
        1
    oppddd  
    OP
       2022-11-10 23:17:50 +08:00 via iPhone
    看了看 nest 文档 猜测是因为 post 的返回码都是 201 导致的,明天试试
    Giftina
        2
    Giftina  
       2022-11-11 09:42:15 +08:00
    给个 decorator:

    @Public()
    @Post('callback')
    @HttpCode(HttpStatus.OK) <--- 这个会返回 200
    async postMsg ......
    Giftina
        3
    Giftina  
       2022-11-11 09:43:55 +08:00
    试一下代码块

    ```typescript
    @Public()
    @Post('callback')
    @HttpCode(HttpStatus.OK) // <--- 这个会返回 200
    async postMsg ......
    ```
    oppddd
        4
    oppddd  
    OP
       2022-11-11 09:57:16 +08:00
    @Giftina 感谢回复,确实是因为 httpCode 引起的; 很容易踩坑,哈哈
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2576 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 10:37 · PVG 18:37 · LAX 02:37 · JFK 05:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.