← Back to PRs

#4402: fix: store group messages from non-allowlisted senders as pending context

by adam91holt open 2026-01-30 05:41 View on GitHub →
channel: whatsapp-web size: S trusted-contributor
## Problem When `groupPolicy: "allowlist"` and a group message arrives from a sender **not** in `groupAllowFrom`, the message is completely dropped at the access-control layer (`allowed: false` → `continue`). This means the agent cannot see messages from non-allowlisted group members in its `[Chat messages since your last reply - for context]` block. The [groups docs](https://docs.openclaw.ai/concepts/groups) describe the flow as: ``` requireMention? yes → mentioned? no → store for context only ``` But this context-storage path only runs **after** access control passes. Messages blocked by `groupAllowFrom` never reach the mention-gating/context-storage logic — they are silently discarded. ## Use Case You have a WhatsApp group with multiple participants (humans and bots). You only want certain numbers to **trigger** your agent (`groupAllowFrom`), but you want the agent to **see** all messages as context so it has full conversational awareness when it does respond. ## Fix Adds a new opt-in config flag `groupContextFromAll` (default: `false`) that preserves backward compatibility while allowing non-allowlisted group members' messages to be stored as pending context. ### Config Available at both the top-level WhatsApp config and per-account level. Per-account takes precedence. **Per-account (recommended):** ```json5 { channels: { whatsapp: { accounts: { "default": { groupAllowFrom: ["+15551234567", "+15559876543"], groupPolicy: "allowlist", groupContextFromAll: true // <-- NEW: see all group messages as context } } } } } ``` **Top-level (applies to all accounts):** ```json5 { channels: { whatsapp: { groupContextFromAll: true } } } ``` ### Behavior | `groupContextFromAll` | Sender in `groupAllowFrom` | Result | |---|---|---| | `false` (default) | No | Message **dropped** (existing behavior) | | `false` (default) | Yes | Message processed normally | | `true` | No | Message **stored as pending context** (visible in `[Chat messages since your last reply]`) but cannot trigger a reply | | `true` | Yes | Message processed normally | ### What "context only" means - Message appears in the `[Chat messages since your last reply - for context]` block - Message **cannot** trigger the agent (no reply generated) - No read receipts sent for context-only messages - Sender name and number are visible in context ## Changes **6 files changed:** - `src/web/inbound/access-control.ts` — Added `storeForContext` to result type; when `groupContextFromAll` is enabled and sender fails `groupAllowFrom`, returns `storeForContext: true` instead of dropping - `src/web/inbound/monitor.ts` — Passes `storeForContext` messages through as `contextOnly` instead of `continue`-ing; skips read receipts for context-only messages - `src/web/inbound/types.ts` — Added `contextOnly?: boolean` to `WebInboundMessage` - `src/web/auto-reply/monitor/on-message.ts` — Stores `contextOnly` messages in group history via `recordPendingHistoryEntryIfEnabled` without triggering reply - `src/config/types.whatsapp.ts` — Added `groupContextFromAll?: boolean` to both top-level and per-account WhatsApp config - `src/config/zod-schema.providers-whatsapp.ts` — Added schema validation for `groupContextFromAll` - `src/web/accounts.ts` — Added `groupContextFromAll` to `ResolvedWhatsAppAccount` ## Backward Compatibility - `groupContextFromAll` defaults to `false` — **zero behavior change** for existing installations - Opt-in only: users must explicitly enable it - No changes to DM behavior - No changes to `groupPolicy: "open"` or `groupPolicy: "disabled"` behavior ## Checklist - [x] Code word: lobster-biscuit ## Tested Verified locally with two bot instances in a WhatsApp group. Before the fix, Bot A could not see Bot B's messages. After enabling `groupContextFromAll: true`, Bot A correctly sees Bot B's messages in its context window and can reference them when triggered. <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR introduces an opt-in WhatsApp config flag `groupContextFromAll` (top-level + per-account) to retain group messages from non-allowlisted senders as *pending context* instead of dropping them. The change threads a new access-control outcome (`storeForContext`) through the inbound monitor to mark such messages as `contextOnly` (and skip read receipts), and then stores them in group history without triggering an auto-reply. This fits into the existing WhatsApp inbound pipeline by splitting “can trigger a reply” (`allowed`) from “should be retained for context” (`storeForContext`/`contextOnly`), enabling the documented mention-gating context behavior to work even when `groupPolicy: "allowlist"` blocks triggering. <h3>Confidence Score: 3/5</h3> - This PR is likely safe to merge but has a correctness edge case around allowlist matching/normalization. - Changes are localized and clearly scoped, but the allowlist comparison mixes normalized allowlist entries with a potentially non-normalized `senderE164`, which could silently misclassify senders and change behavior (especially with `groupContextFromAll` enabled). The new context-only early return also bypasses existing group gating/state updates, which may lead to subtle behavioral inconsistencies depending on what `applyGroupGating` manages. - src/web/inbound/access-control.ts; src/web/auto-reply/monitor/on-message.ts <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs