项目简介
Baileys 是一个基于 WebSocket 的 TypeScript 库,用于与 WhatsApp Web API 交互。它支持 Node.js、Deno 和 Bun,常用于构建自定义 WhatsApp 客户端和自动化工具。该项目与 WhatsApp 无关联,采用 MIT 许可。
README 预览
\n\n\n> [!CAUTION]\n> NOTICE OF BREAKING CHANGE.\n>\n> As of 7.0.0, multiple breaking changes were introduced into the library.\n>\n> Please check out https://whiskey.so/migrate-latest for more information.\n\nBaileys is a WebSockets-based TypeScript library for interacting with the WhatsApp Web API.\n\nJoin the WhiskeySockets community via the link: https://whiskey.so/discord\n\n# Usage & Guide\n\n> [!IMPORTANT]\n> The new guide is a work in progress. Expect missing pages/content. [Report missing or incorrect content.](https://github.com/WhiskeySockets/baileys.wiki-site/issues/new)\n>\n> **You can still access the old guide here:** [README.md](https://github.com/WhiskeySockets/Baileys/tree/master/README.md), or the [NPM homepage](https://npmjs.com/package/baileys).\n\nThe new guide is posted at https://baileys.wiki .\n\n# Get Support\n\nIf you'd like business to enterprise-level support from Rajeh, the current maintainer of Baileys, you can book a video chat. Book a 1 hour time slot by contacting him on Discord or pre-ordering [here](https://purpshell.dev/book). The earlier you pre-order the better, as his time slots usually fill up very quickly. He offers immense value per hour and will answer all your questions before the time runs out.\n\nIf you are a business, we encourage you to contribute back to the high development costs of the project and to feed the maintainers who dump tens of hours a week on this. You can do so by booking meetings or sponsoring below. All support, even in bona fide / contribution hours, is welcome by businesses of all sizes. This is not condoning or endorsing businesses to use the library. See the Disclaimer below.\n\n# Sponsor\n\nIf you'd like to financially support this project, you can do so by supporting the current maintainer [here](https://purpshell.dev/sponsor).\n\n# Disclaimer\n> [!CAUTION]\n> This project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with WhatsApp or any of its subsi
常见问题 (5)
故障排除如何修复 Baileys downloadMediaMessage 在媒体下载连接断开时无限期挂起或因 'TypeError: terminated' uncaughtException 而崩溃的问题?
这是 Baileys 中的一个 bug(已在 7.0.0-rc13/rc14 及 master 分支上确认):src/Utils/messages-media.ts 中的 downloadEncryptedContent(约第 652 行)在通过管道传输 undici 响应流时,没有附加 'error' 监听器。当连接在响应体传输中途被切断时,undici 会在源流上抛出 TypeError: terminated——由于 .pipe() 不会转发错误,这会变成进程级的 uncaughtException,并且目标流永远不会结束,因此 await downloadMediaMessage(msg, 'buffer') 既不会 resolve 也不会 reject,for await 迭代将永远挂起。
**修复方法(给库打补丁):** 在 src/Utils/messages-media.ts 中,将:
return fetched.pipe(output, { end: true })改为:
fetched.on('error', err => output.destroy(err))
return fetched.pipe(output, { end: true })或者改用
stream.pipeline(fetched, output, () => {}),它在设计上就会转发错误并清理源流。
**应用方法:** 由于该修复位于 npm 包内部,请使用 patch-package(或 pnpm 的 pnpm patch)来持久化此更改:以同样的方式编辑 node_modules/baileys/lib/Utils/messages-media.js,然后运行 npx patch-package baileys。应用此补丁后,返回的流会在消费端以 TypeError: terminated 触发 reject,这样你现有的包裹 downloadMediaMessage 的 try/catch 就能捕获该失败并进行重试,而不是让进程崩溃或消息处理器无声地卡住。
**在上游修复之前的防御性编程:** 为媒体下载加上你自己的超时机制(例如用 Promise.race 与计时器竞速),因为未打补丁的流可能无限期挂起;并添加 process.on('uncaughtException') 处理器作为最后手段,防止 undici 错误杀死进程。该变通方案已在 Baileys 7.0.0-rc14 搭配 Node 24 的生产环境中验证通过。
故障排除如何修复使用 Baileys 连接后立即发送图片时出现的 "Connection Closed" 错误?
这是因为图片上传会调用 refreshMediaConn(),该方法会查询 socket,而此时 WebSocket 可能仍处于 CONNECTING 状态(readyState=0),导致 sendRawMessage 抛出 Boom('Connection Closed')。文本消息很少遇到此问题,因为它们只需要一次往返。修复方法:在发送媒体之前等待 socket 完全打开:
await sock.waitForSocketOpen();
await sock.sendMessage(jid, { image, caption });
waitForSocketOpen() 在 socket 打开后立即 resolve,如果仍在连接中则会等待,如果已关闭或正在关闭则抛出异常。已在 @whiskeysockets/baileys 6.7.24 上验证——添加等待后,消息投递始终成功。
故障排除如何修复 Baileys communityMetadata 抛出 "Cannot read properties of undefined (reading 'attrs')" 错误?
此 bug 影响 @whiskeysockets/baileys@7.0.0-rc.14 以及当前的 master 分支。extractCommunityMetadata() 期望返回 <community> 节点,但 WhatsApp 可能返回 <group> 节点,因此非空断言失败,community.attrs 抛出异常。
临时解决方案:使用相同的 community JID 调用 groupMetadata()。community JID 就是一个普通的 @g.us JID,该方法会返回所需的元数据,包括与 community 相关的字段:
const meta = await sock.groupMetadata(communityJid)
对于描述更新,使用 group 对应的等效方法:
await sock.groupUpdateDescription(communityJid, newDescription)
永久修复方案:更新 community 元数据解析器,使其接受任意一种响应结构,并在两种节点都缺失时抛出已分类的错误:
const community =
getBinaryNodeChild(result, 'community') ??
getBinaryNodeChild(result, 'group')
if (!community) {
throw new Boom('community metadata response carried no <community> or <group> node', {
data: result,
})
}
同样的错误假设也影响了 communityUpdateDescription() 和 communityGetInviteInfo();communityFetchAllParticipating() 可能因同样的原因静默返回 {}。
故障排除如何修复 Baileys 中登录前调用 sendMessageAck 时报错 "Cannot read properties of undefined (reading 'id')" 的问题?
在 Baileys 7.0.0-rc13/rc14 中,sendMessageAck 会在登录之前读取 authState.creds.me.id,但 creds.me 只有在配对完成后才会被填充。请将 src/Socket/messages-recv.ts 中的调用改为使用可选链:
- const stanza = buildAckStanza(node, errorCode, authState.creds.me.id);
+ const stanza = buildAckStanza(node, errorCode, authState.creds.me?.id);
buildAckStanza 已经可以处理为假值的 meId;登录前的 notification ACK 并不需要 from 属性。在修复版本发布之前,请重新构建该包,或使用 patch-package。这可以解决隐藏的 TypeError 以及具有误导性的 failed to ack notification { ackErr: {} } 日志。但它本身并不能修复 QR 配对问题或未处理的 companion_reg_refresh 通知。
故障排除如何修复向已映射 LID 的电话号码 JID 发送一对一消息时出现的 WhatsApp ERROR 463?
在向 @s.whatsapp.net PN JID 发送 1:1 消息之前,先通过 Baileys 的本地 LID 映射进行解析:调用 signalRepository.lidMapping.getLIDForPN(pn)。如果返回了 LID,则将消息发送到 <lid>@lid 而不是 PN JID,并将原始 PN 保留为 remoteJidAlt 元数据。例如,当该映射存在时,将 19178056839@s.whatsapp.net 路由到 148373990592755@lid。这可以避免带有 messageStubParameters: ["463"] 的异步 messages.update 拒绝,并应产生正常的 SERVER_ACK/DELIVERY_ACK 响应。如果不存在本地 LID 映射,则保留现有的 PN 解析路径,而不是强制执行隐式的 USync。上游修复在发送/中继路径中实现了此 PN 到 LID 的解析。