Runtime model
- Gateway owns the Discord connection.
- Reply routing is deterministic: Discord inbound replies back to Discord.
- Bot replies and thread-bound persona replies share Markdown formatting, including CommonMark bold and configured table conversion.
- Forwarded message snapshots reach the agent together with any accompanying caption. Forwarded text is not treated as a typed command; command classification uses only the sender’s own message text.
- Discord guild/channel metadata is added to the model prompt as untrusted context, not as a user-visible reply prefix. If a model copies that envelope back, OpenClaw strips the copied metadata from outbound replies and from future replay context.
- By default (
session.dmScope=main), direct chats share the agent main session (agent:main:main). - Guild channels are isolated session keys (
agent:<agentId>:discord:channel:<channelId>). - Group DMs are ignored by default (
channels.discord.dm.groupEnabled=false). - Native slash commands run in isolated command sessions (
agent:<agentId>:discord:slash:<userId>), while still carryingCommandTargetSessionKeyto the routed conversation session. - Text-only cron/heartbeat announce delivery to Discord collapses to the final assistant-visible answer, sent once. Media and structured component payloads remain multi-message when the agent emits multiple deliverable payloads.
- A send response without a Discord message ID stays unconfirmed. Queued delivery records the missing identity for recovery instead of reporting success or immediately sending a duplicate; inspect delivery warnings with
openclaw health --verbose.
Message behavior
Introductions when joining a server
Introductions when joining a server
When the bot joins an allowed Discord server, OpenClaw posts one room-specific introduction. It prefers the server’s system channel when the bot can view and send messages there; otherwise, it uses the first text channel with both View Channel and Send Messages permissions. If no eligible channel exists, no introduction is sent.Introductions use the channel name and topic, plus recent messages when available. Reading earlier messages also requires Read Message History; when that permission is missing, OpenClaw still introduces itself using channel metadata instead of failing.Introductions are enabled by default, apply only to newly joined servers, and never run in direct messages. Set
channels.discord.joinIntro: false to disable them, or set channels.discord.accounts.<accountId>.joinIntro to override one account. See group join introductions for the history limits, target-channel selection, once-per-room behavior, and untrusted-content handling.Link previews
Link previews
Discord generates rich link embeds for URLs by default. OpenClaw suppresses those generated embeds on outbound Discord messages by default, so agent-sent URLs stay plain links unless you opt in:Set
channels.discord.accounts.<id>.suppressEmbeds to override one account. Agent message-tool sends can also pass suppressEmbeds: false for a single message. Explicit Discord embeds payloads are not suppressed by the default link-preview setting.Live stream preview
Live stream preview
OpenClaw can stream draft replies by sending a temporary message and editing it as text arrives. Discord preview streaming defaults to Preview streaming is text-only; media replies fall back to normal delivery.
off; set channels.discord.streaming.mode to partial, block, or progress to opt in. streamMode is a legacy alias; run openclaw doctor --fix to rewrite persisted config to the canonical nested streaming shape.offdisables Discord preview edits.partialedits a single preview message as tokens arrive.blockemits draft-sized chunks; tune size and breakpoints withstreaming.preview.chunk(minChars,maxChars,breakPreference), clamped totextChunkLimit. An explicit non-offpreview mode overrides inheritedagents.defaults.blockStreamingDefault: "on"; explicitstreaming.block.enabled: trueoverrides the preview. If a turn cannot use previews, inherited block delivery still applies.progresskeeps one editable status draft until final delivery. By default it is quiet: the agent’s latest preamble or narration as a status headline, 💬 commentary and 🧠 reasoning when they stream, ✅ / ▸ / ▢ plan steps, and any approval request or failed command. Ordinary tool calls do not add rows.- Media, error, and explicit-reply finals cancel pending preview edits.
streaming.progress.toolProgress: trueadds the rolling tool log underneath the headline: rows such as🛠️ Bash: run testsor🔎 Web Search: for "query"(defaultfalse).streaming.preview.toolProgresscontrols tool rows inpartialandblockmodes, where they default totrue.streaming.progress.commentary(defaultfalse) opts into raw assistant commentary in the temporary progress draft. The default preamble/narration status line is independent of this option. Commentary is cleaned before display, stays transient, and does not change final answer delivery.streaming.progress.maxLineCharscontrols the per-line progress preview budget. Prose is shortened on word boundaries; command and path details keep useful suffixes.streaming.preview.commandText/streaming.progress.commandTextcontrols command/exec detail in compact progress lines:status(default, tool label only) orraw(explicit command text).
Ack reactions
Ack reactions
Status reactions keep the acknowledgement stable throughout work. They do not add per-tool emoji, inactivity warnings, or a success flash. Actual failures retain the error reaction lifecycle.
ackReaction sends an acknowledgement emoji while OpenClaw processes an inbound message.Resolution order:channels.discord.accounts.<accountId>.ackReactionchannels.discord.ackReactionmessages.ackReaction- agent identity emoji fallback (
agents.entries.*.identity.emoji, else ”👀”)
- Discord accepts unicode emoji or custom emoji names.
- Use
""to disable the reaction for a channel or account.
messages.ackReactionScope):Values: "all" (DMs + groups, including ambient room events), "direct" (DMs only), "group-all" (every group message except ambient room events, no DMs), "group-mentions" (groups when the bot is mentioned; no DMs, default), "off" / "none" (disabled).The default scope (
"group-mentions") does not fire ack reactions in direct messages or ambient room events. To get an ack reaction on inbound Discord DMs and quiet room events, set messages.ackReactionScope to "all".Outbound mention aliases
Outbound mention aliases
Use
mentionAliases when agents need deterministic outbound mentions for known Discord users. Keys are handles without the leading @; values are Discord user IDs. Unknown handles, @everyone, @here, and mentions inside Markdown code spans are left unchanged.