#16655: fix(whatsapp): resolve reply-to sender E.164 for LID JIDs (have bot see replys without a mention even with "requireMention: true", like the Discord integration)
channel: whatsapp-web
stale
size: S
Cluster:
WhatsApp and Google Chat Fixes
WhatsApp quoted replies can identify the quoted sender using LID JIDs (e.g. `123@lid`). When reverse mapping is missing, we must not treat the raw JID as an E.164.
- Avoid falling back to raw JID for `senderE164` in `describeReplyContext`
- Resolve reply-to sender E.164 via `lidLookup` in the inbound monitor
- Add unit tests for `describeReplyContext`
## Summary
- **Problem:** In WhatsApp group chats, quoted replies can set `replyToSenderJid` to a LID JID (`...@lid`). When reverse mapping is missing, the code previously propagated the raw JID as `senderE164`, which later got normalized into a bogus `+<digits>` and broke implicit “reply-to-bot counts as mention” gating.
- **Why it matters:** Users replying to the bot’s message (without an explicit @mention) were not activating the bot, even though reply-to-bot is intended to count as an implicit mention.
- **What changed:**
- `describeReplyContext()` no longer falls back to the raw JID for `senderE164` when E.164 cannot be resolved.
- WhatsApp inbound monitor now attempts to resolve the quoted sender (`replyContext.senderJid`) to E.164 via `resolveJidToE164(..., { lidLookup })` and overwrites `senderE164/sender` when available.
- Added unit tests to lock in the corrected behavior.
- **What did NOT change (scope boundary):** No changes to mention regex matching, group policy defaults, config formats, or outbound sending. This is limited to WhatsApp inbound reply metadata normalization/resolution.
## Change Type (select all)
- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Docs
- [ ] Security hardening
- [ ] Chore/infra
## Scope (select all touched areas)
- [x] Gateway / orchestration
- [ ] Skills / tool execution
- [ ] Auth / tokens
- [ ] Memory / storage
- [x] Integrations
- [ ] API / contracts
- [ ] UI / DX
- [ ] CI/CD / infra
## Linked Issue/PR
None.
## User-visible / Behavior Changes
- WhatsApp group messages that **reply/quote** a bot message are more likely to trigger the bot as an implicit mention even when the quoted sender is identified via `@lid` (when `lidLookup` can resolve it).
- Prevents bogus `replyToSenderE164` values derived from LID JIDs (e.g. `262...@lid` → `+262...`) from interfering with gating logic.
## Security Impact (required)
- New permissions/capabilities? (`No`)
- Secrets/tokens handling changed? (`No`)
- New/changed network calls? (`No`)\*
- Command/tool execution surface changed? (`No`)
- Data access scope changed? (`No`)
\*Uses an existing Baileys `lidLookup` facility already present in the WhatsApp monitor runtime; this change only applies it to quoted-reply sender resolution.
## Repro + Verification
### Environment
- OS: Linux (local dev)
- Runtime/container: Node.js (OpenClaw gateway)
- Model/provider: N/A (pre-LLM gating/normalization)
- Integration/channel (if any): WhatsApp Web (Baileys)
- Relevant config (redacted): group chats with `requireMention: true`
### Steps
1. Run OpenClaw gateway logged into WhatsApp Web.
2. In a WhatsApp group with mention-gating enabled (`requireMention: true`), send a message as the bot identity.
3. From another account, **reply/quote** that bot message without an explicit @mention.
### Expected
- The reply should count as an implicit mention and proceed through normal processing (i.e., not be skipped as “no mention detected”).
### Actual (before)
- The reply could be skipped when `replyToSenderJid` was a LID JID and reverse mapping was missing (implicit mention computed as false).
## Evidence
- [x] Failing log before + passing behavior after (locally observed with verbose logs; reply-to-bot implicit mention was false before, true after when LID resolves)
- [x] Unit test(s) added and passing:
- `pnpm test:fast` includes `src/web/inbound/extract.test.ts` (new)
## Human Verification (required)
- Verified scenarios:
- Unit tests for `describeReplyContext`:
- LID JID without reverse mapping does **not** populate `senderE164` - PN JID populates `senderE164` correctly
- Edge cases checked:
- Quoted sender present vs absent
- What you did **not** verify:
- Full end-to-end WhatsApp group activation via CI (relies on local reproduction / unit tests)
- Behavior when `lidLookup` itself is unavailable (falls back to existing behavior; no E.164 resolution)
## Compatibility / Migration
- Backward compatible? (`Yes`)
- Config/env changes? (`No`)
- Migration needed? (`No`)
## Failure Recovery (if this breaks)
- How to disable/revert this change quickly:
- Revert this commit.
- Known bad symptoms reviewers should watch for:
- `ReplyToSenderE164` unexpectedly becoming undefined for quoted replies where previously it was set to a raw `@lid` JID (intentional; it was not a real E.164).
## Risks and Mitigations
- Risk: Slight additional async work on messages that contain quoted reply metadata (attempting LID→PN resolution).
- Mitigation: Only runs when `replyContext.senderJid` exists; otherwise no behavior change.
- Risk: Downstream code expecting `replyToSenderE164` to be populated with *something* even when not resolvable.
- Mitigation: We still preserve `replyToSenderJid` and `replyToSender` for context; we avoid populating misleading E.164 values.
## AI-assisted disclosure
This PR was **AI-assisted** (authored with help from Codex/OpenAI tooling). I validated the change by reproducing the issue locally (verbose gateway logs) and by adding/running unit tests (`src/web/inbound/extract.test.ts`). Reviewers should focus on the WhatsApp inbound reply-context normalization (`src/web/inbound/extract.ts` + `src/web/inbound/monitor.ts`) and the new test coverage.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes a bug where WhatsApp quoted replies with LID JIDs (e.g. `26285350879314@lid`) were incorrectly propagated as E.164 phone numbers, breaking the implicit "reply-to-bot counts as mention" gating in groups with `requireMention: true`.
- **`extract.ts`**: `describeReplyContext()` no longer falls back to the raw JID for `senderE164` — it's now `undefined` when `jidToE164()` can't resolve the JID, preventing bogus `+<digits>` numbers from being created downstream via `normalizeE164`.
- **`monitor.ts`**: Adds async LID→E.164 resolution for the quoted reply sender using the existing `resolveInboundJid` helper (backed by `lidLookup`). This correctly resolves LID JIDs when the Baileys signal repository has the mapping available.
- **`extract.test.ts`**: New unit tests covering LID JID (no reverse mapping → `senderE164` is `undefined`) and PN JID (correctly extracts E.164) scenarios.
The changes are well-scoped to inbound reply metadata normalization and do not affect mention regex matching, group policy defaults, or outbound sending.
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge — it's a well-scoped bug fix with correct logic and new test coverage.
- The changes are minimal and targeted: two lines changed in extract.ts (removing an incorrect fallback), a ~12-line async resolution block added in monitor.ts using existing infrastructure, and new unit tests. The logic is sound — verified by tracing through jidToE164, resolveJidToE164, normalizeE164, and the downstream group-gating implicit mention detection. The defensive guard in monitor.ts (lines 261-264) is effectively unreachable after the extract.ts fix but is harmless. Score is 4 rather than 5 because the monitor.ts changes introduce an additional async call per message with reply context, which has a small performance surface, and because the defensive guard is dead code that could be cleaned up.
- No files require special attention. All changes are straightforward and well-tested.
<sub>Last reviewed commit: d4812e6</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#23059: fix(whatsapp): resolve LID JIDs for reply-to-bot implicit mention d...
by azisseno · 2026-02-21
91.0%
#23046: fix(whatsapp): detect LID JID in implicit reply-to-bot mention check
by hydro13 · 2026-02-21
88.9%
#11166: fix(whatsapp): detect LID @mentions in self-chat mode
by mcaxtr · 2026-02-07
85.8%
#2772: fix: search WhatsApp account subdirs for LID mapping files
by impozzible · 2026-01-27
85.1%
#23251: fix(whatsapp): include LID in implicit mention detection for group ...
by SidQin-cyber · 2026-02-22
83.7%
#16608: feat(whatsapp): resolve outbound @mentions to clickable WhatsApp me...
by lucasmpramos · 2026-02-14
82.3%
#22106: fix(whatsapp): honor selfChatMode override for group mentions
by sportclaw · 2026-02-20
81.5%
#12069: fix(whatsapp): handle native group @mentions with requireMention
by abhishek0450 · 2026-02-08
80.7%
#5665: fix: match group JIDs in groupAllowFrom allowlist
by koala73 · 2026-01-31
79.9%
#17256: fix: allow text regex fallback when bot JID not in mentionedJids
by DarlingtonDeveloper · 2026-02-15
79.5%