feat(chatwoot-adapter): history backfill (lazy + opt-in bulk) (#609)#27
Merged
Conversation
Agents now see prior WhatsApp context in Chatwoot instead of a conversation that starts mid-thread. Two composable modes, both off by default: - Lazy (backfillLimit): when a chat first opens as a Chatwoot conversation, its recent messages (both directions, with media) are replayed oldest->newest before the triggering message, deduped against the live path so nothing double-posts. - Bulk (backfillAllOnce): a one-time sweep imports every existing chat's history on setup, sequential and best-effort, run once per session behind a durable marker + an in-flight guard. Business-side (fromMe) messages post as Chatwoot outgoing, contact messages as incoming (postText/postMedia gain a message_type). The per-message render and conversation resolve are extracted into a shared relay.ts (leaf module) so live inbound and backfill render identically without an import cycle. Bumps minOpenWAVersion to 0.8.5 (engine.getChatHistory) and the plugin to 0.3.0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the "initial history sync" P1 of rmyndharis/OpenWA#609. Pairs with OpenWA 0.8.5 (
engine.getChatHistory).Why
An opened Chatwoot conversation started mid-thread — agents lost the prior WhatsApp context. This backfills it, replacing the external
sync-inbound.shworkaround.Two modes (both off by default, composable)
backfillLimit(messages per chat): when a chat first opens as a Chatwoot conversation, its recent history is replayed oldest→newest before the triggering message, so the thread reads chronologically and the live message's quote resolves against a just-postedsource_id. Reactive context, exactly when an agent needs it.backfillAllOnce: a one-time sweep that imports every existing chat's history on setup (for mirroring a whole inbox). Sequential, best-effort, and run once per session behind a durable marker plus an in-memory in-flight guard.Both reconstruct both directions: business/
fromMemessages post as Chatwootoutgoing, contact messages asincoming. Historical media is uploaded fully (like live). Everything is deduped against the samemarkSeenstore the live path uses, so the two modes compose and nothing double-posts.Shape
engine.getChatHistory(gated byengine:read+ active session, limit clamped host-side). This plugin pinsminOpenWAVersion 0.8.5.relay.ts(relayMessage,ensureConversation), so live inbound (inbound.ts) and backfill (backfill.ts) render identically with no import cycle.postText/postMediagain an optionalmessage_type.Not included (still #609 roadmap)
Retry/dead-letter, read receipts, and pinned-message banner — each needs a further host capability.
Tests
New
backfill.test.ts:backfillHistoryposts oldest→newest withfromMe→outgoing, dedups, and swallows a fetch failure;backfillAllChatssweeps each chat once, skips groups whenrelayGroupsis off, survives a per-chat failure, and is a no-op after the run-once marker is set. Plus a clientmessage_type: outgoingtest. Full suite green (231 tests across all plugins),tsc --noEmitclean, plugin packages, catalog up to date.