Repository navigation
fix(whatsapp): messages stuck at Sending - add ACK timeout and retry #1344
Copy link
Copy link
Open
Labels
area:backendBackend (Express/SQLite)Backend (Express/SQLite)area:frontendFrontend (React/Next.js)Frontend (React/Next.js)state:readyScoped and ready for implementationScoped and ready for implementationtype:bugA confirmed defect in existing behaviorA confirmed defect in existing behavior
Description
Parent: #830 (chat leftovers). Verified against main @ 8e39053.
Bug
WhatsApp messages can stay at "Sending" forever (user report, 14 Sep).
Root cause (verified in code)
main/services/whatsapp.ts~L1672 sets the row totypingbefore sending. Aftersocket.sendMessage(~L1689-1694) it only storesexternal_message_id: "Do not mark 'sent' immediately; wait for server ACK (status=2) in messages.update" (messages.updatehandler ~L994).- Nothing times out a missing ACK: no stale-status sweep, and no
queued/typingcleanup on startup or reconnect. If the ACK never arrives (socket drop, app restart, phone offline), the row staystyping, which the UI shows as sending (frontend/src/app/(dashboard)/whatsapp/page.tsx,STATUS_STEPS~L197). - feat: add WhatsApp message templates, automated rules, and safety controls #1315 and fix(main): harden WhatsApp offline abort, split-bill deduplication, loyalty rounding, and auto-settlement automation #1323 (main, unreleased) do not cover this.
Fix (decided)
- Add an ACK timeout. If a message is still
queuedortypingN minutes after its last transition (a named constant, for example 5 minutes), mark itfailedwith reasonack_timeout. - Run the sweep on a timer while connected, and once on startup for rows left over from a previous run.
- A late ACK for a message already marked
failedshould still promote it tosent/delivered(messages.updatekeys byexternal_message_id). - UI: failed rows already render. Add a "Retry" action that re-queues through the same send path, honouring the feat: add WhatsApp message templates, automated rules, and safety controls #1315 safety controls and Offline mode (feat(settings): owner-only Offline mode that closes every optional outbound connection #1306).
Acceptance criteria
- A message without an ACK becomes
failed(ack_timeout) after the timeout. - A late ACK still upgrades it to
sent/delivered. - Rows stuck from before a restart are swept on startup.
- Retry sends once (no duplicates) and is blocked in Offline mode.
Verification
- Extend
tests/whatsapp-service.test.tswith fake timers covering the timeout, a late ACK, the startup sweep and retry idempotency. npm run lint && npm test
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area:backendBackend (Express/SQLite)Backend (Express/SQLite)area:frontendFrontend (React/Next.js)Frontend (React/Next.js)state:readyScoped and ready for implementationScoped and ready for implementationtype:bugA confirmed defect in existing behaviorA confirmed defect in existing behavior
Activity