mirror of
https://github.com/chatwoot/chatwoot.git
synced 2026-06-04 21:02:35 +08:00
When a WhatsApp contact starts a new conversation by sending multiple images at once (an album), each image arrives as a separate webhook. Because no conversation exists yet, the concurrent workers each pass the "does a conversation exist?" check and each create their own conversation — producing one conversation per image instead of one grouped conversation. This fix serializes webhook processing per `(inbox, contact)` using a Redis lock at the job level, so only one webhook at a time can create the initial conversation for a given contact. Concurrent workers retry with backoff and append to the same conversation once the lock is released. ## Closes - Closes #13261 ## How to test 1. On a WhatsApp inbox, ensure there is no active (open) conversation with a specific test contact — resolve or delete any existing one. 2. From a phone, select 6+ images in the WhatsApp gallery and send them as a single album to the Chatwoot-connected number. 3. Open the Chatwoot dashboard and confirm exactly **one** new conversation is created, with all images grouped under it. 4. Repeat the test with a mix of attachment types (XMLs, PDFs, images) sent in rapid succession — still one conversation. ## What changed - New Redis key `WHATSAPP_MESSAGE_CREATE_LOCK::<inbox_id>::<sender_id>` in `lib/redis/redis_keys.rb`. - `Webhooks::WhatsappEventsJob` now inherits from `MutexApplicationJob` and wraps event processing in `with_lock(key)`, matching the pattern already used by `FacebookEventsJob`, `InstagramEventsJob`, and `TiktokEventsJob`. - Uses `retry_on LockAcquisitionError, wait: 1.second, attempts: 8` so concurrent webhooks retry until the lock is free instead of poll-waiting inside the service. - Sender ID is derived from the webhook payload (contact's `from`, or `to` for SMB echo events); status-only webhooks bypass the lock. - Issue 1 from the report (same `source_id` redelivery) was already handled previously by `Whatsapp::MessageDedupLock` (atomic `SET NX EX`); no changes needed there. --------- Co-authored-by: Muhsin <12408980+muhsin-k@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| alfred.rb | ||
| config.rb | ||
| lock_manager.rb | ||
| redis_keys.rb | ||