This change https://github.com/chatwoot/chatwoot/pull/13371 broke the
functionality. When a user replies to a WhatsApp message, the reply
context wasn't being properly stored in Chatwoot due to #13371
WhatsApp sends reply messages with a `context` field containing the
original message ID:
```json
{
"messages": [{
"context": {
"from": "phone_number",
"id": "wamid.ORIGINAL_MESSAGE_ID"
},
"from": "phone_number",
"id": "wamid.REPLY_MESSAGE_ID",
"text": { "body": "This is a reply" }
}]
}
```
However, the in_reply_to_external_id was being overridden when building
the message because content_attributes was explicitly set to either {
external_echo: true } or {}, which discarded the reply-to information.
When businesses use WhatsApp Business App (co-existence mode) or
Instagram App or TikTok alongside Chatwoot, messages sent from the
native apps were not synced properly back to Chatwoot. This left agents
with an incomplete conversation history and no visibility into responses
sent outside the dashboard. Additionally, if these echo messages did
arrive, they appeared as "Sent by: Bot" in the UI since they had no
sender, making it confusing for agents.
This PR subscribes to WhatsApp `smb_message_echoes` webhook events and
routes them through the existing service with an `outgoing_echo` flag,
mirroring how Instagram already handles echoes. On the Instagram side,
echo messages now also carry the `external_echo` content attribute and
`delivered` status.
On the frontend, messages with `externalEcho` are distinguished from bot
messages showing a "Native app" avatar and an advisory note encouraging
agents to reply from Chatwoot to maintain the service window.
<img width="1518" height="524" alt="CleanShot 2026-01-29 at 13 37 57@2x"
src="https://github.com/user-attachments/assets/5aa0b552-6382-441f-96aa-9a62ca716e4a"
/>
Fixes
https://linear.app/chatwoot/issue/CW-4204/display-messages-not-sent-from-chatwoot-in-case-of-outgoing-echo
Fixes
https://linear.app/chatwoot/issue/PLA-33/incoming-from-me-messages-from-whatsapp-business-app-are-not-falling
Fixes https://github.com/chatwoot/chatwoot/issues/11753 and
https://github.com/chatwoot/chatwoot/issues/12442
**Problem**
When a WhatsApp conversation started with a media message, the
conversation created webhook would sometimes fire before the message and
its relationships were fully committed to the database. This resulted in
the message being missing
from the webhook payload, breaking external automations that rely on
this field.
**Solution**
Added `ActiveRecord::Base.transaction` wrapper around the core message
processing operations in `Whatsapp::IncomingMessageBaseService` to
ensure atomic execution:
- `set_conversation` (creates conversation)
- `create_messages` (creates message with account_id)
- `clear_message_source_id_from_redis` (cleanup)
Now the webhook only triggers after all related data is fully persisted,
guaranteeing message availability.
Currently, we do not support reactions, ephemeral messages, or the request_welcome event for the WhatsApp channel. However, if this is the first event we receive in Chatwoot (i.e., there is no previous conversation or contact in Chatwoot), it will create a contact and a conversation without any messages. This confuses our customer, as it may appear that Chatwoot has missed some messages. There are multiple cases where this might be the first event we receive in Chatwoot. One quick example is when the user has sent an outbound campaign from another tool and their customers reacted to the message.
Another event like this is request_welcome event. WhatsApp has a concept for welcome messages. You can send an outbound message even though the user has not send a message. You can receive notifications through a webhook whenever a WhatsApp user initiates a chat with you for the first time. (Read the Welcome message section: https://developers.facebook.com/docs/whatsapp/cloud-api/phone-numbers/conversational-components/ ). Although this can help the business send a pro-active message to the user, we don't have it scoped in our feature set. For now, I'm ignoring this event.
Fixes https://linear.app/chatwoot/issue/CW-3018/whatsapp-handle-request-welcome-case-properly
Fixes https://linear.app/chatwoot/issue/CW-3017/whatsapp-handle-reactions-properly
Process field statuses received in webhook WhatsApp cloud API
ref: #1021
Co-authored-by: Sojan <sojan@pepalo.com>
Co-authored-by: Nithin David <1277421+nithindavid@users.noreply.github.com>