You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Build and publish a Chat SDK adapter for OpenWA so a Chat SDK bot can use a linked WhatsApp account through OpenWA’s browser-backed runtime.
Proposed package:
workspace: integrations/chat-sdk
npm: @open-wa/chat-adapter
Chat SDK adapter name: openwa
This should be presented as a vendor-official Chat SDK adapter maintained by OpenWA, not as another official Meta/WhatsApp Cloud API adapter. Chat SDK already ships @chat-adapter/whatsapp for WhatsApp Business Cloud and lists community adapters for Baileys/Zaileys; this adapter’s value is OpenWA’s browser-backed session lifecycle, multi-driver runtime, Easy API/remote-client path, plugin ecosystem, and OpenWA-specific escape hatches.
OpenWA v5 already exposes most of the primitives needed for an adapter:
lifecycle and events through Client, onMessage, onAnyMessage, and listener handles with off()
text/media sends through sendText, sendImage, sendFile, and media decryption
mutation methods through editMessage, deleteMessage, and react
chat/message lookup through getChatById, getAllMessages, loadEarlierMessages, and getMessageById
graceful teardown through the existing OpenWA client/resource-scope lifecycle
The remaining gaps should be explicit:
simulateTyping exists in WAPI, but it is not currently exposed as a supported v5 schema/client method.
A reaction event exists in schema/core, but the v5 Client does not currently expose a supported onReaction listener.
onMessageDeleted is declared but intentionally unsupported by the shipped browser runtime.
WhatsApp history is only what the linked client has loaded; it is not a durable server-side history API.
Proposed design
Lifecycle and client ownership
createOpenWAAdapter should accept a small structural OpenWA client interface so embedded Client and the remote Easy API client can be supported without coupling the adapter to a browser driver.
The host application should own the OpenWA client by default. Chat SDK’s initialize() stores the ChatInstance and subscribes to OpenWA events; disconnect() removes adapter listeners but must not stop a caller-owned OpenWA session. If an owned-client mode is added later, make ownership explicit in config.
This is a long-running Node adapter, not a webhook/serverless adapter. handleWebhook() should return 501 Not Implemented, matching the lifecycle model used by connection-based Chat SDK adapters.
Thread identity
Use a collision-safe ID containing both the OpenWA session and WhatsApp chat:
openwa:<base64url(sessionId)>:<base64url(chatId)>
WhatsApp chats are threadless from Chat SDK’s perspective, so:
channelIdFromThreadId(threadId) returns the same conversation identifier.
lockScope is "channel".
isDM() treats group JIDs separately from direct/LID JIDs.
persistThreadHistory is enabled because complete history is not available from a remote WhatsApp API.
Incoming messages
Normalize OpenWA messages into Chat SDK Message objects, including text/caption, author, timestamps, group sender identity, mentions, quoted-message metadata where useful, and lazy attachment data through OpenWA media decryption.
Do not map OpenWA’s fromMe flag directly to Chat SDK author.isMe. A linked WhatsApp account is user-owned, so manually authored messages should remain user messages. Track message IDs returned by this adapter; only echoed messages with a tracked ID should be marked isMe: true and isBot: true to prevent handler feedback loops.
Use onAnyMessage only if the implementation needs outbound echo tracking; otherwise process inbound traffic through onMessage. Group mentions should set message.isMention when mentionedJidList contains the host account.
Outgoing messages and formatting
Render Chat SDK text/markdown through an OpenWA format converter for WhatsApp formatting.
Use extractCard, extractFiles, and toBuffer from @chat-adapter/shared.
Send cards as documented text fallback in v1; interactive buttons, callback tokens, and modals are out of scope until the relevant OpenWA APIs are stable.
Route attachments by MIME type to sendImage, sendFile, and the appropriate audio/video methods, preserving captions and filenames.
Implement edit, delete, add reaction, and remove reaction where the OpenWA runtime supports them; removing a reaction should use the platform’s empty-reaction behavior and be covered by a runtime-facing test.
Buffer Chat SDK streams through normal post/edit fallback rather than claiming native streaming.
History and optional capabilities
fetchMessages() may return the currently loaded OpenWA messages in chronological order, but it must document that this is not complete durable history. Prefer Chat SDK’s state-backed persisted thread history for reliable bot context.
Typing and incoming reaction dispatch should be added only after the corresponding supported v5 client surfaces exist. Do not reach directly into WAPI from the adapter.
Package and docs
ESM-only build using this monorepo’s current tsdown conventions.
Peer dependency on chat (current npm release is 4.34.0) and dependency on matching @chat-adapter/shared.
Export OpenWAAdapter, createOpenWAAdapter, the format converter, config/thread types, and a narrow OpenWA client interface.
Add OpenWA docs with an embedded-client example, an Easy API/remote-client example if supported, multi-session thread-ID behavior, QR/session setup, limitations, and the unofficial WhatsApp Web automation risk.
Add a Chat SDK docs PR for the vendor-official listing and chat/adapters catalog, including the package name, peer dependencies, constructor-only config, and environment variables.
Announce the adapter in the OpenWA changelog/release notes once published.
MVP feature matrix
Capability
MVP
Notes
Receive DMs and group messages
Yes
Normalize text, captions, authors, mentions, and attachments
Post text/markdown
Yes
WhatsApp format converter
File uploads
Yes
Images, video/audio, and documents where OpenWA supports them
Edit/delete messages
Yes
Runtime-supported operations only
Add/remove reactions
Yes
Send side; receive side follows the client-surface gap
Typing indicator
No
Add after simulateTyping is a supported v5 client method
Fetch history
Partial
Loaded messages plus Chat SDK state persistence
Cards/buttons/modals
No
Text fallback in v1
Streaming
Buffered
Chat SDK post/edit fallback
Webhooks/serverless
No
Long-running OpenWA session
Acceptance criteria
@open-wa/chat-adapter implements the current Chat SDK Adapter interface and builds as ESM with declarations.
A minimal Chat SDK bot can receive an OpenWA DM, subscribe to the conversation, reply, and avoid replying to its own adapter-generated echo.
Group messages and host-account mentions map to stable session-scoped thread IDs.
Text, media, edit, delete, add-reaction, and remove-reaction paths have unit tests with a fake OpenWA client.
Thread ID encode/decode round-trips direct, group, LID, and multi-session identifiers.
Summary
Build and publish a Chat SDK adapter for OpenWA so a Chat SDK bot can use a linked WhatsApp account through OpenWA’s browser-backed runtime.
Proposed package:
integrations/chat-sdk@open-wa/chat-adapteropenwaThis should be presented as a vendor-official Chat SDK adapter maintained by OpenWA, not as another official Meta/WhatsApp Cloud API adapter. Chat SDK already ships
@chat-adapter/whatsappfor WhatsApp Business Cloud and lists community adapters for Baileys/Zaileys; this adapter’s value is OpenWA’s browser-backed session lifecycle, multi-driver runtime, Easy API/remote-client path, plugin ecosystem, and OpenWA-specific escape hatches.References:
Triage findings
OpenWA v5 already exposes most of the primitives needed for an adapter:
Client,onMessage,onAnyMessage, and listener handles withoff()sendText,sendImage,sendFile, and media decryptioneditMessage,deleteMessage, andreactgetChatById,getAllMessages,loadEarlierMessages, andgetMessageByIdThe remaining gaps should be explicit:
simulateTypingexists in WAPI, but it is not currently exposed as a supported v5 schema/client method.Clientdoes not currently expose a supportedonReactionlistener.onMessageDeletedis declared but intentionally unsupported by the shipped browser runtime.Proposed design
Lifecycle and client ownership
createOpenWAAdaptershould accept a small structural OpenWA client interface so embeddedClientand the remote Easy API client can be supported without coupling the adapter to a browser driver.The host application should own the OpenWA client by default. Chat SDK’s
initialize()stores theChatInstanceand subscribes to OpenWA events;disconnect()removes adapter listeners but must not stop a caller-owned OpenWA session. If an owned-client mode is added later, make ownership explicit in config.This is a long-running Node adapter, not a webhook/serverless adapter.
handleWebhook()should return501 Not Implemented, matching the lifecycle model used by connection-based Chat SDK adapters.Thread identity
Use a collision-safe ID containing both the OpenWA session and WhatsApp chat:
WhatsApp chats are threadless from Chat SDK’s perspective, so:
channelIdFromThreadId(threadId)returns the same conversation identifier.lockScopeis"channel".isDM()treats group JIDs separately from direct/LID JIDs.persistThreadHistoryis enabled because complete history is not available from a remote WhatsApp API.Incoming messages
Normalize OpenWA messages into Chat SDK
Messageobjects, including text/caption, author, timestamps, group sender identity, mentions, quoted-message metadata where useful, and lazy attachment data through OpenWA media decryption.Do not map OpenWA’s
fromMeflag directly to Chat SDKauthor.isMe. A linked WhatsApp account is user-owned, so manually authored messages should remain user messages. Track message IDs returned by this adapter; only echoed messages with a tracked ID should be markedisMe: trueandisBot: trueto prevent handler feedback loops.Use
onAnyMessageonly if the implementation needs outbound echo tracking; otherwise process inbound traffic throughonMessage. Group mentions should setmessage.isMentionwhenmentionedJidListcontains the host account.Outgoing messages and formatting
extractCard,extractFiles, andtoBufferfrom@chat-adapter/shared.sendImage,sendFile, and the appropriate audio/video methods, preserving captions and filenames.History and optional capabilities
fetchMessages()may return the currently loaded OpenWA messages in chronological order, but it must document that this is not complete durable history. Prefer Chat SDK’s state-backed persisted thread history for reliable bot context.Typing and incoming reaction dispatch should be added only after the corresponding supported v5 client surfaces exist. Do not reach directly into WAPI from the adapter.
Package and docs
tsdownconventions.chat(current npm release is4.34.0) and dependency on matching@chat-adapter/shared.OpenWAAdapter,createOpenWAAdapter, the format converter, config/thread types, and a narrow OpenWA client interface.chat/adapterscatalog, including the package name, peer dependencies, constructor-only config, and environment variables.MVP feature matrix
simulateTypingis a supported v5 client methodAcceptance criteria
@open-wa/chat-adapterimplements the current Chat SDKAdapterinterface and builds as ESM with declarations.disconnect()unregisters every listener and does not close a caller-owned OpenWA client.Non-goals
Suggested implementation order
@open-wa, add primary docs, then submit the Chat SDK vendor-official catalog/docs PR.