Skip to content

Add a vendor-official Chat SDK adapter for OpenWA #3389

Description

@smashah

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:

  • 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.

References:

Triage findings

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.
  • Parsing tests cover inbound/outbound identity, captions, quoted messages, mentions, timestamps, and lazy media.
  • disconnect() unregisters every listener and does not close a caller-owned OpenWA client.
  • Unsupported webhook, typing, interactivity, and incomplete-history behavior is documented and tested.
  • CI runs typecheck, tests, build, and package export checks.
  • OpenWA usage docs and the vendor-official Chat SDK catalog/docs PR are prepared before publication.

Non-goals

  • Replacing Chat SDK’s Meta WhatsApp Business Cloud adapter.
  • Owning OpenWA browser/session configuration inside the first adapter release.
  • Direct WAPI access from the adapter.
  • Complete WhatsApp history synchronization.
  • Cards, callback buttons, modals, slash commands, ephemeral messages, or native streaming in v1.

Suggested implementation order

  1. Define the narrow OpenWA client contract, thread codec, parser, and format converter.
  2. Implement lifecycle/event bridging and self-echo tracking.
  3. Add posting, media, mutations, reactions, and state-backed history behavior.
  4. Add conformance/unit tests and runnable embedded-client example.
  5. Publish under @open-wa, add primary docs, then submit the Chat SDK vendor-official catalog/docs PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions