#20003: feat(whatsapp): follow-up window for group conversations with requireMention
channel: whatsapp-web
size: S
Cluster:
WhatsApp and Google Chat Fixes
## 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
#4402: fix: store group messages from non-allowlisted senders as pending c...
by adam91holt · 2026-01-30
80.5%
#8224: feat(whatsapp): extract @mentions into dedicated module
by zurizuriaria · 2026-02-03
79.7%
#12069: fix(whatsapp): handle native group @mentions with requireMention
by abhishek0450 · 2026-02-08
79.5%
#11166: fix(whatsapp): detect LID @mentions in self-chat mode
by mcaxtr · 2026-02-07
79.0%
#11611: feat: separate group-level allowlist from sender-level command auth...
by thisnick · 2026-02-08
78.8%
#22106: fix(whatsapp): honor selfChatMode override for group mentions
by sportclaw · 2026-02-20
78.8%
#6567: fix: include paired users in WhatsApp group sender allowlist
by giannisanni · 2026-02-01
78.6%
#23288: feat(whatsapp): group command gating via commands.allowFrom + sende...
by rodrigoscoelho · 2026-02-22
77.3%
#5201: Signal: add group mention gating with requireMention config
by csalvato · 2026-01-31
76.6%
#23046: fix(whatsapp): detect LID JID in implicit reply-to-bot mention check
by hydro13 · 2026-02-21
76.1%