← Back to PRs

#20003: feat(whatsapp): follow-up window for group conversations with requireMention

by alexmelges open 2026-02-18 11:43 View on GitHub →
channel: whatsapp-web size: S
## Problem When `requireMention: true` is configured for a WhatsApp group, the bot only responds to @mentions or swipe-replies. This prevents noise but creates friction for ongoing conversations: after @mentioning the bot and getting a reply, the user must @mention again on every follow-up turn — even though the conversation is clearly still directed at the bot. ## Solution Add a **follow-up window**: after the bot sends an auto-reply in a group, messages from the same sender within a configurable window are treated as implicit mentions (conversation continuations). No @mention is required until the window expires or the conversation goes quiet. ### Behavior - Window starts when the bot sends its final reply to a sender. - Any subsequent message from that sender within the window is processed without requiring a new @mention. - Each (group, sender) pair is tracked independently — Alice having an active window does not open the window for Bob. - Expired entries are cleaned up lazily on the next check. - Swipe-replies continue to work as before (they are not affected). ## Config The window duration is configurable at three levels (highest priority first): ```yaml channels: whatsapp: groups: "120363xxxxxxxxxxxxxxx@g.us": followUpWindowMs: 120000 # 2 min for this specific group "*": followUpWindowMs: 600000 # 10 min default for all groups messages: groupChat: followUpWindowMs: 0 # disable globally (per-group still wins) ``` | Config path | Scope | |---|---| | `channels.whatsapp.groups.<id>.followUpWindowMs` | Per-group override | | `channels.whatsapp.groups."*".followUpWindowMs` | Wildcard default for all groups | | `messages.groupChat.followUpWindowMs` | Global cross-channel default | | *(built-in)* | 300 000 ms (5 min) | Set `followUpWindowMs: 0` at any level to disable the feature for that scope. ## Changes | File | Change | |---|---| | `src/config/group-policy.ts` | Add `followUpWindowMs` to `ChannelGroupConfig` | | `src/config/types.whatsapp.ts` | Add `followUpWindowMs` to `WhatsAppGroupConfig` | | `src/config/types.messages.ts` | Add `followUpWindowMs` to `GroupChatConfig` | | `src/config/zod-schema.core.ts` | Add field to `GroupChatSchema` | | `src/config/zod-schema.providers-whatsapp.ts` | Add field to `WhatsAppGroupEntrySchema` | | `src/web/auto-reply/monitor/group-gating.ts` | Follow-up tracker + `recordGroupReply` + `isFollowUp` | | `src/web/auto-reply/monitor/process-message.ts` | Static import + call `recordGroupReply` after final reply | | `src/web/auto-reply/monitor/group-gating.follow-up.test.ts` | 8 unit tests | ## Tests 8 new unit tests cover: - Same sender within window → follow-up detected ✓ - Same sender after window expires → not detected ✓ - Different sender within window → not detected ✓ - Multiple senders tracked independently per group ✓ - Each sender's expiry is independent ✓ - `followUpWindowMs: 0` disables the feature ✓ - Undefined sender handled gracefully ✓ - Different groups are isolated ✓ `pnpm build` and `pnpm test` pass (389 config tests + 8 new follow-up tests). <!-- greptile_comment --> <h3>Greptile Summary</h3> Adds a configurable follow-up window for WhatsApp group conversations with `requireMention` enabled. After the bot auto-replies to a sender, subsequent messages from that same sender within the window are treated as implicit mentions, removing the friction of re-mentioning on every turn. - Introduces `followUpWindowMs` config at three levels: per-group, wildcard default, and global `messages.groupChat` — with a built-in 5-minute default. - Adds an in-memory `groupFollowUpTracker` in `group-gating.ts` that records bot reply timestamps per (group, sender) pair, with lazy expiry on next lookup. - Integrates the follow-up check into the existing `applyGroupGating` flow alongside swipe-reply detection. - Records follow-up timestamps in `process-message.ts` after the final reply delivery. - Includes 8 focused unit tests covering core scenarios (same/different sender, expiry, independent tracking, disabled feature, undefined sender, group isolation). <h3>Confidence Score: 4/5</h3> - This PR is safe to merge with minimal risk; the feature is well-scoped and additive. - The changes are well-structured, narrowly scoped, and follow existing codebase patterns. Type additions, schema updates, and config resolution all align with established conventions. The only concern is the unbounded in-memory tracker, which is a style/operational issue rather than a correctness bug. Tests cover all key scenarios. - `src/web/auto-reply/monitor/group-gating.ts` — the `groupFollowUpTracker` Map has no periodic cleanup, which could cause slow memory growth in long-running gateway processes. <sub>Last reviewed commit: 46bea8a</sub> <!-- greptile_other_comments_section --> <sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs