Per-channel configuration keys underDocumentation Index
Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
channels.*. Covers DM and group access,
multi-account setups, mention gating, and per-channel keys for Slack, Discord,
Telegram, WhatsApp, Matrix, iMessage, and the other bundled channel plugins.
For agents, tools, gateway runtime, and other top-level keys, see
Configuration reference.
Channels
Each channel starts automatically when its config section exists (unlessenabled: false).
DM and group access
All channels support DM policies and group policies:| DM policy | Behavior |
|---|---|
pairing (default) | Unknown senders get a one-time pairing code; owner must approve |
allowlist | Only senders in allowFrom (or paired allow store) |
open | Allow all inbound DMs (requires allowFrom: ["*"]) |
disabled | Ignore all inbound DMs |
| Group policy | Behavior |
|---|---|
allowlist (default) | Only groups matching the configured allowlist |
open | Bypass group allowlists (mention-gating still applies) |
disabled | Block all group/room messages |
channels.defaults.groupPolicy sets the default when a provider’s groupPolicy is unset.
Pairing codes expire after 1 hour. Pending DM pairing requests are capped at 3 per channel.
If a provider block is missing entirely (channels.<provider> absent), runtime group policy falls back to allowlist (fail-closed) with a startup warning.Channel model overrides
Usechannels.modelByChannel to pin specific channel IDs to a model. Values accept provider/model or configured model aliases. The channel mapping applies when a session does not already have a model override (for example, set via /model).
Channel defaults and heartbeat
Usechannels.defaults for shared group-policy and heartbeat behavior across providers:
channels.defaults.groupPolicy: fallback group policy when a provider-levelgroupPolicyis unset.channels.defaults.contextVisibility: default supplemental context visibility mode for all channels. Values:all(default, include all quoted/thread/history context),allowlist(only include context from allowlisted senders),allowlist_quote(same as allowlist but keep explicit quote/reply context). Per-channel override:channels.<channel>.contextVisibility.channels.defaults.heartbeat.showOk: include healthy channel statuses in heartbeat output.channels.defaults.heartbeat.showAlerts: include degraded/error statuses in heartbeat output.channels.defaults.heartbeat.useIndicator: render compact indicator-style heartbeat output.
Multi-account WhatsApp
Multi-account WhatsApp
- Outbound commands default to account
defaultif present; otherwise the first configured account id (sorted). - Optional
channels.whatsapp.defaultAccountoverrides that fallback default account selection when it matches a configured account id. - Legacy single-account Baileys auth dir is migrated by
openclaw doctorintowhatsapp/default. - Per-account overrides:
channels.whatsapp.accounts.<id>.sendReadReceipts,channels.whatsapp.accounts.<id>.dmPolicy,channels.whatsapp.accounts.<id>.allowFrom.
Telegram
- Bot token:
channels.telegram.botTokenorchannels.telegram.tokenFile(regular file only; symlinks rejected), withTELEGRAM_BOT_TOKENas fallback for the default account. apiRootis the Telegram Bot API root only. Usehttps://api.telegram.orgor your self-hosted/proxy root, nothttps://api.telegram.org/bot<TOKEN>;openclaw doctor --fixremoves an accidental trailing/bot<TOKEN>suffix.- Optional
channels.telegram.defaultAccountoverrides default account selection when it matches a configured account id. - In multi-account setups (2+ account ids), set an explicit default (
channels.telegram.defaultAccountorchannels.telegram.accounts.default) to avoid fallback routing;openclaw doctorwarns when this is missing or invalid. configWrites: falseblocks Telegram-initiated config writes (supergroup ID migrations,/config set|unset).- Top-level
bindings[]entries withtype: "acp"configure persistent ACP bindings for forum topics (use canonicalchatId:topic:topicIdinmatch.peer.id). Field semantics are shared in ACP Agents. - Telegram stream previews use
sendMessage+editMessageText(works in direct and group chats). - Retry policy: see Retry policy.
Discord
- Token:
channels.discord.token, withDISCORD_BOT_TOKENas fallback for the default account. - Direct outbound calls that provide an explicit Discord
tokenuse that token for the call; account retry/policy settings still come from the selected account in the active runtime snapshot. - Optional
channels.discord.defaultAccountoverrides default account selection when it matches a configured account id. - Use
user:<id>(DM) orchannel:<id>(guild channel) for delivery targets; bare numeric IDs are rejected. - Guild slugs are lowercase with spaces replaced by
-; channel keys use the slugged name (no#). Prefer guild IDs. - Bot-authored messages are ignored by default.
allowBots: trueenables them; useallowBots: "mentions"to only accept bot messages that mention the bot (own messages still filtered). channels.discord.guilds.<id>.ignoreOtherMentions(and channel overrides) drops messages that mention another user or role but not the bot (excluding @everyone/@here).channels.discord.mentionAliasesmaps stable outbound@handletext to Discord user IDs before sending, so known teammates can be mentioned deterministically even when the transient directory cache is empty. Per-account overrides live underchannels.discord.accounts.<accountId>.mentionAliases.maxLinesPerMessage(default 17) splits tall messages even when under 2000 chars.channels.discord.threadBindingscontrols Discord thread-bound routing:enabled: Discord override for thread-bound session features (/focus,/unfocus,/agents,/session idle,/session max-age, and bound delivery/routing)idleHours: Discord override for inactivity auto-unfocus in hours (0disables)maxAgeHours: Discord override for hard max age in hours (0disables)spawnSessions: switch forsessions_spawn({ thread: true })and ACP thread-spawn auto thread creation/binding (default:true)defaultSpawnContext: native subagent context for thread-bound spawns ("fork"by default)
- Top-level
bindings[]entries withtype: "acp"configure persistent ACP bindings for channels and threads (use channel/thread id inmatch.peer.id). Field semantics are shared in ACP Agents. channels.discord.ui.components.accentColorsets the accent color for Discord components v2 containers.channels.discord.voiceenables Discord voice channel conversations and optional auto-join + LLM + TTS overrides. Text-only Discord configs leave voice off by default; setchannels.discord.voice.enabled=trueto opt in.channels.discord.voice.modeloptionally overrides the LLM model used for Discord voice channel responses.channels.discord.voice.daveEncryptionandchannels.discord.voice.decryptionFailureTolerancepass through to@discordjs/voiceDAVE options (trueand24by default).channels.discord.voice.connectTimeoutMscontrols the initial@discordjs/voiceReady wait for/vc joinand auto-join attempts (30000by default).channels.discord.voice.reconnectGraceMscontrols how long a disconnected voice session may take to enter reconnect signalling before OpenClaw destroys it (15000by default).- Discord voice playback is not interrupted by another user’s speaking-start event. To avoid feedback loops, OpenClaw ignores new voice capture while TTS is playing.
- OpenClaw additionally attempts voice receive recovery by leaving/rejoining a voice session after repeated decrypt failures.
channels.discord.streamingis the canonical stream mode key. Discord defaults tostreaming.mode: "progress"so tool/work progress appears in one edited preview message; setstreaming.mode: "off"to disable it. LegacystreamModeand booleanstreamingvalues remain runtime aliases; runopenclaw doctor --fixto rewrite persisted config.channels.discord.autoPresencemaps runtime availability to bot presence (healthy => online, degraded => idle, exhausted => dnd) and allows optional status text overrides.channels.discord.dangerouslyAllowNameMatchingre-enables mutable name/tag matching (break-glass compatibility mode).channels.discord.execApprovals: Discord-native exec approval delivery and approver authorization.enabled:true,false, or"auto"(default). In auto mode, exec approvals activate when approvers can be resolved fromapproversorcommands.ownerAllowFrom.approvers: Discord user IDs allowed to approve exec requests. Falls back tocommands.ownerAllowFromwhen omitted.agentFilter: optional agent ID allowlist. Omit to forward approvals for all agents.sessionFilter: optional session key patterns (substring or regex).target: where to send approval prompts."dm"(default) sends to approver DMs,"channel"sends to the originating channel,"both"sends to both. When target includes"channel", buttons are only usable by resolved approvers.cleanupAfterResolve: whentrue, deletes approval DMs after approval, denial, or timeout.
off (none), own (bot’s messages, default), all (all messages), allowlist (from guilds.<id>.users on all messages).
Google Chat
- Service account JSON: inline (
serviceAccount) or file-based (serviceAccountFile). - Service account SecretRef is also supported (
serviceAccountRef). - Env fallbacks:
GOOGLE_CHAT_SERVICE_ACCOUNTorGOOGLE_CHAT_SERVICE_ACCOUNT_FILE. - Use
spaces/<spaceId>orusers/<userId>for delivery targets. channels.googlechat.dangerouslyAllowNameMatchingre-enables mutable email principal matching (break-glass compatibility mode).
Slack
- Socket mode requires both
botTokenandappToken(SLACK_BOT_TOKEN+SLACK_APP_TOKENfor default account env fallback). - HTTP mode requires
botTokenplussigningSecret(at root or per-account). socketModepasses Slack SDK Socket Mode transport tuning through to the public Bolt receiver API. Use it only when investigating ping/pong timeout or stale websocket behavior.botToken,appToken,signingSecret, anduserTokenaccept plaintext strings or SecretRef objects.- Slack account snapshots expose per-credential source/status fields such as
botTokenSource,botTokenStatus,appTokenStatus, and, in HTTP mode,signingSecretStatus.configured_unavailablemeans the account is configured through SecretRef but the current command/runtime path could not resolve the secret value. configWrites: falseblocks Slack-initiated config writes.- Optional
channels.slack.defaultAccountoverrides default account selection when it matches a configured account id. channels.slack.streaming.modeis the canonical Slack stream mode key.channels.slack.streaming.nativeTransportcontrols Slack’s native streaming transport. LegacystreamMode, booleanstreaming, andnativeStreamingvalues remain runtime aliases; runopenclaw doctor --fixto rewrite persisted config.unfurlLinksandunfurlMediapass Slack’schat.postMessagelink and media unfurl booleans through for bot replies. Omit them to keep Slack’s default behavior; set them atchannels.slack.accounts.<accountId>to override the top-level default for one account.- Use
user:<id>(DM) orchannel:<id>for delivery targets.
off, own (default), all, allowlist (from reactionAllowlist).
Thread session isolation: thread.historyScope is per-thread (default) or shared across channel. thread.inheritParent copies parent channel transcript to new threads.
- Slack native streaming plus the Slack assistant-style “is typing…” thread status require a reply thread target. Top-level DMs stay off-thread by default, so they can still stream through Slack draft post-and-edit previews instead of showing the thread-style native stream/status preview.
typingReactionadds a temporary reaction to the inbound Slack message while a reply is running, then removes it on completion. Use a Slack emoji shortcode such as"hourglass_flowing_sand".channels.slack.execApprovals: Slack-native exec approval delivery and approver authorization. Same schema as Discord:enabled(true/false/"auto"),approvers(Slack user IDs),agentFilter,sessionFilter, andtarget("dm","channel", or"both").
| Action group | Default | Notes |
|---|---|---|
| reactions | enabled | React + list reactions |
| messages | enabled | Read/send/edit/delete |
| pins | enabled | Pin/unpin/list |
| memberInfo | enabled | Member info |
| emojiList | enabled | Custom emoji list |
Mattermost
Mattermost ships as a bundled plugin in current OpenClaw releases. Older or custom builds can install a current npm package withopenclaw plugins install @openclaw/mattermost. Check
npmjs.com/package/@openclaw/mattermost
for the current dist-tags before pinning a version.
oncall (respond on @-mention, default), onmessage (every message), onchar (messages starting with trigger prefix).
When Mattermost native commands are enabled:
commands.callbackPathmust be a path (for example/api/channels/mattermost/command), not a full URL.commands.callbackUrlmust resolve to the OpenClaw gateway endpoint and be reachable from the Mattermost server.- Native slash callbacks are authenticated with the per-command tokens returned
by Mattermost during slash command registration. If registration fails or no
commands are activated, OpenClaw rejects callbacks with
Unauthorized: invalid command token. - For private/tailnet/internal callback hosts, Mattermost may require
ServiceSettings.AllowedUntrustedInternalConnectionsto include the callback host/domain. Use host/domain values, not full URLs. channels.mattermost.configWrites: allow or deny Mattermost-initiated config writes.channels.mattermost.requireMention: require@mentionbefore replying in channels.channels.mattermost.groups.<channelId>.requireMention: per-channel mention-gating override ("*"for default).- Optional
channels.mattermost.defaultAccountoverrides default account selection when it matches a configured account id.
Signal
off, own (default), all, allowlist (from reactionAllowlist).
channels.signal.account: pin channel startup to a specific Signal account identity.channels.signal.configWrites: allow or deny Signal-initiated config writes.- Optional
channels.signal.defaultAccountoverrides default account selection when it matches a configured account id.
iMessage
OpenClaw spawnsimsg rpc (JSON-RPC over stdio). No daemon or port required. This is the preferred path for new OpenClaw iMessage setups when the host can grant Messages database and Automation permissions.
BlueBubbles support was removed. channels.bluebubbles is not a supported runtime config surface on current OpenClaw. Migrate old configs to channels.imessage; use BlueBubbles removal and the imsg iMessage path for the short version and Coming from BlueBubbles for the full translation table.
If the Gateway is not running on the signed-in Messages Mac, keep channels.imessage.enabled=true and set channels.imessage.cliPath to an SSH wrapper that runs imsg "$@" on that Mac. The default local imsg path is macOS-only.
-
Optional
channels.imessage.defaultAccountoverrides default account selection when it matches a configured account id. - Requires Full Disk Access to the Messages DB.
-
Prefer
chat_id:<id>targets. Useimsg chats --limit 20to list chats. -
cliPathcan point to an SSH wrapper; setremoteHost(hostoruser@host) for SCP attachment fetching. -
attachmentRootsandremoteAttachmentRootsrestrict inbound attachment paths (default:/Users/*/Library/Messages/Attachments). -
SCP uses strict host-key checking, so ensure the relay host key already exists in
~/.ssh/known_hosts. -
channels.imessage.configWrites: allow or deny iMessage-initiated config writes. -
channels.imessage.actions.*: enable private API actions that are also gated byimsg status/openclaw channels status --probe. -
channels.imessage.includeAttachmentsis off by default; set it totruebefore expecting inbound media in agent turns. -
channels.imessage.catchup.enabled: opt in to replaying inbound messages that arrived while the Gateway was down. -
channels.imessage.groups: group registry and per-group settings. WithgroupPolicy: "allowlist", configure either explicitchat_idkeys or a"*"wildcard entry so group messages can pass the registry gate. -
Top-level
bindings[]entries withtype: "acp"can bind iMessage conversations to persistent ACP sessions. Use a normalized handle or explicit chat target (chat_id:*,chat_guid:*,chat_identifier:*) inmatch.peer.id. Shared field semantics: ACP Agents.
iMessage SSH wrapper example
iMessage SSH wrapper example
Matrix
Matrix is plugin-backed and configured underchannels.matrix.
- Token auth uses
accessToken; password auth usesuserId+password. channels.matrix.proxyroutes Matrix HTTP traffic through an explicit HTTP(S) proxy. Named accounts can override it withchannels.matrix.accounts.<id>.proxy.channels.matrix.network.dangerouslyAllowPrivateNetworkallows private/internal homeservers.proxyand this network opt-in are independent controls.channels.matrix.defaultAccountselects the preferred account in multi-account setups.channels.matrix.autoJoindefaults tooff, so invited rooms and fresh DM-style invites are ignored until you setautoJoin: "allowlist"withautoJoinAllowlistorautoJoin: "always".channels.matrix.execApprovals: Matrix-native exec approval delivery and approver authorization.enabled:true,false, or"auto"(default). In auto mode, exec approvals activate when approvers can be resolved fromapproversorcommands.ownerAllowFrom.approvers: Matrix user IDs (e.g.@owner:example.org) allowed to approve exec requests.agentFilter: optional agent ID allowlist. Omit to forward approvals for all agents.sessionFilter: optional session key patterns (substring or regex).target: where to send approval prompts."dm"(default),"channel"(originating room), or"both".- Per-account overrides:
channels.matrix.accounts.<id>.execApprovals.
channels.matrix.dm.sessionScopecontrols how Matrix DMs group into sessions:per-user(default) shares by routed peer, whileper-roomisolates each DM room.- Matrix status probes and live directory lookups use the same proxy policy as runtime traffic.
- Full Matrix configuration, targeting rules, and setup examples are documented in Matrix.
Microsoft Teams
Microsoft Teams is plugin-backed and configured underchannels.msteams.
- Core key paths covered here:
channels.msteams,channels.msteams.configWrites. - Full Teams config (credentials, webhook, DM/group policy, per-team/per-channel overrides) is documented in Microsoft Teams.
IRC
IRC is plugin-backed and configured underchannels.irc.
- Core key paths covered here:
channels.irc,channels.irc.dmPolicy,channels.irc.configWrites,channels.irc.nickserv.*. - Optional
channels.irc.defaultAccountoverrides default account selection when it matches a configured account id. - Full IRC channel configuration (host/port/TLS/channels/allowlists/mention gating) is documented in IRC.
Multi-account (all channels)
Run multiple accounts per channel (each with its ownaccountId):
defaultis used whenaccountIdis omitted (CLI + routing).- Env tokens only apply to the default account.
- Base channel settings apply to all accounts unless overridden per account.
- Use
bindings[].match.accountIdto route each account to a different agent. - If you add a non-default account via
openclaw channels add(or channel onboarding) while still on a single-account top-level channel config, OpenClaw promotes account-scoped top-level single-account values into the channel account map first so the original account keeps working. Most channels move them intochannels.<channel>.accounts.default; Matrix can preserve an existing matching named/default target instead. - Existing channel-only bindings (no
accountId) keep matching the default account; account-scoped bindings remain optional. openclaw doctor --fixalso repairs mixed shapes by moving account-scoped top-level single-account values into the promoted account chosen for that channel. Most channels useaccounts.default; Matrix can preserve an existing matching named/default target instead.
Other plugin channels
Many plugin channels are configured aschannels.<id> and documented in their dedicated channel pages (for example Feishu, Matrix, LINE, Nostr, Zalo, Nextcloud Talk, Synology Chat, and Twitch).
See the full channel index: Channels.
Group chat mention gating
Group messages default to require mention (metadata mention or safe regex patterns). Applies to WhatsApp, Telegram, Discord, Google Chat, and iMessage group chats. Visible replies are controlled separately. Group/channel rooms default tomessages.groupChat.visibleReplies: "message_tool": OpenClaw still processes the turn, but normal final replies stay private and visible room output requires message(action=send). Set "automatic" only when you want the legacy behavior where normal replies are posted back to the room. To apply the same tool-only visible-reply behavior to direct chats too, set messages.visibleReplies: "message_tool"; the Codex harness also uses that tool-only behavior as its unset direct-chat default.
Tool-only visible replies require a model/runtime that reliably calls tools. If
the session log shows assistant text with didSendViaMessagingTool: false, the
model produced a private final answer instead of calling the message tool.
Switch to a stronger tool-calling model for that channel, or set
messages.groupChat.visibleReplies: "automatic" to restore legacy visible final
replies.
If the message tool is unavailable under the active tool policy, OpenClaw falls back to automatic visible replies instead of silently suppressing the response. openclaw doctor warns about this mismatch.
The gateway hot-reloads messages config after the file is saved. Restart only when file watching or config reload is disabled in the deployment.
Mention types:
- Metadata mentions: Native platform @-mentions. Ignored in WhatsApp self-chat mode.
- Text patterns: Safe regex patterns in
agents.list[].groupChat.mentionPatterns. Invalid patterns and unsafe nested repetition are ignored. - Mention gating is enforced only when detection is possible (native mentions or at least one pattern).
messages.groupChat.historyLimit sets the global default. Channels can override with channels.<channel>.historyLimit (or per-account). Set 0 to disable.
messages.visibleReplies is the global source-turn default; messages.groupChat.visibleReplies overrides it for group/channel source turns. When messages.visibleReplies is unset, a harness can provide its own direct/source default; the Codex harness defaults to message_tool. Channel allowlists and mention gating still decide whether a turn is processed.
DM history limits
telegram, whatsapp, discord, slack, signal, imessage, msteams.
Self-chat mode
Include your own number inallowFrom to enable self-chat mode (ignores native @-mentions, only responds to text patterns):
Commands (chat command handling)
Command details
Command details
- This block configures command surfaces. For the current built-in + bundled command catalog, see Slash Commands.
- This page is a config-key reference, not the full command catalog. Channel/plugin-owned commands such as QQ Bot
/bot-ping/bot-help/bot-logs, LINE/card, device-pair/pair, memory/dreaming, phone-control/phone, and Talk/voiceare documented in their channel/plugin pages plus Slash Commands. - Text commands must be standalone messages with leading
/. native: "auto"turns on native commands for Discord/Telegram, leaves Slack off.nativeSkills: "auto"turns on native skill commands for Discord/Telegram, leaves Slack off.- Override per channel:
channels.discord.commands.native(bool or"auto"). For Discord,falseskips native command registration and cleanup during startup. - Override native skill registration per channel with
channels.<provider>.commands.nativeSkills. channels.telegram.customCommandsadds extra Telegram bot menu entries.bash: trueenables! <cmd>for host shell. Requirestools.elevated.enabledand sender intools.elevated.allowFrom.<channel>.config: trueenables/config(reads/writesopenclaw.json). For gatewaychat.sendclients, persistent/config set|unsetwrites also requireoperator.admin; read-only/config showstays available to normal write-scoped operator clients.mcp: trueenables/mcpfor OpenClaw-managed MCP server config undermcp.servers.plugins: trueenables/pluginsfor plugin discovery, install, and enable/disable controls.channels.<provider>.configWritesgates config mutations per channel (default: true).- For multi-account channels,
channels.<provider>.accounts.<id>.configWritesalso gates writes that target that account (for example/allowlist --config --account <id>or/config set channels.<provider>.accounts.<id>...). restart: falsedisables/restartand gateway restart tool actions. Default:true.ownerAllowFromis the explicit owner allowlist for owner-only commands/tools. It is separate fromallowFrom.ownerDisplay: "hash"hashes owner ids in the system prompt. SetownerDisplaySecretto control hashing.allowFromis per-provider. When set, it is the only authorization source (channel allowlists/pairing anduseAccessGroupsare ignored).useAccessGroups: falseallows commands to bypass access-group policies whenallowFromis not set.- Command docs map:
Related
- Configuration reference — top-level keys
- Configuration — agents
- Channels overview