用 Nestjs 写微信的自动回复消息功能,一直报错?Nodejs环境下如何解决

发布于 1周前 作者 sinazl 来自 nodejs/Nestjs

用 Nestjs 写微信的自动回复消息功能,一直报错?Nodejs环境下如何解决

  1. 为了收到微信服务器的 xml 信息,我写了个 xml 解析的中间件;
import { Injectable, NestMiddleware } from '[@nestjs](/user/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](/user/Public)()
  [@Post](/user/Post)('callback')
  async postMsg ([@Body](/user/Body)() body: {xml: any}, [@Req](/user/Req)() req: Request, [@Res](/user/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>

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


5 回复

看了看 nest 文档 猜测是因为 post 的返回码都是 201 导致的,明天试试


给个 decorator:

()
(‘callback’)
(HttpStatus.OK) <— 这个会返回 200
async postMsg …

试一下代码块

typescript<br>()<br>('callback')<br>(HttpStatus.OK) // &lt;--- 这个会返回 200<br>async postMsg ......<br>

感谢回复,确实是因为 httpCode 引起的; 很容易踩坑,哈哈

在使用 NestJS 实现微信自动回复消息功能时遇到报错,通常可能是由于几个常见问题引起的。以下是一些可能的解决步骤,并附带简单的代码示例来帮助你排查和解决问题。

  1. 确保微信开发者配置正确: 确保你已经正确配置了微信公众平台的开发者接口,包括服务器URL和Token。

  2. 使用官方SDK或API: 建议使用微信官方提供的SDK或API库来简化开发。如果没有现成的NestJS模块,可以考虑封装微信API。

  3. 错误处理: 检查你的代码中的错误处理逻辑,确保能够捕获并正确处理来自微信的响应。

以下是一个简单的NestJS控制器示例,用于处理微信消息并自动回复:

import { Controller, Post, Body } from '@nestjs/common';
import * as axios from 'axios';
import * as crypto from 'crypto';

@Controller('wechat')
export class WechatController {
  @Post('message')
  async handleMessage(@Body() body: any) {
    // 验证消息来自微信
    const signature = body.signature;
    const timestamp = body.timestamp;
    const nonce = body.nonce;
    const token = 'YOUR_TOKEN'; // 替换为你的Token

    const arr = [token, timestamp, nonce].sort();
    const str = arr.join('');
    const sha1 = crypto.createHash('sha1');
    sha1.update(str);
    const hashcode = sha1.digest('hex');

    if (hashcode !== signature) {
      return 'Invalid request';
    }

    // 回复消息
    const reply = {
      MsgType: 'text',
      Content: 'Hello, this is an auto reply!',
    };
    // 使用axios或其他HTTP库发送回复给微信服务器
    await axios.post(body.FromUserName, reply);
  }
}

确保替换YOUR_TOKEN为你在微信公众平台设置的Token,并处理HTTP请求的发送细节。希望这能帮助你解决问题!

回到顶部