From 30a5c441f32109bc8d4e424903e70564bba71ed3 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Wed, 22 Apr 2026 23:39:21 -0700 Subject: [PATCH] docs(channels): cover WhatsApp replyToMode, Discord inheritParent, Slack HTTP/ACP/downloadFile, Telegram webhook+picker auth, Mattermost reasoning suppression, workspace .env block for channel endpoints --- docs/channels/discord.md | 4 ++++ docs/channels/mattermost.md | 1 + docs/channels/slack.md | 9 +++++++++ docs/channels/telegram.md | 6 ++++++ docs/channels/whatsapp.md | 22 ++++++++++++++++++++++ docs/gateway/security/index.md | 1 + 6 files changed, 43 insertions(+) diff --git a/docs/channels/discord.md b/docs/channels/discord.md index 76e1e6d0238..6a85670118c 100644 --- a/docs/channels/discord.md +++ b/docs/channels/discord.md @@ -655,6 +655,10 @@ Default slash command settings: - Discord threads are routed as channel sessions - parent thread metadata can be used for parent-session linkage - thread config inherits parent channel config unless a thread-specific entry exists + - parent transcript inheritance into newly created auto-threads is opt-in via `channels.discord.thread.inheritParent` (default `false`). When `false`, newly created Discord thread sessions start isolated from the parent channel transcript; when `true`, the parent channel history seeds the new thread session + - per-account overrides live under `channels.discord.accounts..thread.inheritParent` + - message-tool reactions can resolve `user:` DM targets in addition to channel targets + - `channels.discord.guilds..channels..requireMention: false` is preserved during reply-stage activation fallback, so configured always-on channels stay always-on even when reply-stage fallback runs Channel topics are injected as **untrusted** context (not as system prompt). Reply and quoted-message context currently stays as received. diff --git a/docs/channels/mattermost.md b/docs/channels/mattermost.md index 413c76cb80f..e534f100e94 100644 --- a/docs/channels/mattermost.md +++ b/docs/channels/mattermost.md @@ -267,6 +267,7 @@ Notes: - `progress` shows a status preview while generating and only posts the final answer at completion. - `off` disables preview streaming. - If the stream cannot be finalized in place (for example the post was deleted mid-stream), OpenClaw falls back to sending a fresh final post so the reply is never lost. +- Reasoning-only payloads are suppressed from channel posts, including text that arrives as a `> Reasoning:` blockquote. Set `/reasoning on` to see thinking in other surfaces; the Mattermost final post keeps the answer only. - See [Streaming](/concepts/streaming#preview-streaming-modes) for the channel-mapping matrix. ## Reactions (message tool) diff --git a/docs/channels/slack.md b/docs/channels/slack.md index 3e1c11f184d..b77b74a0909 100644 --- a/docs/channels/slack.md +++ b/docs/channels/slack.md @@ -710,6 +710,8 @@ Manual reply tags are supported: Note: `replyToMode="off"` disables **all** reply threading in Slack, including explicit `[[reply_to_*]]` tags. This differs from Telegram, where explicit tags are still honored in `"off"` mode. The difference reflects the platform threading models: Slack threads hide messages from the channel, while Telegram replies remain visible in the main chat flow. +Focused Slack thread replies route through their bound ACP session when one exists, instead of preparing the reply against the default agent shell. That keeps `/focus` and `/acp spawn ... --bind here` bindings intact for follow-up messages in the thread. + ## Ack reactions `ackReaction` sends an acknowledgement emoji while OpenClaw is processing an inbound message. @@ -744,6 +746,7 @@ Notes: - Media and non-text payloads fall back to normal delivery. - Media/error finals cancel pending preview edits without flushing a temporary draft; eligible text/block finals flush only when they can edit the preview in place. - If streaming fails mid-reply, OpenClaw falls back to normal delivery for remaining payloads. +- Slack Connect channels that reject a stream before the SDK flushes its local buffer fall back to normal Slack replies, so short replies are not silently dropped or reported as delivered before Slack acknowledges them. Use draft preview instead of Slack native text streaming: @@ -1032,6 +1035,12 @@ openclaw pairing list slack snapshots, the HTTP account is configured but the current runtime could not resolve the SecretRef-backed signing secret. + Registered Request URL webhooks are dispatched through the same shared handler registry used by Slack monitor setup, so HTTP-mode Slack events keep routing through the registered path instead of 404ing after successful route registration. + + + + + The `downloadFile` helper resolves its bot token from the runtime config when a caller passes `cfg` without an explicit `token` or prebuilt client, preserving cfg-only file downloads outside the action runtime path. diff --git a/docs/channels/telegram.md b/docs/channels/telegram.md index 37fab1f1695..34e8af2f7b1 100644 --- a/docs/channels/telegram.md +++ b/docs/channels/telegram.md @@ -745,6 +745,10 @@ curl "https://api.telegram.org/bot/getUpdates" + + Group model-picker inline buttons require the same authorization as `/models`. Unauthorized participants can browse and tap buttons, but OpenClaw rejects the callback before changing the session model. + + Default: long polling. @@ -761,6 +765,8 @@ curl "https://api.telegram.org/bot/getUpdates" If your public endpoint differs, place a reverse proxy in front and point `webhookUrl` at the public URL. Set `webhookHost` (for example `0.0.0.0`) when you intentionally need external ingress. + The grammY webhook callback returns a 200 within 5 seconds so Telegram does not retry long-running updates as read timeouts; longer work continues in the background. Polling rebuilds the HTTP transport after `getUpdates` 409 conflicts, so retries use a fresh TCP connection instead of looping on a Telegram-terminated keep-alive socket. + diff --git a/docs/channels/whatsapp.md b/docs/channels/whatsapp.md index f5d20592340..b6c8881ac46 100644 --- a/docs/channels/whatsapp.md +++ b/docs/channels/whatsapp.md @@ -331,6 +331,28 @@ When the linked self number is also present in `allowFrom`, WhatsApp self-chat s +## Reply quoting + +WhatsApp supports native reply quoting, where outbound replies visibly quote the inbound message. Control it with `channels.whatsapp.replyToMode`. + +| Value | Behavior | +| -------- | ---------------------------------------------------------------------------------- | +| `"auto"` | Quote the inbound message when the provider supports it; skip quoting otherwise | +| `"on"` | Always quote the inbound message; fall back to a plain send if quoting is rejected | +| `"off"` | Never quote; send as a plain message | + +Default is `"auto"`. Per-account overrides use `channels.whatsapp.accounts..replyToMode`. + +```json5 +{ + channels: { + whatsapp: { + replyToMode: "on", + }, + }, +} +``` + ## Reaction level `channels.whatsapp.reactionLevel` controls how broadly the agent uses emoji reactions on WhatsApp: diff --git a/docs/gateway/security/index.md b/docs/gateway/security/index.md index 2b202b24a64..d64ac5f462a 100644 --- a/docs/gateway/security/index.md +++ b/docs/gateway/security/index.md @@ -1042,6 +1042,7 @@ Hardening tips: OpenClaw loads workspace-local `.env` files for agents and tools, but never lets those files silently override gateway runtime controls. - Any key that starts with `OPENCLAW_*` is blocked from untrusted workspace `.env` files. +- Channel endpoint settings for Matrix, Mattermost, IRC, and Synology Chat are also blocked from workspace `.env` overrides, so cloned workspaces cannot redirect bundled connector traffic through local endpoint config. Endpoint env keys (such as `MATRIX_HOMESERVER`, `MATTERMOST_URL`, `IRC_HOST`, `SYNOLOGY_CHAT_INCOMING_URL`) must come from the gateway process environment or `env.shellEnv`, not from a workspace-loaded `.env`. - The block is fail-closed: a new runtime-control variable added in a future release cannot be inherited from a checked-in or attacker-supplied `.env`; the key is ignored and the gateway keeps its own value. - Trusted process/OS environment variables (the gateway's own shell, launchd/systemd unit, app bundle) still apply — this only constrains `.env` file loading.