Skip to content

feat(engine): Baileys reply/forward/react/delete + persisted store (slice 2b)#308

Merged
rmyndharis merged 7 commits into
mainfrom
feat/baileys-store-ops
Jun 18, 2026
Merged

feat(engine): Baileys reply/forward/react/delete + persisted store (slice 2b)#308
rmyndharis merged 7 commits into
mainfrom
feat/baileys-store-ops

Conversation

@rmyndharis

Copy link
Copy Markdown
Owner

Summary

Slice 2b of the Baileys engine: un-gates reply / forward / react / delete, backed by a DB-persisted message store (Baileys 6.7.23 ships none) that survives restarts.

Stacked on #307 (base branch feat/baileys-media-sends, which is itself stacked on #299). This PR's diff is slice-2b only; once #307#299 merge, I'll retarget the base to main.

What's added

  • replyToMessagesock.sendMessage(chatId, { text }, { quoted }) · forwardMessage{ forward } · reactToMessage{ react: { text, key } } · deleteMessage (revoke for everyone) → { delete: key }. A store miss throws a clear Message <id> not found; delete-for-me (forEveryone=false) returns HTTP 501.
  • Persisted store baileys_stored_messages ('data' connection, CASCADE-deleted with its session): maps (sessionId, waMessageId) → the serialized WAMessage (via Baileys' own BufferJSON). Populated fire-and-forget on every inbound + outbound message; cleared on logout; bounded per-session by BAILEYS_MESSAGE_STORE_LIMIT (default 5000) via a (createdAt, id) cutoff range-delete.
  • getFeatures() now advertises message-replies, message-forwarding, message-reactions, message-deletion.

Architecture

  • The store service is injected into EngineFactory and threaded through the plugin constructor into the adapter config — the neutral per-call createEngine contract (feat(engine): opaque per-engine config (engine-agnostic EngineFactory) #296) is untouched, and the Baileys proto/key never leaks into the neutral pipeline (messages table, webhooks, dashboard). The adapter depends on a narrow BaileysMessageStore interface, not the Nest service.
  • No new dependency (uses BufferJSON/WAMessage from the installed lib + TypeORM).

⚠️ Operator note: new data-at-rest

This engine now persists recent message protos to the data DB (so reply/forward/react/delete survive restarts) — more data-at-rest than the whatsapp-web.js engine, which resolves only from a live in-memory window. It is bounded per-session by BAILEYS_MESSAGE_STORE_LIMIT, CASCADE-deleted with the session, and cleared on logout. Operators with retention/GDPR concerns can tune the cap.

Out of scope (still 501)

getMessageReactions (reading reactions — needs reaction-event aggregation), deleteMessage for-me, and everything store-backed-reads (contacts/groups/chats/history) → slice 3.

Testing

  • 596 unit + 6 e2e green; backend lint 0 / build clean; dashboard build clean / lint 0 errors.
  • New coverage: store service (BufferJSON round-trip, idempotent upsert, eviction prunes oldest + same-timestamp tiebreaker, session-scoped clear); adapter (each op → exact sendMessage shape, store-miss throw, delete-for-me 501, populate-on-upsert/send, clear-on-logout); migration up/down in-memory; the e2e boot gate (feature list synced).
  • Fixed a latent boot bug: the migration spec was matching the migrations/*{.ts,.js} glob (TypeORM loaded a test file as a migration, crashing e2e/dev boot) — moved to a __tests__/ subdir.

Base automatically changed from feat/baileys-media-sends to main June 18, 2026 08:36
@rmyndharis rmyndharis merged commit 829c050 into main Jun 18, 2026
@rmyndharis rmyndharis deleted the feat/baileys-store-ops branch June 18, 2026 08:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant