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. - 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).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)spawnSubagentSessions: opt-in switch forsessions_spawn({ thread: true })auto thread creation/binding
- 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 + TTS overrides.channels.discord.voice.daveEncryptionandchannels.discord.voice.decryptionFailureTolerancepass through to@discordjs/voiceDAVE options (trueand24by default).- OpenClaw additionally attempts voice receive recovery by leaving/rejoining a voice session after repeated decrypt failures.
channels.discord.streamingis the canonical stream mode key. LegacystreamModeand booleanstreamingvalues are auto-migrated.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). 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 are auto-migrated.- 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 use
typingReactionor normal delivery instead of the thread-style 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 plugin:openclaw plugins install @openclaw/mattermost.
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.
BlueBubbles
BlueBubbles is the recommended iMessage path (plugin-backed, configured underchannels.bluebubbles).
- Core key paths covered here:
channels.bluebubbles,channels.bluebubbles.dmPolicy. - Optional
channels.bluebubbles.defaultAccountoverrides default account selection when it matches a configured account id. - Top-level
bindings[]entries withtype: "acp"can bind BlueBubbles conversations to persistent ACP sessions. Use a BlueBubbles handle or target string (chat_id:*,chat_guid:*,chat_identifier:*) inmatch.peer.id. Shared field semantics: ACP Agents. - Full BlueBubbles channel configuration is documented in BlueBubbles.
iMessage
OpenClaw spawnsimsg rpc (JSON-RPC over stdio). No daemon or port required.
-
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. -
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. 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.
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").falseclears previously registered commands. - 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