fix(whatsapp): reopen conversation across a contact's coexistence identities - #15098
Conversation
|
SummaryCoverage spans normal and edge-case message handling across phone and alternate WhatsApp identities, including conversation reuse, inbox and contact isolation, duplicate delivery protection, resolved-thread behavior, rollback safety, and signed inbound message processing. The application behavior is healthy across sequential, identity-variant, status, and failure-recovery paths, with one concurrency-specific fragmentation issue identified. Safe to merge — the sole failure is a medium-severity concurrency bug explicitly determined to be pre-existing and not attributable to this PR, while the PR’s targeted sequential identity-reuse behavior and related safeguards passed. The concurrency issue is a flag for later rather than a merge blocker, with no PR regressions or newly introduced failures identified. Tests run by ItoAdditional Findings DetailsThese findings are unrelated to the current changes but were observed during testing. 🟡 Concurrent phone and BSUID deliveries create one conversation
Evidence PackageTip Reply with @itoqa to send us feedback on this test run. |
Reworked to the direction agreed in chatwoot#14931: the business scoped user id is the active identity whenever one is present, a message resolves to that exact contact inbox, and the conversation opened under a previous identity is left where it is. Three changes carry it. Resolution now lists the identifier before the phone number, so the phone is the fallback for a payload that carries none. Reuse is scoped to the contact inbox that resolved the message rather than to the contact, which is what removes the contact wide lookup: a contact can hold unrelated identities in one inbox, from coexistence or from a dashboard merge, and that lookup cannot tell them apart. The repoint this PR carried before is gone, since the phone conversation is meant to stay reachable under previous conversations. Worth stating plainly: this changes behaviour released in chatwoot#15098. A contact that already holds a phone conversation gets a second one on the identifier inbox instead of continuing the first. That is the agreed trade, and it is what makes a reply always address the identity that sent the message.

WhatsApp contacts using coexistence are identified by more than one source ID (a phone
wa_idand aBR./BSUID identity), so a single contact ends up owning multiplecontact_inboxrecords. The "reopen the same conversation" feature scoped conversation reuse to a singlecontact_inbox, so messages arriving under a different identity of the same contact started a brand-new conversation — even with reopen enabled — producing duplicate conversations.This scopes reuse to the contact across all of its
contact_inboxrecords in the inbox instead of a singlecontact_inbox.Closes
How to reproduce
wa_idand only the BSUID identity.What changed
Whatsapp::IncomingMessageBaseService#set_conversationnow looks up reusable conversations via@contact.conversations.where(inbox_id: @inbox.id)instead of@contact_inbox.conversations.contactto the contact_inbox's contact, mirroring production data.