You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express.js集成whatsapp-web.js遇404错误:接口无法访问求助

问题排查:Express + whatsapp-web.js 接口返回404错误

问题现象

使用Express.js结合whatsapp-web.js开发,手机扫码后控制台打印"READY",但向/sendmessage发送JSON请求、访问/getqr均返回404错误,已按官方文档使用LocalAuth适配多设备,无法定位问题。

核心错误原因

  1. Express实例创建顺序错误:原代码中const app = express()定义在client事件监听之后,导致client.on('qr')回调里挂载/getqr路由时,app变量尚未初始化,路由根本无法挂载成功。
  2. 路由挂载时机错误:将/getqr路由放在qr事件回调内,只有当触发QR码生成事件时才会尝试挂载路由,且即使触发,此时app可能已经启动监听,Express不会自动识别后续动态添加的路由。

修复方案

步骤1:调整代码结构,提前创建Express实例

将const app = express()移到代码最前面,确保所有路由挂载和中间件配置都基于已初始化的app实例。

步骤2:用变量存储QR码,统一挂载路由

定义全局变量存储QR码内容,在qr事件中更新该变量,提前在app上挂载/getqr路由,直接返回存储的QR码。

步骤3:清理冗余代码

原代码中保留的SESSION_FILE_PATH相关逻辑属于旧的文件认证方式,使用LocalAuth时无需保留,可直接删除。

修复后的完整代码

const express = require('express');
const createError = require('http-errors');
const morgan = require('morgan');
const { Client, LocalAuth } = require('whatsapp-web.js');
const qrcode = require('qrcode-terminal');
require('dotenv').config();

// 提前创建Express实例
const app = express();
// 全局变量存储QR码
let currentQrCode = null;

// 配置Express中间件
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(morgan('dev'));

// 初始化whatsapp-web.js客户端
const client = new Client({
  authStrategy: new LocalAuth({
    clientId: "client-one"
  }),
  puppeteer: {
    headless: false,
  }
});

client.initialize();

client.on('qr', qr => {
  console.log('QR RECEIVED', qr);
  qrcode.generate(qr, { small: true });
  // 更新全局QR码变量
  currentQrCode = qr;
});

client.on('authenticated', () => {
  console.log('WHATSAPP WEB => Authenticated');
});

client.on('auth_failure', msg => {
  console.error('AUTHENTICATION FAILURE', msg);
});

client.on('ready', () => {
  console.log('READY');
});

// 挂载/getqr路由
app.get('/getqr', (req, res) => {
  if (!currentQrCode) {
    return res.status(404).send({ message: '当前无可用QR码' });
  }
  res.send({ qr: currentQrCode });
});

// 挂载/sendmessage路由
app.post('/sendmessage', async (req, res, next) => {
  try {
    // 检查客户端是否已就绪
    if (!client.info) {
      return res.status(400).send({ message: 'WhatsApp客户端尚未就绪,请扫码后重试' });
    }
    const { number, message } = req.body;
    const msg = await client.sendMessage(`${number}@c.us`, message);
    res.send({ msg });
  } catch (error) {
    next(error);
  }
});

// 404处理中间件
app.use((req, res, next) => {
  next(createError.NotFound());
});

// 全局错误处理中间件
app.use((err, req, res) => {
  res.status(err.status || 500);
  res.send({
    status: err.status || 500,
    message: err.message,
  });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`🚀 服务启动于 http://localhost:${PORT}`));

额外注意事项

  • 使用LocalAuth时,会话数据会自动存储在项目根目录的.wwebjs_auth文件夹下,无需手动处理session文件。
  • 在/sendmessage接口中增加了客户端就绪检查,避免未扫码就发送消息导致的错误。
  • Express路由和中间件的挂载顺序很重要:中间件(如express.json())必须在路由之前挂载,否则无法解析请求体。

内容的提问来源于stack exchange,提问作者E.MRZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 10:32:27