* fix(whatsapp): extract GIF metadata and distinguish gifPlayback in media placeholders (fixes#49099)
- Add escapeAttr() helper to sanitize quotes and angle brackets in XML attribute values
- Add extractExternalAdReplyMetadata() to extract title, sourceUrl, body from contextInfo.externalAdReply
- Distinguish GIFs from videos using videoMessage.gifPlayback flag (media:gif vs media:video)
- Enrich image and video placeholders with externalAdReply metadata when available
- Add 5 test cases covering GIF detection, metadata extraction, attribute escaping, and empty fields
* fix(whatsapp): keep GIF metadata in untrusted context
---------
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
* fix(whatsapp): preserve auth on passive terminal stops
* fix(whatsapp): recover stale web auth during relink
* fix(gateway): defer channel stop until qr takeover
The inline-code/fence restore step matched the placeholder index with a
greedy `(\d+)`, so a digit in user text immediately after a code span
(e.g. `code`5) was absorbed into the index, resolved to undefined, and
`?? ""` deleted both the code span and the digit. Terminate the
placeholder index with the existing NUL marker so the index boundary is
unambiguous.
Co-authored-by: Dr Rushindra Sinha <5796457+rushindrasinha@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* fix: add timeout to waitForWaConnection to prevent indefinite hangs
If Baileys fails to emit a 'connection.update' event with either 'open'
or 'close' status (e.g. due to network issues or internal errors), the
waitForWaConnection promise hangs forever, blocking the entire monitor
loop.
Add a configurable timeout (default 60s) that rejects the promise and
cleans up the event listener if no connection state is received in time.
The timeout is backward-compatible as an optional parameter with a
sensible default.
* test: add coverage for waitForWaConnection timeout path
- Test that promise rejects with descriptive error after timeout
- Test that event listener is cleaned up after timeout
- Test that timer is cleared when connection opens before timeout
* fix: default timeoutMs to 0 to preserve QR login behavior
The 60s default broke the QR login flow in login-qr.ts, which calls
waitForWaConnection without a timeout and expects to wait up to 3 minutes
while the user scans. Change the default to 0 (wait forever, matching
original behavior) and pass the 60s timeout explicitly at the monitor
callsite where it's actually needed.
* fix: bound whatsapp connection startup waits
* fix: align web channel wait contract
* fix: retry whatsapp setup timeouts
* fix: satisfy whatsapp status lint
* fix: preserve whatsapp wait compatibility
---------
Co-authored-by: MMMMSSSS8899 <praelovk@gmail.com>
Suppress WhatsApp typing indicators only for silent message-tool-only unmentioned group runs. Automatic visible replies and authorized group commands still show composing normally.
Fixes the autoreview regression risk by narrowing suppressTyping and adding coverage for both silent and visible group paths.
Proof:
- pnpm test src/auto-reply/reply/reply-utils.test.ts extensions/whatsapp/src/auto-reply/monitor/inbound-dispatch.test.ts
- .agents/skills/autoreview/scripts/autoreview --mode local
- .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main
- CI run 26717880577 green
Thanks @Bluetegu.
## Summary
- Document scoped configured mention-pattern policy on the Groups page, including allow/deny mode semantics, supported conversation IDs, account-level precedence, and native-mention behavior.
- Add config UI help for `mentionPatterns.mode`, `allowIn`, and `denyIn` on Discord, Matrix, Slack, Telegram, and WhatsApp.
- Regenerate channel config/docs/plugin SDK metadata baselines for the new hint copy.
Refs #70864.
## Verification
- git diff --check
- pnpm format:docs:check
- pnpm docs:check-mdx
- pnpm docs:check-links
- pnpm config:channels:check
- pnpm config:docs:check
- pnpm plugin-sdk:api:check
- node scripts/run-vitest.mjs src/config/schema.hints.test.ts
- .agents/skills/autoreview/scripts/autoreview --mode local
## Real behavior proof
Behavior addressed: Documentation and config UI metadata for scoped configured mention-pattern policy.
Real environment tested: Local OpenClaw checkout on macOS.
Exact steps or command run after this patch: The verification commands listed above.
Evidence after fix: Docs formatting, MDX, link audit, generated config/channel/API baselines, and config hint tests passed; autoreview reported no accepted/actionable findings.
Observed result after fix: The Groups page now explains how to scope `messages.groupChat.mentionPatterns` with `channels.<channel>.mentionPatterns`, and config metadata exposes field help for the supported channels.
What was not tested: Live Discord, Matrix, Slack, Telegram, or WhatsApp inbound messages; this PR is documentation/config metadata only and follows the already-landed runtime behavior from #70864.
Provider-scoped configured regex mention patterns for Discord, Matrix, Slack, Telegram, and WhatsApp.
Native platform mentions keep their existing behavior, and unsupported channels do not opt into the new regex policy path. The new policy supports per-channel allow/deny routing through mentionPatterns.mode with allowIn and denyIn so group auto-reply regexes can be limited without broad global blast radius.
Refs #70864.
Supersedes #87200.
Thanks @patrick-slimelab.