Discord (Bot API)
Status: Bereit für DMs und Server-Kanäle über das offizielle Discord-Gateway.
- Pairing — Discord-DMs nutzen standardmäßig den Pairing-Modus.
- Slash-Befehle — Natives Befehlsverhalten und Befehlskatalog.
- Kanal-Fehlerbehebung — Kanalübergreifende Diagnose und Reparaturabläufe.
Schnelleinrichtung
Du musst eine neue Anwendung mit Bot erstellen, den Bot zu deinem Server hinzufügen und ihn mit OpenClaw verknüpfen. Wir empfehlen, den Bot auf deinen eigenen privaten Server einzuladen. Falls du noch keinen hast, erstelle zuerst einen (wähle Eigenen erstellen > Für mich und meine Freunde).
Schritt 1: Discord-Anwendung und Bot erstellen
Gehe zum [Discord Developer Portal](https://discord.com/developers/applications) und klicke auf **New Application**. Benenne sie z. B. „OpenClaw".
Klicke in der Seitenleiste auf **Bot**. Setze den **Username** auf den Namen, den dein OpenClaw-Agent tragen soll.
Schritt 2: Privilegierte Intents aktivieren
Scrolle auf der **Bot**-Seite nach unten zu **Privileged Gateway Intents** und aktiviere:
- **Message Content Intent** (erforderlich)
- **Server Members Intent** (empfohlen; nötig für Rollen-Allowlists und Name-zu-ID-Zuordnung)
- **Presence Intent** (optional; nur für Presence-Updates benötigt)
Schritt 3: Bot-Token kopieren
Scrolle auf der **Bot**-Seite wieder nach oben und klicke auf **Reset Token**.
> **Hinweis:** Trotz des Namens wird hier dein erstes Token generiert — es wird nichts „zurückgesetzt".
Kopiere das Token und speichere es sicher ab. Das ist dein **Bot Token**, das du gleich brauchst.
Schritt 4: Einladungs-URL generieren und Bot zum Server hinzufügen
Klicke in der Seitenleiste auf **OAuth2**. Hier generierst du eine Einladungs-URL mit den richtigen Berechtigungen.
Scrolle nach unten zum **OAuth2 URL Generator** und aktiviere:
- `bot`
- `applications.commands`
Darunter erscheint ein Bereich **Bot Permissions**. Aktiviere:
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (optional)
Kopiere die generierte URL unten, füge sie in deinen Browser ein, wähle deinen Server und klicke auf **Continue**. Dein Bot sollte jetzt im Discord-Server sichtbar sein.
Schritt 5: Entwicklermodus aktivieren und IDs erfassen
Zurück in der Discord-App musst du den Entwicklermodus aktivieren, um interne IDs kopieren zu können.
1. Klicke auf **Benutzereinstellungen** (Zahnrad neben deinem Avatar) → **Erweitert** → schalte **Entwicklermodus** ein
2. Rechtsklick auf dein **Server-Symbol** in der Seitenleiste → **Server-ID kopieren**
3. Rechtsklick auf deinen **eigenen Avatar** → **Benutzer-ID kopieren**
Speichere deine **Server-ID** und **Benutzer-ID** zusammen mit dem Bot Token — du wirst alle drei im nächsten Schritt an OpenClaw übergeben.
Schritt 6: DMs von Server-Mitgliedern erlauben
Damit das Pairing funktioniert, muss Discord deinem Bot erlauben, dir DMs zu schicken. Rechtsklick auf dein **Server-Symbol** → **Privatsphäre-Einstellungen** → aktiviere **Direktnachrichten**.
So können Server-Mitglieder (einschließlich Bots) dir DMs senden. Lass das aktiviert, wenn du Discord-DMs mit OpenClaw nutzen willst. Falls du nur Server-Kanäle verwenden möchtest, kannst du DMs nach dem Pairing deaktivieren.
Schritt 7: Bot-Token sicher hinterlegen (nicht im Chat senden)
Dein Discord-Bot-Token ist ein Geheimnis (wie ein Passwort). Setze es auf dem Rechner, auf dem OpenClaw läuft, bevor du deinen Agenten anschreibst.
openclaw config set channels.discord.token '"YOUR_BOT_TOKEN"' --json
openclaw config set channels.discord.enabled true --json
openclaw gateway
Falls OpenClaw bereits als Hintergrunddienst läuft, verwende stattdessen `openclaw gateway restart`.
Schritt 8: OpenClaw konfigurieren und Pairing durchführen
#### Agent fragen
Schreibe deinem OpenClaw-Agenten auf einem bestehenden Kanal (z. B. Telegram) und sage ihm Bescheid. Falls Discord dein erster Kanal ist, nutze stattdessen den CLI-/Config-Weg.
> „Ich habe mein Discord-Bot-Token bereits in der Config gesetzt. Bitte schließe das Discord-Setup mit User-ID `<user_id>` und Server-ID `<server_id>` ab."
#### CLI / Config
Wenn du dateibasierte Konfiguration bevorzugst:
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN",
},
},
}
Env-Fallback für das Standard-Konto:
DISCORD_BOT_TOKEN=...
SecretRef-Werte werden ebenfalls für `channels.discord.token` unterstützt (env/file/exec-Provider). Siehe [Secrets Management](/docs/gateway/secrets).
Schritt 9: Erstes DM-Pairing bestätigen
Warte, bis das Gateway läuft, und sende deinem Bot eine DM in Discord. Er antwortet mit einem Pairing-Code.
#### Agent fragen
Sende den Pairing-Code an deinen Agenten auf dem bestehenden Kanal:
> „Genehmige diesen Discord-Pairing-Code: `<CODE>`"
#### CLI
openclaw pairing list discord
openclaw pairing approve discord <CODE>
Pairing-Codes laufen nach 1 Stunde ab.
Du solltest jetzt per DM in Discord mit deinem Agenten chatten können.
Hinweis: Die Token-Auflösung ist kontenabhängig. Config-Werte haben Vorrang vor dem Env-Fallback.
DISCORD_BOT_TOKENwird nur für das Standard-Konto verwendet. Für erweiterte ausgehende Aufrufe (Nachrichten-Tool/Kanal-Aktionen) wird ein explizitestokenpro Aufruf verwendet. Kontobezogene Richtlinien-/Retry-Einstellungen kommen weiterhin aus dem gewählten Konto im aktiven Runtime-Snapshot.
Empfohlen: Guild-Workspace einrichten
Sobald DMs funktionieren, kannst du deinen Discord-Server als vollwertigen Workspace einrichten, in dem jeder Kanal eine eigene Agent-Sitzung mit eigenem Kontext bekommt. Das ist ideal für private Server, auf denen nur du und dein Bot unterwegs sind.
Schritt 1: Server zur Guild-Allowlist hinzufügen
Damit reagiert dein Agent in jedem Kanal auf deinem Server, nicht nur in DMs.
#### Agent fragen
> „Füge meine Discord-Server-ID `<server_id>` zur Guild-Allowlist hinzu"
#### Config
{
channels: {
discord: {
groupPolicy: "allowlist",
guilds: {
YOUR_SERVER_ID: {
requireMention: true,
users: ["YOUR_USER_ID"],
},
},
},
},
}
Schritt 2: Antworten ohne @Mention erlauben
Standardmäßig antwortet dein Agent in Server-Kanälen nur, wenn er @erwähnt wird. Auf einem privaten Server willst du vermutlich, dass er auf jede Nachricht reagiert.
#### Agent fragen
> „Erlaube meinem Agenten, auf diesem Server ohne @Mention zu antworten"
#### Config
Setze `requireMention: false` in deiner Guild-Konfiguration:
{
channels: {
discord: {
guilds: {
YOUR_SERVER_ID: {
requireMention: false,
},
},
},
},
}
Schritt 3: Speicher in Server-Kanälen planen
Standardmäßig wird der Langzeitspeicher (MEMORY.md) nur in DM-Sitzungen geladen. Server-Kanäle laden MEMORY.md nicht automatisch.
#### Agent fragen
> „Wenn ich Fragen in Discord-Kanälen stelle, nutze memory_search oder memory_get, falls du Langzeitkontext aus MEMORY.md brauchst."
#### Manuell
Wenn du gemeinsamen Kontext in jedem Kanal benötigst, lege die stabilen Anweisungen in `AGENTS.md` oder `USER.md` ab (sie werden für jede Sitzung injiziert). Langfristige Notizen gehören in `MEMORY.md` und werden bei Bedarf per Memory-Tools abgerufen.
Erstelle jetzt Kanäle auf deinem Discord-Server und leg los. Dein Agent sieht den Kanalnamen, und jeder Kanal bekommt eine eigene isolierte Sitzung — so kannst du #coding, #home, #research oder was auch immer zu deinem Workflow passt einrichten.
Laufzeitmodell
- Das Gateway hält die Discord-Verbindung.
- Antwort-Routing ist deterministisch: Discord-Eingang wird an Discord zurückgeleitet.
- Standardmäßig (
session.dmScope=main) teilen sich Direkt-Chats die Agent-Hauptsitzung (agent:main:main). - Server-Kanäle bekommen isolierte Session-Keys (
agent:<agentId>:discord:channel:<channelId>). - Gruppen-DMs werden standardmäßig ignoriert (
channels.discord.dm.groupEnabled=false). - Native Slash-Befehle laufen in isolierten Command-Sessions (
agent:<agentId>:discord:slash:<userId>) und tragen dabeiCommandTargetSessionKeyzur gerouteten Konversationssitzung.
Forum-Kanäle
Discord-Forum- und Medien-Kanäle akzeptieren nur Thread-Posts. OpenClaw unterstützt zwei Wege, sie zu erstellen:
- Sende eine Nachricht an den Forum-Elternkanal (
channel:<forumId>), um automatisch einen Thread zu erstellen. Der Thread-Titel verwendet die erste nicht-leere Zeile deiner Nachricht. - Verwende
openclaw message thread create, um einen Thread direkt zu erstellen. Übergib bei Forum-Kanälen kein--message-id.
Beispiel: An den Forum-Elternkanal senden, um einen Thread zu erstellen
openclaw message send --channel discord --target channel:<forumId> \
--message "Topic title\nBody of the post"
Beispiel: Forum-Thread explizit erstellen
openclaw message thread create --channel discord --target channel:<forumId> \
--thread-name "Topic title" --message "Body of the post"
Forum-Elternkanäle akzeptieren keine Discord-Komponenten. Wenn du Komponenten brauchst, sende an den Thread selbst (channel:<threadId>).
Interaktive Komponenten
OpenClaw nutzt Discord Components v2 Container für Agent-Nachrichten. Verwende das Nachrichten-Tool mit einem components-Payload. Interaktionsergebnisse werden wie normale eingehende Nachrichten an den Agenten zurückgeleitet und folgen den bestehenden Discord-replyToMode-Einstellungen.
Unterstützte Blöcke:
text,section,separator,actions,media-gallery,file- Action-Rows erlauben bis zu 5 Buttons oder ein einzelnes Select-Menü
- Select-Typen:
string,user,role,mentionable,channel
Komponenten sind standardmäßig Einmal-Nutzung. Setze components.reusable=true, damit Buttons, Selects und Formulare mehrfach verwendet werden können, bis sie ablaufen.
Um einzuschränken, wer einen Button klicken darf, setze allowedUsers auf dem Button (Discord-User-IDs, Tags oder *). Nicht übereinstimmende Benutzer erhalten eine ephemerale Ablehnung.
Die Slash-Befehle /model und /models öffnen einen interaktiven Modell-Picker mit Provider- und Modell-Dropdowns plus Bestätigungsschritt. Die Picker-Antwort ist ephemeral und nur der aufrufende Benutzer kann sie verwenden.
Dateianhänge:
file-Blöcke müssen auf eine Attachment-Referenz verweisen (attachment://<filename>)- Stelle den Anhang über
media/path/filePathbereit (einzelne Datei); verwendemedia-galleryfür mehrere Dateien - Verwende
filename, um den Upload-Namen zu überschreiben, wenn er mit der Attachment-Referenz übereinstimmen soll
Modale Formulare:
- Füge
components.modalmit bis zu 5 Feldern hinzu - Feldtypen:
text,checkbox,radio,select,role-select,user-select - OpenClaw fügt automatisch einen Trigger-Button hinzu
Beispiel:
{
channel: "discord",
action: "send",
to: "channel:123456789012345678",
message: "Optional fallback text",
components: {
reusable: true,
text: "Choose a path",
blocks: [
{
type: "actions",
buttons: [
{
label: "Approve",
style: "success",
allowedUsers: ["123456789012345678"],
},
{ label: "Decline", style: "danger" },
],
},
{
type: "actions",
select: {
type: "string",
placeholder: "Pick an option",
options: [
{ label: "Option A", value: "a" },
{ label: "Option B", value: "b" },
],
},
},
],
modal: {
title: "Details",
triggerLabel: "Open form",
fields: [
{ type: "text", label: "Requester" },
{
type: "select",
label: "Priority",
options: [
{ label: "Low", value: "low" },
{ label: "High", value: "high" },
],
},
],
},
},
}
Zugriffskontrolle und Routing
DM-Richtlinie
`channels.discord.dmPolicy` steuert den DM-Zugriff (Legacy: `channels.discord.dm.policy`):
- `pairing` (Standard)
- `allowlist`
- `open` (erfordert `channels.discord.allowFrom` mit `"*"`; Legacy: `channels.discord.dm.allowFrom`)
- `disabled`
Ist die DM-Richtlinie nicht offen, werden unbekannte Benutzer blockiert (oder im `pairing`-Modus zum Pairing aufgefordert).
Multi-Account-Rangfolge:
- `channels.discord.accounts.default.allowFrom` gilt nur für das `default`-Konto.
- Benannte Konten erben `channels.discord.allowFrom`, wenn kein eigener `allowFrom`-Wert gesetzt ist.
- Benannte Konten erben nicht `channels.discord.accounts.default.allowFrom`.
DM-Zielformat für die Zustellung:
- `user:<id>`
- `<@id>` Mention
Nackte numerische IDs sind mehrdeutig und werden abgelehnt, sofern nicht explizit ein Zieltyp (user/channel) angegeben wird.
Guild-Richtlinie
Die Guild-Verarbeitung wird über `channels.discord.groupPolicy` gesteuert:
- `open`
- `allowlist`
- `disabled`
Sichere Basislinie wenn `channels.discord` existiert: `allowlist`.
`allowlist`-Verhalten:
- Guild muss in `channels.discord.guilds` enthalten sein (`id` bevorzugt, Slug akzeptiert)
- Optionale Absender-Allowlists: `users` (stabile IDs empfohlen) und `roles` (nur Rollen-IDs); ist eine davon konfiguriert, werden Absender erlaubt, wenn sie `users` ODER `roles` matchen
- Direkter Name-/Tag-Abgleich ist standardmäßig deaktiviert; aktiviere `channels.discord.dangerouslyAllowNameMatching: true` nur als Notfall-Kompatibilitätsmodus
- Namen/Tags werden für `users` unterstützt, aber IDs sind sicherer; `openclaw security audit` warnt bei Name-/Tag-Einträgen
- Hat eine Guild `channels` konfiguriert, werden nicht aufgelistete Kanäle abgelehnt
- Hat eine Guild keinen `channels`-Block, sind alle Kanäle in dieser erlaubten Guild zugelassen
Beispiel:
{
channels: {
discord: {
groupPolicy: "allowlist",
guilds: {
"123456789012345678": {
requireMention: true,
ignoreOtherMentions: true,
users: ["987654321098765432"],
roles: ["123456789012345678"],
channels: {
general: { allow: true },
help: { allow: true, requireMention: true },
},
},
},
},
},
}
Wenn du nur `DISCORD_BOT_TOKEN` setzt und keinen `channels.discord`-Block erstellst, fällt die Laufzeit auf `groupPolicy="allowlist"` zurück (mit Warnung in den Logs), selbst wenn `channels.defaults.groupPolicy` auf `open` steht.
Mentions und Gruppen-DMs
Server-Nachrichten sind standardmäßig mention-gated.
Mention-Erkennung umfasst:
- Explizite Bot-Erwähnung
- Konfigurierte Mention-Patterns (`agents.list[].groupChat.mentionPatterns`, Fallback `messages.groupChat.mentionPatterns`)
- Implizites Reply-to-Bot-Verhalten in unterstützten Fällen
`requireMention` wird pro Guild/Kanal konfiguriert (`channels.discord.guilds...`).
`ignoreOtherMentions` verwirft optional Nachrichten, die einen anderen Benutzer/eine andere Rolle erwähnen, aber nicht den Bot (ausgenommen @everyone/@here).
Gruppen-DMs:
- Standard: ignoriert (`dm.groupEnabled=false`)
- Optionale Allowlist über `dm.groupChannels` (Kanal-IDs oder Slugs)
Rollenbasiertes Agent-Routing
Verwende bindings[].match.roles, um Discord-Server-Mitglieder anhand der Rollen-ID an verschiedene Agenten weiterzuleiten. Rollenbasierte Bindings akzeptieren nur Rollen-IDs und werden nach Peer- oder Parent-Peer-Bindings und vor reinen Guild-Bindings ausgewertet. Setzt ein Binding auch andere Match-Felder (z. B. peer + guildId + roles), müssen alle konfigurierten Felder übereinstimmen.
{
bindings: [
{
agentId: "opus",
match: {
channel: "discord",
guildId: "123456789012345678",
roles: ["111111111111111111"],
},
},
{
agentId: "sonnet",
match: {
channel: "discord",
guildId: "123456789012345678",
},
},
],
}
Developer-Portal-Einrichtung
App und Bot erstellen
1. Discord Developer Portal -> **Applications** -> **New Application**
2. **Bot** -> **Add Bot**
3. Bot-Token kopieren
Privilegierte Intents
Unter **Bot -> Privileged Gateway Intents** aktiviere:
- Message Content Intent
- Server Members Intent (empfohlen)
Der Presence Intent ist optional und nur erforderlich, wenn du Presence-Updates empfangen willst. Das Setzen der Bot-Presence (`setPresence`) erfordert nicht, dass Presence-Updates für Mitglieder aktiviert sind.
OAuth-Scopes und Basis-Berechtigungen
OAuth-URL-Generator:
- Scopes: `bot`, `applications.commands`
Typische Basis-Berechtigungen:
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (optional)
Vermeide `Administrator`, sofern nicht explizit nötig.
IDs kopieren
Aktiviere den Discord-Entwicklermodus und kopiere:
- Server-ID
- Kanal-ID
- Benutzer-ID
Bevorzuge numerische IDs in der OpenClaw-Config für zuverlässige Audits und Probes.
Native Befehle und Befehlsautorisierung
commands.nativeist standardmäßig"auto"und für Discord aktiviert.- Kanalspezifische Überschreibung:
channels.discord.commands.native. commands.native=falseentfernt explizit zuvor registrierte Discord-Native-Befehle.- Die Native-Befehlsautorisierung nutzt dieselben Discord-Allowlists/-Richtlinien wie die normale Nachrichtenverarbeitung.
- Befehle können für nicht autorisierte Benutzer weiterhin in der Discord-UI sichtbar sein; die Ausführung erzwingt trotzdem die OpenClaw-Autorisierung und gibt „not authorized” zurück.
Siehe Slash-Befehle für Befehlskatalog und Verhalten.
Standard-Slash-Befehlseinstellungen:
ephemeral: true
Feature-Details
Reply-Tags und native Antworten
Discord unterstützt Reply-Tags in der Agent-Ausgabe:
- `[[reply_to_current]]`
- `[[reply_to:<id>]]`
Gesteuert über `channels.discord.replyToMode`:
- `off` (Standard)
- `first`
- `all`
Hinweis: `off` deaktiviert implizites Reply-Threading. Explizite `[[reply_to_*]]`-Tags werden weiterhin berücksichtigt.
Nachrichten-IDs werden im Kontext/Verlauf angezeigt, damit Agenten bestimmte Nachrichten gezielt ansprechen können.
Live-Stream-Vorschau
OpenClaw kann Antwort-Entwürfe streamen, indem es eine temporäre Nachricht sendet und sie bearbeitet, während Text eintrifft.
- `channels.discord.streaming` steuert die Vorschau-Streams (`off` | `partial` | `block` | `progress`, Standard: `off`).
- `progress` wird der kanalübergreifenden Einheitlichkeit halber akzeptiert und auf Discord auf `partial` abgebildet.
- `channels.discord.streamMode` ist ein Legacy-Alias und wird automatisch migriert.
- `partial` bearbeitet eine einzelne Vorschaunachricht, während Tokens eintreffen.
- `block` gibt Chunks in Entwurfsgröße aus (verwende `draftChunk` zum Anpassen von Größe und Umbruchpunkten).
Beispiel:
{
channels: {
discord: {
streaming: "partial",
},
},
}
Standard-Chunking für den `block`-Modus (begrenzt durch `channels.discord.textChunkLimit`):
{
channels: {
discord: {
streaming: "block",
draftChunk: {
minChars: 200,
maxChars: 800,
breakPreference: "paragraph",
},
},
},
}
Vorschau-Streaming ist nur für Text; Medien-Antworten fallen auf normale Zustellung zurück.
Hinweis: Vorschau-Streaming ist getrennt von Block-Streaming. Wenn Block-Streaming für Discord explizit aktiviert ist, überspringt OpenClaw den Vorschau-Stream, um doppeltes Streaming zu vermeiden.
Verlauf, Kontext und Thread-Verhalten
Guild-Verlaufskontext:
- `channels.discord.historyLimit` Standard `20`
- Fallback: `messages.groupChat.historyLimit`
- `0` deaktiviert
DM-Verlaufssteuerung:
- `channels.discord.dmHistoryLimit`
- `channels.discord.dms["<user_id>"].historyLimit`
Thread-Verhalten:
- Discord-Threads werden als Kanal-Sitzungen geroutet
- Übergeordnete Thread-Metadaten können für Parent-Session-Verknüpfung genutzt werden
- Thread-Konfiguration erbt die Konfiguration des übergeordneten Kanals, sofern kein thread-spezifischer Eintrag existiert
Kanal-Topics werden als **nicht vertrauenswürdiger** Kontext injiziert (nicht als System-Prompt).
Thread-gebundene Sitzungen für Subagenten
Discord kann einen Thread an ein Session-Ziel binden, damit Folgenachrichten in diesem Thread weiterhin an dieselbe Sitzung geroutet werden (einschließlich Subagenten-Sitzungen).
Befehle:
- `/focus <target>` aktuellen/neuen Thread an ein Subagenten-/Session-Ziel binden
- `/unfocus` aktuelle Thread-Bindung entfernen
- `/agents` aktive Runs und Bindungsstatus anzeigen
- `/session idle <duration|off>` Inaktivitäts-Auto-Unfocus für fokussierte Bindungen prüfen/aktualisieren
- `/session max-age <duration|off>` Maximalalter für fokussierte Bindungen prüfen/aktualisieren
Konfiguration:
{
session: {
threadBindings: {
enabled: true,
idleHours: 24,
maxAgeHours: 0,
},
},
channels: {
discord: {
threadBindings: {
enabled: true,
idleHours: 24,
maxAgeHours: 0,
spawnSubagentSessions: false, // opt-in
},
},
},
}
Hinweise:
- `session.threadBindings.*` setzt die globalen Standardwerte.
- `channels.discord.threadBindings.*` überschreibt das Discord-Verhalten.
- `spawnSubagentSessions` muss true sein, um automatisch Threads für `sessions_spawn({ thread: true })` zu erstellen/binden.
- `spawnAcpSessions` muss true sein, um automatisch Threads für ACP zu erstellen/binden (`/acp spawn ... --thread ...` oder `sessions_spawn({ runtime: "acp", thread: true })`).
- Sind Thread-Bindungen für ein Konto deaktiviert, stehen `/focus` und verwandte Operationen nicht zur Verfügung.
Siehe [Sub-Agents](/docs/tools/subagents), [ACP Agents](/docs/tools/acp-agents) und [Konfigurationsreferenz](/docs/gateway/configuration-reference).
Persistente ACP-Kanalbindungen
Für stabile „Always-on"-ACP-Workspaces konfiguriere Top-Level-ACP-Bindings mit Typ, die auf Discord-Konversationen zielen.
Config-Pfad:
- `bindings[]` mit `type: "acp"` und `match.channel: "discord"`
Beispiel:
{
agents: {
list: [
{
id: "codex",
runtime: {
type: "acp",
acp: {
agent: "codex",
backend: "acpx",
mode: "persistent",
cwd: "/workspace/openclaw",
},
},
},
],
},
bindings: [
{
type: "acp",
agentId: "codex",
match: {
channel: "discord",
accountId: "default",
peer: { kind: "channel", id: "222222222222222222" },
},
acp: { label: "codex-main" },
},
],
channels: {
discord: {
guilds: {
"111111111111111111": {
channels: {
"222222222222222222": {
requireMention: false,
},
},
},
},
},
},
}
Hinweise:
- Thread-Nachrichten können die ACP-Bindung des übergeordneten Kanals erben.
- In einem gebundenen Kanal oder Thread setzen `/new` und `/reset` dieselbe ACP-Sitzung zurück.
- Temporäre Thread-Bindungen funktionieren weiterhin und können die Zielauflösung überschreiben, solange sie aktiv sind.
Siehe [ACP Agents](/docs/tools/acp-agents) für Details zum Bindungsverhalten.
Reaktions-Benachrichtigungen
Reaktions-Benachrichtigungsmodus pro Guild:
- `off`
- `own` (Standard)
- `all`
- `allowlist` (nutzt `guilds.<id>.users`)
Reaktions-Events werden in System-Events umgewandelt und an die geroutete Discord-Sitzung angehängt.
Bestätigungsreaktionen
`ackReaction` sendet ein Bestätigungs-Emoji, während OpenClaw eine eingehende Nachricht verarbeitet.
Auflösungsreihenfolge:
- `channels.discord.accounts.<accountId>.ackReaction`
- `channels.discord.ackReaction`
- `messages.ackReaction`
- Agent-Identity-Emoji-Fallback (`agents.list[].identity.emoji`, sonst "👀")
Hinweise:
- Discord akzeptiert Unicode-Emoji oder benutzerdefinierte Emoji-Namen.
- Verwende `""`, um die Reaktion für einen Kanal oder ein Konto zu deaktivieren.
Config-Schreibvorgänge
Kanalinitiierte Config-Schreibvorgänge sind standardmäßig aktiviert.
Das betrifft `/config set|unset`-Abläufe (wenn Befehlsfeatures aktiviert sind).
Deaktivieren:
{
channels: {
discord: {
configWrites: false,
},
},
}
Gateway-Proxy
Leite Discord-Gateway-WebSocket-Traffic und Startup-REST-Abfragen (Application-ID + Allowlist-Auflösung) über einen HTTP(S)-Proxy mit `channels.discord.proxy`.
{
channels: {
discord: {
proxy: "http://proxy.example:8080",
},
},
}
Überschreibung pro Konto:
{
channels: {
discord: {
accounts: {
primary: {
proxy: "http://proxy.example:8080",
},
},
},
},
}
PluralKit-Unterstützung
Aktiviere PluralKit-Auflösung, um geproxyte Nachrichten einer System-Member-Identität zuzuordnen:
{
channels: {
discord: {
pluralkit: {
enabled: true,
token: "pk_live_...", // optional; nötig für private Systeme
},
},
},
}
Hinweise:
- Allowlists können `pk:<memberId>` verwenden
- Member-Anzeigenamen werden nur per Name/Slug abgeglichen, wenn `channels.discord.dangerouslyAllowNameMatching: true`
- Lookups verwenden die Original-Nachrichten-ID und sind zeitfenster-begrenzt
- Schlägt der Lookup fehl, werden geproxyte Nachrichten als Bot-Nachrichten behandelt und verworfen, sofern nicht `allowBots=true`
Presence-Konfiguration
Presence-Updates werden angewendet, wenn du ein Status- oder Activity-Feld setzt oder Auto-Presence aktivierst.
Nur-Status-Beispiel:
{
channels: {
discord: {
status: "idle",
},
},
}
Activity-Beispiel (Custom-Status ist der Standard-Activity-Typ):
{
channels: {
discord: {
activity: "Focus time",
activityType: 4,
},
},
}
Streaming-Beispiel:
{
channels: {
discord: {
activity: "Live coding",
activityType: 1,
activityUrl: "https://twitch.tv/openclaw",
},
},
}
Activity-Typ-Zuordnung:
- 0: Playing
- 1: Streaming (erfordert `activityUrl`)
- 2: Listening
- 3: Watching
- 4: Custom (nutzt den Activity-Text als Statustext; Emoji ist optional)
- 5: Competing
Auto-Presence-Beispiel (Runtime-Health-Signal):
{
channels: {
discord: {
autoPresence: {
enabled: true,
intervalMs: 30000,
minUpdateIntervalMs: 15000,
exhaustedText: "token exhausted",
},
},
},
}
Auto-Presence bildet die Runtime-Verfügbarkeit auf den Discord-Status ab: healthy => online, degraded oder unknown => idle, exhausted oder unavailable => dnd. Optionale Text-Überschreibungen:
- `autoPresence.healthyText`
- `autoPresence.degradedText`
- `autoPresence.exhaustedText` (unterstützt `{reason}`-Platzhalter)
Exec-Genehmigungen in Discord
Discord unterstützt buttonbasierte Exec-Genehmigungen in DMs und kann optional Genehmigungsaufforderungen im Ursprungskanal anzeigen.
Config-Pfad:
- `channels.discord.execApprovals.enabled`
- `channels.discord.execApprovals.approvers`
- `channels.discord.execApprovals.target` (`dm` | `channel` | `both`, Standard: `dm`)
- `agentFilter`, `sessionFilter`, `cleanupAfterResolve`
Ist `target` auf `channel` oder `both` gesetzt, wird die Genehmigungsaufforderung im Kanal sichtbar. Nur konfigurierte Genehmiger können die Buttons nutzen; andere Benutzer erhalten eine ephemerale Ablehnung. Genehmigungsaufforderungen zeigen den Befehlstext, aktiviere Kanal-Zustellung also nur in vertrauenswürdigen Kanälen. Kann die Kanal-ID nicht aus dem Session-Key abgeleitet werden, fällt OpenClaw auf DM-Zustellung zurück.
Die Gateway-Authentifizierung für diesen Handler nutzt denselben Shared-Credential-Auflösungsvertrag wie andere Gateway-Clients:
- Env-First-Local-Auth (`OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD`, dann `gateway.auth.*`)
- Im lokalen Modus kann `gateway.remote.*` als Fallback genutzt werden, aber nur wenn `gateway.auth.*` nicht gesetzt ist; konfigurierte, aber nicht aufgelöste lokale SecretRefs schlagen geschlossen fehl
- Remote-Modus-Unterstützung über `gateway.remote.*` wenn zutreffend
- URL-Überschreibungen sind override-sicher: CLI-Overrides verwenden keine impliziten Credentials, und Env-Overrides nutzen nur Env-Credentials
Schlagen Genehmigungen mit unbekannten Approval-IDs fehl, prüfe die Genehmigerliste und ob das Feature aktiviert ist.
Verwandte Docs: [Exec-Genehmigungen](/docs/tools/exec-approvals)
Tools und Action-Gates
Discord-Nachrichtenaktionen umfassen Messaging, Kanal-Administration, Moderation, Presence und Metadaten-Aktionen.
Zentrale Beispiele:
- Messaging:
sendMessage,readMessages,editMessage,deleteMessage,threadReply - Reaktionen:
react,reactions,emojiList - Moderation:
timeout,kick,ban - Presence:
setPresence
Action-Gates liegen unter channels.discord.actions.*.
Standard-Gate-Verhalten:
| Action-Gruppe | Standard |
|---|---|
| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | aktiviert |
| roles | deaktiviert |
| moderation | deaktiviert |
| presence | deaktiviert |
Components v2 UI
OpenClaw nutzt Discord Components v2 für Exec-Genehmigungen und kanalübergreifende Marker. Discord-Nachrichtenaktionen können auch components für benutzerdefinierte UIs akzeptieren (fortgeschritten; erfordert Carbon-Komponenteninstanzen), während Legacy-embeds verfügbar bleiben, aber nicht empfohlen werden.
channels.discord.ui.components.accentColorsetzt die Akzentfarbe für Discord-Komponentencontainer (Hex).- Pro Konto konfigurierbar mit
channels.discord.accounts.<id>.ui.components.accentColor. embedswerden ignoriert, wenn Components v2 vorhanden sind.
Beispiel:
{
channels: {
discord: {
ui: {
components: {
accentColor: "#5865F2",
},
},
},
},
}
Sprachkanäle
OpenClaw kann Discord-Sprachkanälen beitreten für Echtzeit-Gespräche. Das ist getrennt von Sprachnachricht-Anhängen.
Voraussetzungen:
- Native Befehle aktivieren (
commands.nativeoderchannels.discord.commands.native). channels.discord.voicekonfigurieren.- Der Bot braucht Connect- + Speak-Berechtigungen im Ziel-Sprachkanal.
Verwende den Discord-exklusiven nativen Befehl /vc join|leave|status zur Steuerung. Der Befehl nutzt den Standard-Agenten des Kontos und folgt denselben Allowlist- und Group-Policy-Regeln wie andere Discord-Befehle.
Auto-Join-Beispiel:
{
channels: {
discord: {
voice: {
enabled: true,
autoJoin: [
{
guildId: "123456789012345678",
channelId: "234567890123456789",
},
],
daveEncryption: true,
decryptionFailureTolerance: 24,
tts: {
provider: "openai",
openai: { voice: "alloy" },
},
},
},
},
}
Hinweise:
voice.ttsüberschreibtmessages.ttsnur für die Sprachwiedergabe.- Sprachtranskript-Turns leiten den Owner-Status aus Discord
allowFrom(oderdm.allowFrom) ab; Nicht-Owner-Sprecher haben keinen Zugriff auf Owner-only-Tools (z. B.gatewayundcron). - Voice ist standardmäßig aktiviert; setze
channels.discord.voice.enabled=falsezum Deaktivieren. voice.daveEncryptionundvoice.decryptionFailureTolerancewerden an die@discordjs/voice-Join-Optionen durchgereicht.@discordjs/voice-Standards sinddaveEncryption=trueunddecryptionFailureTolerance=24, wenn nicht gesetzt.- OpenClaw überwacht zudem Empfangs-Entschlüsselungsfehler und stellt sich automatisch wieder her, indem es den Sprachkanal bei wiederholten Fehlern in kurzem Zeitfenster verlässt und neu beitritt.
- Zeigen Empfangsprotokolle wiederholt
DecryptionFailed(UnencryptedWhenPassthroughDisabled), könnte es sich um den bekannten@discordjs/voice-Empfangsfehler handeln, der in discord.js #11419 verfolgt wird.
Sprachnachrichten
Discord-Sprachnachrichten zeigen eine Wellenform-Vorschau und erfordern OGG/Opus-Audio samt Metadaten. OpenClaw generiert die Wellenform automatisch, benötigt aber ffmpeg und ffprobe auf dem Gateway-Host, um Audiodateien zu prüfen und zu konvertieren.
Anforderungen und Einschränkungen:
- Gib einen lokalen Dateipfad an (URLs werden abgelehnt).
- Lass den Textinhalt weg (Discord erlaubt keinen Text + Sprachnachricht im selben Payload).
- Jedes Audioformat wird akzeptiert; OpenClaw konvertiert bei Bedarf zu OGG/Opus.
Beispiel:
message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)
Fehlerbehebung
Disallowed Intents oder Bot sieht keine Server-Nachrichten
- Aktiviere den Message Content Intent
- Aktiviere den Server Members Intent, wenn du auf Benutzer-/Mitgliederauflösung angewiesen bist
- Starte das Gateway nach dem Ändern der Intents neu
Server-Nachrichten werden unerwartet blockiert
- Überprüfe `groupPolicy`
- Überprüfe die Guild-Allowlist unter `channels.discord.guilds`
- Existiert eine `channels`-Map in der Guild, werden nur aufgelistete Kanäle erlaubt
- Überprüfe `requireMention`-Verhalten und Mention-Patterns
Nützliche Prüfungen:
openclaw doctor
openclaw channels status --probe
openclaw logs --follow
requireMention false, aber trotzdem blockiert
Häufige Ursachen:
- `groupPolicy="allowlist"` ohne passende Guild-/Kanal-Allowlist
- `requireMention` an der falschen Stelle konfiguriert (muss unter `channels.discord.guilds` oder Kanaleintrag stehen)
- Absender durch Guild-/Kanal-`users`-Allowlist blockiert
Langlebige Handler laufen in Timeout oder doppelte Antworten
Typische Logs:
- `Listener DiscordMessageListener timed out after 30000ms for event MESSAGE_CREATE`
- `Slow listener detected ...`
- `discord inbound worker timed out after ...`
Listener-Budget-Regler:
- Einzelkonto: `channels.discord.eventQueue.listenerTimeout`
- Multikonto: `channels.discord.accounts.<accountId>.eventQueue.listenerTimeout`
Worker-Run-Timeout-Regler:
- Einzelkonto: `channels.discord.inboundWorker.runTimeoutMs`
- Multikonto: `channels.discord.accounts.<accountId>.inboundWorker.runTimeoutMs`
- Standard: `1800000` (30 Minuten); setze `0` zum Deaktivieren
Empfohlene Basislinie:
{
channels: {
discord: {
accounts: {
default: {
eventQueue: {
listenerTimeout: 120000,
},
inboundWorker: {
runTimeoutMs: 1800000,
},
},
},
},
},
}
Verwende `eventQueue.listenerTimeout` für langsame Listener-Setups und `inboundWorker.runTimeoutMs` nur als zusätzliches Sicherheitsventil für eingereihte Agent-Turns.
Berechtigungsaudit-Abweichungen
`channels status --probe`-Berechtigungsprüfungen funktionieren nur mit numerischen Kanal-IDs.
Bei Slug-Keys kann das Runtime-Matching trotzdem funktionieren, aber Probe kann Berechtigungen nicht vollständig verifizieren.
DM- und Pairing-Probleme
- DM deaktiviert: `channels.discord.dm.enabled=false`
- DM-Richtlinie deaktiviert: `channels.discord.dmPolicy="disabled"` (Legacy: `channels.discord.dm.policy`)
- Wartet auf Pairing-Genehmigung im `pairing`-Modus
Bot-zu-Bot-Schleifen
Standardmäßig werden Bot-Nachrichten ignoriert.
Wenn du `channels.discord.allowBots=true` setzt, verwende strikte Mention- und Allowlist-Regeln, um Schleifen zu vermeiden.
Bevorzuge `channels.discord.allowBots="mentions"`, um nur Bot-Nachrichten zu akzeptieren, die den Bot erwähnen.
Voice-STT schlägt fehl mit DecryptionFailed(...)
- Halte OpenClaw aktuell (`openclaw update`), damit die Discord-Voice-Receive-Recovery-Logik vorhanden ist
- Bestätige `channels.discord.voice.daveEncryption=true` (Standard)
- Starte mit `channels.discord.voice.decryptionFailureTolerance=24` (Upstream-Standard) und passe nur bei Bedarf an
- Beobachte die Logs auf:
- `discord voice: DAVE decrypt failures detected`
- `discord voice: repeated decrypt failures; attempting rejoin`
- Halten die Fehler nach dem automatischen Rejoin an, sammle Logs und vergleiche mit [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419)
Konfigurationsreferenz-Verweise
Primäre Referenz:
Wichtige Discord-Felder:
- Startup/Auth:
enabled,token,accounts.*,allowBots - Richtlinien:
groupPolicy,dm.*,guilds.*,guilds.*.channels.* - Befehle:
commands.native,commands.useAccessGroups,configWrites,slashCommand.* - Event-Queue:
eventQueue.listenerTimeout(Listener-Budget),eventQueue.maxQueueSize,eventQueue.maxConcurrency - Inbound-Worker:
inboundWorker.runTimeoutMs - Antwort/Verlauf:
replyToMode,historyLimit,dmHistoryLimit,dms.*.historyLimit - Zustellung:
textChunkLimit,chunkMode,maxLinesPerMessage - Streaming:
streaming(Legacy-Alias:streamMode),draftChunk,blockStreaming,blockStreamingCoalesce - Medien/Retry:
mediaMaxMb,retrymediaMaxMbbegrenzt ausgehende Discord-Uploads (Standard:8MB)
- Aktionen:
actions.* - Presence:
activity,status,activityType,activityUrl - UI:
ui.components.accentColor - Features:
threadBindings, Top-Levelbindings[](type: "acp"),pluralkit,execApprovals,intents,agentComponents,heartbeat,responsePrefix
Sicherheit und Betrieb
- Behandle Bot-Tokens als Geheimnisse (
DISCORD_BOT_TOKENbevorzugt in überwachten Umgebungen). - Vergib Discord-Berechtigungen nach dem Least-Privilege-Prinzip.
- Bei veraltetem Befehls-Deploy/Zustand starte das Gateway neu und prüfe mit
openclaw channels status --probe.