OpenSource-Hub

Baileys

ライブラリ

WhiskeySockets/Baileys

WhatsApp Web API用のWebSocketベースのTypeScriptライブラリ。

概要

Baileys は、WhatsApp Web API とやり取りするための WebSocket ベースの TypeScript ライブラリです。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

FAQ (5)

トラブル対応
メディアのダウンロード接続が切断されたときに、Baileys の downloadMediaMessage がいつまでもハングしたり、'TypeError: terminated' uncaughtException でクラッシュしたりする問題を修正する方法

これは Baileys のバグです(7.0.0-rc13/rc14 および master で確認済み):src/Utils/messages-media.ts(652行目付近)にある downloadEncryptedContent は、'error' リスナーをアタッチしないまま undici のレスポンスストリームをパイプしています。接続がボディの途中で切断されると、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 の環境で本番運用により検証済みです。

参照 Issue #2750
トラブル対応
Baileysで接続直後に画像を送信する際に発生する 'Connection Closed' エラーの修正方法は?

これは、画像のアップロード時に refreshMediaConn() が呼び出されることが原因で発生します。この関数は、WebSocket がまだ CONNECTING 状態(readyState=0)にある可能性があるタイミングでソケットにクエリを実行するため、sendRawMessage が Boom('Connection Closed') をスローします。テキストメッセージは1回のラウンドトリップで済むため、この問題が発生することはほとんどありません。修正方法:メディアを送信する前に、ソケットが完全に開くまで待機します:

await sock.waitForSocketOpen();
await sock.sendMessage(jid, { image, caption });

waitForSocketOpen() は、ソケットが開いた時点で resolve され、まだ接続中の場合は待機し、closed/closing の場合はスローします。@whiskeysockets/baileys 6.7.24 で検証済みです — 待機を追加した後、送信は常に成功するようになりました。

参照 Issue #2821
トラブル対応
Baileys の communityMetadata が "Cannot read properties of undefined (reading 'attrs')" をスローする場合の修正方法

このバグは @whiskeysockets/baileys@7.0.0-rc.14 と現在の master に影響します。extractCommunityMetadata() は <community> ノードを想定していますが、WhatsApp が <group> ノードを返すことがあるため、非 null アサーションが失敗し、community.attrs で例外がスローされます。

暫定的な回避策: 同じコミュニティ JID を指定して groupMetadata() を呼び出してください。コミュニティ JID は通常の @g.us JID であり、これによりコミュニティ関連フィールドを含む必要なメタデータが返されます:

const meta = await sock.groupMetadata(communityJid)

説明の更新には、グループ相当のメソッドを使用してください:

await sock.groupUpdateDescription(communityJid, newDescription)

恒久対策: コミュニティメタデータのパーサーを更新し、どちらのレスポンス形式も受け入れられるようにして、両方とも存在しない場合は分類されたエラーをスローするようにします:

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() も同じ理由で暗黙的に {} を返す可能性があります。

参照 Issue #2753
トラブル対応
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 は falsy な meId をすでに処理しており、ログイン前の notification ACK には from 属性は必要ありません。修正がリリースされるまでは、パッケージを再ビルドするか patch-package を使用してください。これにより、隠れていた TypeError と誤解を招く failed to ack notification { ackErr: {} } ログが解消されます。なお、これだけでは QR ペアリングや未処理の companion_reg_refresh 通知は修正されません。

参照 Issue #2738
トラブル対応
マッピングされたLIDを持つ電話番号JIDに一対一メッセージを送信する際のWhatsApp ERROR 463を修正するにはどうすればよいですか?

@s.whatsapp.net の PN JID に 1:1 メッセージを送信する前に、Baileys のローカル LID マッピングを通じて解決してください。signalRepository.lidMapping.getLIDForPN(pn) を呼び出します。LID が返された場合は、PN JID の代わりに <lid>@lid にメッセージを送信し、元の PN を remoteJidAlt メタデータとして保持してください。たとえば、そのマッピングが存在する場合、19178056839@s.whatsapp.net を 148373990592755@lid にルーティングします。これにより、messageStubParameters: ["463"] を伴う非同期の messages.update 拒否を回避でき、通常の SERVER_ACK/DELIVERY_ACK 応答が得られるはずです。ローカルの LID マッピングが存在しない場合は、暗黙的な USync を強制するのではなく、既存の PN 解決パスを維持してください。上流の修正では、この PN から LID への解決が send/relay パスに実装されています。

参照 Issue #2683