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
The chatwoot-adapter only relays live inbound WhatsApp messages (message:received, fromMe === false). This causes two major sync gaps in real deployments:
First-time setup: Existing WhatsApp conversations do not appear in Chatwoot when the adapter is enabled — only messages that arrive after enable are relayed.
Linked phone / Apple device: Messages the operator sends from their physical phone (or other linked WhatsApp clients) are never relayed to Chatwoot, even when the customer replies and a live conversation is ongoing.
Operators expect a helpdesk bridge to show the full conversation thread, not just post-enable inbound traffic from contacts.
Problem 1 — No initial / historical sync on first connect
Expected
When enabling chatwoot-adapter (or connecting a WhatsApp session for the first time), existing chats and recent message history should be imported into the mapped Chatwoot API inbox — similar to connecting any helpdesk channel.
Actual
Chatwoot stays empty (or missing most contacts) until new inbound messages arrive after enable.
Root cause
The adapter registers only the message:received hook:
OpenWA itself documents that history bulk is persist-only, no dispatch:
onHistoryMessages: (messages): void=>{// Persist for the chat view only; no dispatch (these predate the live session).voidthis.persistHistoryMessages(id,messages)...},
So history exists in OpenWA's DB/dashboard but never reaches the Chatwoot adapter.
Real-world workaround
Deployments must run a separate custom script (e.g. sync-inbound.sh) that:
Calls OpenWA chats + history APIs manually
Creates Chatwoot contacts/conversations
Posts text-only messages (no media, no source_id, no reply threading)
Seeds plugin mapping files by hand
This should be a built-in adapter feature (configurable: syncOnEnable, historyLimit, unread-only vs full).
Problem 2 — Phone / linked-device messages not synced to Chatwoot
Expected
If an agent chats with a customer on their iPhone / WhatsApp mobile app (linked device), those messages should appear in the Chatwoot conversation thread — both the operator's outgoing texts and the customer's replies.
Actual
Customer replies from phone may appear (if they arrive as live message:received)
Operator messages composed on the phone never appear in Chatwoot
The Chatwoot thread looks one-sided / broken
Root cause (adapter)
Inbound filter explicitly drops all fromMe messages:
OpenWA correctly routes phone-composed sends through a different event path than live inbound:
// whatsapp-web-js adapterthis.client.on('message_create',msg=>{// message_create fires for messages composed on a linked phoneif(!msg.fromMe)return;this.callbacks.onMessageCreate?.(...);});// session.service.ts
onMessageCreate: (message)=>{if(!message.fromMe)return;voidthis.hookManager.execute('message:sent',messageData,{sessionId: id,source: 'Engine'});// NOTE: intentionally does NOT persist phone-composed sends to messages table (yet)voidthis.webhookService.dispatch(id,'message.sent',finalMessage);}
So phone sends emit message:sent, but chatwoot-adapter ignores that hook entirely.
Additionally, OpenWA does not persist phone-composed outgoing messages to its own messages table (only webhooks/WS) — so even the OpenWA dashboard chat view can be incomplete for phone sends. Chatwoot sync is impossible without handling message:sent.
Reproduction
Enable chatwoot-adapter, map a WhatsApp session to a Chatwoot inbox.
On your linked iPhone, open a 1:1 chat and send messages to a contact (do not use Chatwoot or OpenWA API).
Have the contact reply.
Open the conversation in Chatwoot.
Result: Contact replies may show; your phone-sent messages do not.
Proposed fix
A. Initial sync (on enable / session ready)
On session:ready (or first message:received per chat), optionally:
Fetch recent chats from OpenWA (/chats or engine store)
For each chat (respect relayGroups), pull last N messages from history API
Relay fromMe messages to Chatwoot as outgoing (or incoming from contact perspective — pick one convention and document it; recommend outgoing since it's the account owner's message)
Coordinate with OpenWA core to persist phone-composed sends to messages table (session.service onMessageCreate path) so history backfill and dashboard stay consistent
C. Observability
Log skipped vs relayed counts on enable/sync
Surface sync errors in plugin status (not only inbound relay failed in logs)
Impact
Without these fixes, Chatwoot is not a faithful inbox mirror of WhatsApp:
Agents onboarding see an empty helpdesk
Agents using their phone alongside Chatwoot see broken threads
Custom sync scripts become mandatory (fragile, text-only, no media)
Summary
The
chatwoot-adapteronly relays live inbound WhatsApp messages (message:received,fromMe === false). This causes two major sync gaps in real deployments:Operators expect a helpdesk bridge to show the full conversation thread, not just post-enable inbound traffic from contacts.
Related: #609 (parity meta), #606 (reply context), #607 (voice), #608 (media).
Problem 1 — No initial / historical sync on first connect
Expected
When enabling
chatwoot-adapter(or connecting a WhatsApp session for the first time), existing chats and recent message history should be imported into the mapped Chatwoot API inbox — similar to connecting any helpdesk channel.Actual
Chatwoot stays empty (or missing most contacts) until new inbound messages arrive after enable.
Root cause
The adapter registers only the
message:receivedhook:There is no handler for:
session:ready(backfill on connect)onHistoryMessages/ history sync bulk events/messages/.../historyAPIOpenWA itself documents that history bulk is persist-only, no dispatch:
So history exists in OpenWA's DB/dashboard but never reaches the Chatwoot adapter.
Real-world workaround
Deployments must run a separate custom script (e.g.
sync-inbound.sh) that:source_id, no reply threading)This should be a built-in adapter feature (configurable:
syncOnEnable,historyLimit, unread-only vs full).Problem 2 — Phone / linked-device messages not synced to Chatwoot
Expected
If an agent chats with a customer on their iPhone / WhatsApp mobile app (linked device), those messages should appear in the Chatwoot conversation thread — both the operator's outgoing texts and the customer's replies.
Actual
message:received)Root cause (adapter)
Inbound filter explicitly drops all
fromMemessages:The adapter does not subscribe to
message:sent.Root cause (OpenWA engine — important context)
OpenWA correctly routes phone-composed sends through a different event path than live inbound:
So phone sends emit
message:sent, butchatwoot-adapterignores that hook entirely.Additionally, OpenWA does not persist phone-composed outgoing messages to its own
messagestable (only webhooks/WS) — so even the OpenWA dashboard chat view can be incomplete for phone sends. Chatwoot sync is impossible without handlingmessage:sent.Reproduction
chatwoot-adapter, map a WhatsApp session to a Chatwoot inbox.Result: Contact replies may show; your phone-sent messages do not.
Proposed fix
A. Initial sync (on enable / session ready)
On
session:ready(or firstmessage:receivedper chat), optionally:/chatsor engine store)relayGroups), pull last N messages from history APIresolveConversationlogic)source_idand dedup markerssyncOnEnable(defaulttrue),syncHistoryLimit(default50),syncUnreadOnly(defaultfalse)B. Phone / linked-device outgoing sync
message:senthook inchatwoot-adapterfromMemessages to Chatwoot asoutgoing(orincomingfrom contact perspective — pick one convention and document it; recommendoutgoingsince it's the account owner's message)source_id: msg.idfor threading (chatwoot-adapter: WhatsApp reply/quote context not forwarded to Chatwoot (shows only reply text) #606)messagestable (session.serviceonMessageCreatepath) so history backfill and dashboard stay consistentC. Observability
inbound relay failedin logs)Impact
Without these fixes, Chatwoot is not a faithful inbox mirror of WhatsApp:
This is a blocker for production helpdesk use.