Discord (Bot API)
Stato: pronto per DM e canali guild tramite il gateway ufficiale Discord.
- Pairing — I DM Discord usano la modalita pairing per impostazione predefinita.
- Comandi slash — Comportamento comandi nativi e catalogo comandi.
- Risoluzione problemi canali — Diagnostica cross-canale e flusso di riparazione.
Setup rapido
Dovrai creare una nuova applicazione con un bot, aggiungere il bot al tuo server e associarlo a OpenClaw. Ti consigliamo di aggiungere il bot al tuo server privato. Se non ne hai ancora uno, creane uno prima (scegli Create My Own > For me and my friends).
Step 1: Crea un’applicazione e un bot Discord
Vai al [Discord Developer Portal](https://discord.com/developers/applications) e clicca **New Application**. Chiamalo qualcosa come "OpenClaw".
Clicca **Bot** nella sidebar. Imposta lo **Username** come preferisci chiamare il tuo agent OpenClaw.
Step 2: Abilita gli intent privilegiati
Sempre nella pagina **Bot**, scorri fino a **Privileged Gateway Intents** e abilita:
- **Message Content Intent** (necessario)
- **Server Members Intent** (consigliato; necessario per allowlist per ruolo e matching nome-a-ID)
- **Presence Intent** (opzionale; necessario solo per aggiornamenti di presenza)
Step 3: Copia il token del bot
Torna in alto nella pagina **Bot** e clicca **Reset Token**.
> **Nota:** Nonostante il nome, questo genera il tuo primo token -- non stai "reimpostando" nulla.
Copia il token e salvalo da qualche parte. Questo e il tuo **Bot Token** e ti servira a breve.
Step 4: Genera un URL di invito e aggiungi il bot al tuo server
Clicca **OAuth2** nella sidebar. Genererai un URL di invito con i permessi corretti per aggiungere il bot al tuo server.
Scorri fino a **OAuth2 URL Generator** e abilita:
- `bot`
- `applications.commands`
Apparira una sezione **Bot Permissions** sotto. Abilita:
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (opzionale)
Copia l'URL generato in basso, incollalo nel browser, seleziona il tuo server e clicca **Continue** per connettere. Dovresti ora vedere il bot nel server Discord.
Step 5: Abilita la Developer Mode e raccogli i tuoi ID
Nell'app Discord, devi abilitare la Developer Mode per poter copiare gli ID interni.
1. Clicca **User Settings** (icona ingranaggio accanto al tuo avatar) → **Advanced** → attiva **Developer Mode**
2. Clicca destro sull'**icona del server** nella sidebar → **Copy Server ID**
3. Clicca destro sul **tuo avatar** → **Copy User ID**
Salva il tuo **Server ID** e **User ID** insieme al Bot Token -- li invierai tutti e tre a OpenClaw nel passo successivo.
Step 6: Consenti i DM dai membri del server
Per far funzionare il pairing, Discord deve consentire al tuo bot di inviarti DM. Clicca destro sull'**icona del server** → **Privacy Settings** → attiva **Direct Messages**.
Questo consente ai membri del server (inclusi i bot) di inviarti DM. Mantienilo abilitato se vuoi usare i DM Discord con OpenClaw. Se intendi usare solo i canali guild, puoi disabilitare i DM dopo il pairing.
Step 7: Imposta il token del bot in modo sicuro (non inviarlo in chat)
Il token del bot Discord e un segreto (come una password). Impostalo sulla macchina che esegue OpenClaw prima di scrivere al tuo agent.
openclaw config set channels.discord.token '"YOUR_BOT_TOKEN"' --json
openclaw config set channels.discord.enabled true --json
openclaw gateway
Se OpenClaw e gia in esecuzione come servizio in background, usa `openclaw gateway restart` invece.
Step 8: Configura OpenClaw e associa
#### Chiedi al tuo agent
Chatta con il tuo agent OpenClaw su qualsiasi canale esistente (es. Telegram) e digli. Se Discord e il tuo primo canale, usa la CLI / scheda config invece.
> "Ho gia impostato il token del mio bot Discord nel config. Per favore completa il setup Discord con User ID `<user_id>` e Server ID `<server_id>`."
#### CLI / config
Se preferisci la configurazione basata su file, imposta:
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN",
},
},
}
Fallback env per l'account predefinito:
DISCORD_BOT_TOKEN=...
I valori SecretRef sono supportati anche per `channels.discord.token` (provider env/file/exec). Vedi [Gestione Secrets](/docs/gateway/secrets).
Step 9: Approva il primo DM pairing
Attendi che il gateway sia in esecuzione, poi scrivi un DM al tuo bot in Discord. Rispondera con un codice di pairing.
#### Chiedi al tuo agent
Invia il codice di pairing al tuo agent sul canale esistente:
> "Approva questo codice di pairing Discord: `<CODE>`"
#### CLI
openclaw pairing list discord
openclaw pairing approve discord <CODE>
I codici di pairing scadono dopo 1 ora.
Dovresti ora poter chattare con il tuo agent in Discord via DM.
Nota: La risoluzione del token e sensibile all’account. I valori token nel config prevalgono sul fallback env.
DISCORD_BOT_TOKENviene usato solo per l’account predefinito. Per chiamate in uscita avanzate (strumento messaggio/azioni canale), untokenesplicito per chiamata viene usato per quella chiamata. Le impostazioni policy/retry dell’account provengono comunque dall’account selezionato nello snapshot runtime attivo.
Consigliato: Configura un workspace guild
Una volta che i DM funzionano, puoi configurare il tuo server Discord come workspace completo dove ogni canale ha la propria sessione agent con il proprio contesto. Questo e consigliato per server privati dove ci sei solo tu e il tuo bot.
Step 1: Aggiungi il tuo server all’allowlist guild
Questo abilita il tuo agent a rispondere in qualsiasi canale del tuo server, non solo nei DM.
#### Chiedi al tuo agent
> "Aggiungi il mio Server ID Discord `<server_id>` all'allowlist guild"
#### Config
{
channels: {
discord: {
groupPolicy: "allowlist",
guilds: {
YOUR_SERVER_ID: {
requireMention: true,
users: ["YOUR_USER_ID"],
},
},
},
},
}
Step 2: Consenti risposte senza @menzione
Per impostazione predefinita, il tuo agent risponde nei canali guild solo quando viene @menzionato. Per un server privato, probabilmente vuoi che risponda a ogni messaggio.
#### Chiedi al tuo agent
> "Consenti al mio agent di rispondere su questo server senza dover essere @menzionato"
#### Config
Imposta `requireMention: false` nella config della tua guild:
{
channels: {
discord: {
guilds: {
YOUR_SERVER_ID: {
requireMention: false,
},
},
},
},
}
Step 3: Pianifica la memoria nei canali guild
Per impostazione predefinita, la memoria a lungo termine (MEMORY.md) si carica solo nelle sessioni DM. I canali guild non caricano automaticamente MEMORY.md.
#### Chiedi al tuo agent
> "Quando faccio domande nei canali Discord, usa memory_search o memory_get se hai bisogno di contesto a lungo termine da MEMORY.md."
#### Manuale
Se hai bisogno di contesto condiviso in ogni canale, metti le istruzioni stabili in `AGENTS.md` o `USER.md` (vengono iniettati per ogni sessione). Mantieni le note a lungo termine in `MEMORY.md` e accedivi su richiesta con gli strumenti memoria.
Ora crea dei canali nel tuo server Discord e inizia a chattare. Il tuo agent puo vedere il nome del canale, e ogni canale ha la propria sessione isolata — cosi puoi configurare #coding, #home, #research, o qualsiasi cosa si adatti al tuo flusso di lavoro.
Modello runtime
- Il gateway possiede la connessione Discord.
- Il routing delle risposte e deterministico: i messaggi in ingresso Discord rispondono a Discord.
- Per impostazione predefinita (
session.dmScope=main), le chat dirette condividono la sessione principale dell’agent (agent:main:main). - I canali guild sono chiavi di sessione isolate (
agent:<agentId>:discord:channel:<channelId>). - I DM di gruppo sono ignorati per impostazione predefinita (
channels.discord.dm.groupEnabled=false). - I comandi slash nativi girano in sessioni comandi isolate (
agent:<agentId>:discord:slash:<userId>), portando comunqueCommandTargetSessionKeyalla sessione di conversazione instradata.
Canali forum
I canali forum e media di Discord accettano solo post in thread. OpenClaw supporta due modi per crearli:
- Invia un messaggio al forum padre (
channel:<forumId>) per creare automaticamente un thread. Il titolo del thread usa la prima riga non vuota del tuo messaggio. - Usa
openclaw message thread createper creare un thread direttamente. Non passare--message-idper i canali forum.
Esempio: invia al forum padre per creare un thread
openclaw message send --channel discord --target channel:<forumId> \
--message "Topic title\nBody of the post"
Esempio: crea un thread del forum esplicitamente
openclaw message thread create --channel discord --target channel:<forumId> \
--thread-name "Topic title" --message "Body of the post"
I forum padre non accettano componenti Discord. Se hai bisogno di componenti, invia al thread stesso (channel:<threadId>).
Componenti interattivi
OpenClaw supporta i container componenti v2 di Discord per i messaggi dell’agent. Usa lo strumento messaggio con un payload components. I risultati delle interazioni vengono instradati all’agent come normali messaggi in ingresso e seguono le impostazioni replyToMode Discord esistenti.
Blocchi supportati:
text,section,separator,actions,media-gallery,file- Le righe di azioni consentono fino a 5 bottoni o un singolo menu select
- Tipi select:
string,user,role,mentionable,channel
Per impostazione predefinita, i componenti sono a uso singolo. Imposta components.reusable=true per consentire a bottoni, select e form di essere usati piu volte finche non scadono.
Per limitare chi puo cliccare un bottone, imposta allowedUsers su quel bottone (ID utente Discord, tag, o *). Quando configurato, gli utenti non corrispondenti ricevono un rifiuto effimero.
I comandi slash /model e /models aprono un picker modello interattivo con dropdown provider e modello piu uno step Submit. La risposta del picker e effimera e solo l’utente che ha invocato puo usarla.
Allegati file:
- I blocchi
filedevono puntare a un riferimento allegato (attachment://<filename>) - Fornisci l’allegato via
media/path/filePath(file singolo); usamedia-galleryper piu file - Usa
filenameper sovrascrivere il nome di upload quando deve corrispondere al riferimento allegato
Form modali:
- Aggiungi
components.modalcon fino a 5 campi - Tipi campo:
text,checkbox,radio,select,role-select,user-select - OpenClaw aggiunge automaticamente un bottone trigger
Esempio:
{
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" },
],
},
],
},
},
}
Controllo degli accessi e routing
Policy DM
`channels.discord.dmPolicy` controlla l'accesso DM (legacy: `channels.discord.dm.policy`):
- `pairing` (predefinito)
- `allowlist`
- `open` (richiede che `channels.discord.allowFrom` includa `"*"`; legacy: `channels.discord.dm.allowFrom`)
- `disabled`
Se la policy DM non e open, gli utenti sconosciuti vengono bloccati (o invitati al pairing in modalita `pairing`).
Precedenza multi-account:
- `channels.discord.accounts.default.allowFrom` si applica solo all'account `default`.
- Gli account nominati ereditano `channels.discord.allowFrom` quando il proprio `allowFrom` non e impostato.
- Gli account nominati non ereditano `channels.discord.accounts.default.allowFrom`.
Formato target DM per la consegna:
- `user:<id>`
- `<@id>` menzione
Gli ID numerici nudi sono ambigui e vengono rifiutati a meno che non venga fornito un tipo target utente/canale esplicito.
Policy guild
La gestione guild e controllata da `channels.discord.groupPolicy`:
- `open`
- `allowlist`
- `disabled`
La baseline sicura quando `channels.discord` esiste e `allowlist`.
Comportamento `allowlist`:
- la guild deve corrispondere a `channels.discord.guilds` (`id` preferito, slug accettato)
- allowlist mittenti opzionali: `users` (ID stabili consigliati) e `roles` (solo ID ruolo); se uno dei due e configurato, i mittenti sono consentiti quando corrispondono a `users` O `roles`
- il matching diretto per nome/tag e disabilitato per impostazione predefinita; abilita `channels.discord.dangerouslyAllowNameMatching: true` solo come modalita break-glass di compatibilita
- nomi/tag sono supportati per `users`, ma gli ID sono piu sicuri; `openclaw security audit` avvisa quando vengono usate voci nome/tag
- se una guild ha `channels` configurato, i canali non elencati vengono negati
- se una guild non ha un blocco `channels`, tutti i canali in quella guild allowlistata sono consentiti
Esempio:
{
channels: {
discord: {
groupPolicy: "allowlist",
guilds: {
"123456789012345678": {
requireMention: true,
ignoreOtherMentions: true,
users: ["987654321098765432"],
roles: ["123456789012345678"],
channels: {
general: { allow: true },
help: { allow: true, requireMention: true },
},
},
},
},
},
}
Se imposti solo `DISCORD_BOT_TOKEN` e non crei un blocco `channels.discord`, il fallback runtime e `groupPolicy="allowlist"` (con un avviso nei log), anche se `channels.defaults.groupPolicy` e `open`.
Menzioni e DM di gruppo
I messaggi guild sono filtrati per menzione per impostazione predefinita.
Il rilevamento menzione include:
- menzione esplicita del bot
- pattern di menzione configurati (`agents.list[].groupChat.mentionPatterns`, fallback `messages.groupChat.mentionPatterns`)
- comportamento implicito di risposta al bot nei casi supportati
`requireMention` e configurato per guild/canale (`channels.discord.guilds...`).
`ignoreOtherMentions` scarta opzionalmente i messaggi che menzionano un altro utente/ruolo ma non il bot (escludendo @everyone/@here).
DM di gruppo:
- predefinito: ignorati (`dm.groupEnabled=false`)
- allowlist opzionale via `dm.groupChannels` (ID canale o slug)
Routing agent basato su ruoli
Usa bindings[].match.roles per instradare i membri guild Discord a agent diversi per ID ruolo. I binding basati su ruoli accettano solo ID ruolo e vengono valutati dopo i binding peer o parent-peer e prima dei binding solo-guild. Se un binding imposta anche altri campi match (ad esempio peer + guildId + roles), tutti i campi configurati devono corrispondere.
{
bindings: [
{
agentId: "opus",
match: {
channel: "discord",
guildId: "123456789012345678",
roles: ["111111111111111111"],
},
},
{
agentId: "sonnet",
match: {
channel: "discord",
guildId: "123456789012345678",
},
},
],
}
Setup Developer Portal
Crea app e bot
1. Discord Developer Portal -> **Applications** -> **New Application**
2. **Bot** -> **Add Bot**
3. Copia il token del bot
Intent privilegiati
In **Bot -> Privileged Gateway Intents**, abilita:
- Message Content Intent
- Server Members Intent (consigliato)
L'intent Presence e opzionale e necessario solo se vuoi ricevere aggiornamenti di presenza. Impostare la presenza del bot (`setPresence`) non richiede l'abilitazione degli aggiornamenti di presenza per i membri.
Scope OAuth e permessi baseline
Generatore URL OAuth:
- scope: `bot`, `applications.commands`
Permessi baseline tipici:
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (opzionale)
Evita `Administrator` a meno che non sia esplicitamente necessario.
Copia gli ID
Abilita la Discord Developer Mode, poi copia:
- server ID
- channel ID
- user ID
Preferisci ID numerici nella config OpenClaw per audit e probe affidabili.
Comandi nativi e auth comandi
commands.nativee predefinito a"auto"ed e abilitato per Discord.- Override per canale:
channels.discord.commands.native. commands.native=falsecancella esplicitamente i comandi nativi Discord registrati in precedenza.- L’auth dei comandi nativi usa le stesse allowlist/policy Discord della gestione messaggi normale.
- I comandi possono comunque essere visibili nell’UI Discord per utenti non autorizzati; l’esecuzione applica comunque l’auth OpenClaw e restituisce “not authorized”.
Vedi Comandi slash per catalogo comandi e comportamento.
Impostazioni predefinite comandi slash:
ephemeral: true
Dettagli funzionalita
Tag di risposta e risposte native
Discord supporta tag di risposta nel testo dell'agent:
- `[[reply_to_current]]`
- `[[reply_to:<id>]]`
Controllato da `channels.discord.replyToMode`:
- `off` (predefinito)
- `first`
- `all`
Nota: `off` disabilita il threading implicito delle risposte. I tag espliciti `[[reply_to_*]]` vengono comunque rispettati.
Gli ID messaggio sono mostrati nel contesto/storico cosi gli agent possono mirare messaggi specifici.
Anteprima live streaming
OpenClaw puo fare lo streaming di risposte bozza inviando un messaggio temporaneo e modificandolo man mano che il testo arriva.
- `channels.discord.streaming` controlla lo streaming anteprima (`off` | `partial` | `block` | `progress`, predefinito: `off`).
- `progress` e accettato per coerenza cross-canale e mappa a `partial` su Discord.
- `channels.discord.streamMode` e un alias legacy e viene auto-migrato.
- `partial` modifica un singolo messaggio anteprima man mano che i token arrivano.
- `block` emette segmenti dimensionati come bozza (usa `draftChunk` per regolare dimensione e punti di interruzione).
Esempio:
{
channels: {
discord: {
streaming: "partial",
},
},
}
Predefiniti chunking modalita `block` (limitati a `channels.discord.textChunkLimit`):
{
channels: {
discord: {
streaming: "block",
draftChunk: {
minChars: 200,
maxChars: 800,
breakPreference: "paragraph",
},
},
},
}
Lo streaming anteprima e solo testo; le risposte media tornano alla consegna normale.
Nota: lo streaming anteprima e separato dallo streaming a blocchi. Quando lo streaming a blocchi e esplicitamente
abilitato per Discord, OpenClaw salta lo streaming anteprima per evitare il doppio streaming.
Storico, contesto e comportamento thread
Contesto storico guild:
- `channels.discord.historyLimit` predefinito `20`
- fallback: `messages.groupChat.historyLimit`
- `0` disabilita
Controlli storico DM:
- `channels.discord.dmHistoryLimit`
- `channels.discord.dms["<user_id>"].historyLimit`
Comportamento thread:
- I thread Discord vengono instradati come sessioni canale
- I metadati thread padre possono essere usati per il collegamento sessione padre
- La config thread eredita la config canale padre a meno che non esista una voce thread-specifica
I topic dei canali vengono iniettati come contesto **non fidato** (non come prompt di sistema).
Sessioni thread-bound per subagent
Discord puo vincolare un thread a un target di sessione cosi i messaggi successivi in quel thread continuano a instradare alla stessa sessione (incluse sessioni subagent).
Comandi:
- `/focus <target>` vincola il thread corrente/nuovo a un target subagent/sessione
- `/unfocus` rimuove il vincolo del thread corrente
- `/agents` mostra le esecuzioni attive e lo stato del vincolo
- `/session idle <duration|off>` ispeziona/aggiorna l'auto-unfocus per inattivita dei vincoli focus
- `/session max-age <duration|off>` ispeziona/aggiorna l'eta massima rigida dei vincoli focus
Config:
{
session: {
threadBindings: {
enabled: true,
idleHours: 24,
maxAgeHours: 0,
},
},
channels: {
discord: {
threadBindings: {
enabled: true,
idleHours: 24,
maxAgeHours: 0,
spawnSubagentSessions: false, // opt-in
},
},
},
}
Note:
- `session.threadBindings.*` imposta i default globali.
- `channels.discord.threadBindings.*` sovrascrive il comportamento Discord.
- `spawnSubagentSessions` deve essere true per creare/vincolare automaticamente thread per `sessions_spawn({ thread: true })`.
- `spawnAcpSessions` deve essere true per creare/vincolare automaticamente thread per ACP (`/acp spawn ... --thread ...` o `sessions_spawn({ runtime: "acp", thread: true })`).
- Se i vincoli thread sono disabilitati per un account, `/focus` e le operazioni di vincolo thread correlate non sono disponibili.
Vedi [Sub-agent](/docs/tools/subagents), [ACP Agents](/docs/tools/acp-agents) e [Riferimento configurazione](/docs/gateway/configuration-reference).
Binding ACP canale persistenti
Per workspace ACP stabili "always-on", configura binding ACP tipizzati top-level che puntano alle conversazioni Discord.
Percorso config:
- `bindings[]` con `type: "acp"` e `match.channel: "discord"`
Esempio:
{
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,
},
},
},
},
},
},
}
Note:
- I messaggi thread possono ereditare il binding ACP del canale padre.
- In un canale o thread vincolato, `/new` e `/reset` reimpostano la stessa sessione ACP sul posto.
- I vincoli thread temporanei funzionano ancora e possono sovrascrivere la risoluzione target mentre attivi.
Vedi [ACP Agents](/docs/tools/acp-agents) per i dettagli sul comportamento dei binding.
Notifiche reazione
Modalita notifica reazione per guild:
- `off`
- `own` (predefinito)
- `all`
- `allowlist` (usa `guilds.<id>.users`)
Gli eventi reazione vengono trasformati in eventi di sistema e allegati alla sessione Discord instradata.
Reazioni di conferma
`ackReaction` invia un emoji di conferma mentre OpenClaw sta elaborando un messaggio in ingresso.
Ordine di risoluzione:
- `channels.discord.accounts.<accountId>.ackReaction`
- `channels.discord.ackReaction`
- `messages.ackReaction`
- fallback emoji identita agent (`agents.list[].identity.emoji`, altrimenti "👀")
Note:
- Discord accetta emoji unicode o nomi emoji personalizzati.
- Usa `""` per disabilitare la reazione per un canale o account.
Scritture configurazione
Le scritture config iniziate dal canale sono abilitate per impostazione predefinita.
Questo riguarda i flussi `/config set|unset` (quando le funzionalita comandi sono abilitate).
Disabilita:
{
channels: {
discord: {
configWrites: false,
},
},
}
Proxy gateway
Instrada il traffico WebSocket del gateway Discord e i lookup REST di avvio (ID applicazione + risoluzione allowlist) attraverso un proxy HTTP(S) con `channels.discord.proxy`.
{
channels: {
discord: {
proxy: "http://proxy.example:8080",
},
},
}
Override per account:
{
channels: {
discord: {
accounts: {
primary: {
proxy: "http://proxy.example:8080",
},
},
},
},
}
Supporto PluralKit
Abilita la risoluzione PluralKit per mappare i messaggi proxied all'identita membro del sistema:
{
channels: {
discord: {
pluralkit: {
enabled: true,
token: "pk_live_...", // opzionale; necessario per sistemi privati
},
},
},
}
Note:
- le allowlist possono usare `pk:<memberId>`
- i nomi visualizzati dei membri sono matchati per nome/slug solo quando `channels.discord.dangerouslyAllowNameMatching: true`
- i lookup usano l'ID messaggio originale e sono vincolati a una finestra temporale
- se il lookup fallisce, i messaggi proxied vengono trattati come messaggi bot e scartati a meno che `allowBots=true`
Configurazione presenza
Gli aggiornamenti di presenza vengono applicati quando imposti un campo stato o attivita, o quando abiliti la presenza automatica.
Esempio solo stato:
{
channels: {
discord: {
status: "idle",
},
},
}
Esempio attivita (lo stato personalizzato e il tipo di attivita predefinito):
{
channels: {
discord: {
activity: "Focus time",
activityType: 4,
},
},
}
Esempio streaming:
{
channels: {
discord: {
activity: "Live coding",
activityType: 1,
activityUrl: "https://twitch.tv/openclaw",
},
},
}
Mappa tipi attivita:
- 0: Playing
- 1: Streaming (richiede `activityUrl`)
- 2: Listening
- 3: Watching
- 4: Custom (usa il testo attivita come stato; l'emoji e opzionale)
- 5: Competing
Esempio presenza automatica (segnale di salute runtime):
{
channels: {
discord: {
autoPresence: {
enabled: true,
intervalMs: 30000,
minUpdateIntervalMs: 15000,
exhaustedText: "token exhausted",
},
},
},
}
La presenza automatica mappa la disponibilita runtime allo stato Discord: healthy => online, degraded o unknown => idle, exhausted o unavailable => dnd. Override testo opzionali:
- `autoPresence.healthyText`
- `autoPresence.degradedText`
- `autoPresence.exhaustedText` (supporta placeholder `{reason}`)
Approvazioni exec in Discord
Discord supporta le approvazioni exec basate su bottoni nei DM e puo opzionalmente pubblicare i prompt di approvazione nel canale originario.
Percorso config:
- `channels.discord.execApprovals.enabled`
- `channels.discord.execApprovals.approvers`
- `channels.discord.execApprovals.target` (`dm` | `channel` | `both`, predefinito: `dm`)
- `agentFilter`, `sessionFilter`, `cleanupAfterResolve`
Quando `target` e `channel` o `both`, il prompt di approvazione e visibile nel canale. Solo gli approvatori configurati possono usare i bottoni; gli altri utenti ricevono un rifiuto effimero. I prompt di approvazione includono il testo del comando, quindi abilita la consegna nel canale solo in canali fidati. Se l'ID canale non puo essere derivato dalla chiave di sessione, OpenClaw torna alla consegna DM.
L'auth gateway per questo handler usa lo stesso contratto di risoluzione credenziali condiviso degli altri client Gateway:
- auth locale env-first (`OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD` poi `gateway.auth.*`)
- in modalita locale, `gateway.remote.*` puo essere usato come fallback solo quando `gateway.auth.*` non e impostato; i SecretRef locali configurati ma non risolti falliscono chiusi
- supporto modalita remota via `gateway.remote.*` quando applicabile
- gli override URL sono override-safe: gli override CLI non riusano credenziali implicite, e gli override env usano solo credenziali env
Se le approvazioni falliscono con ID approvazione sconosciuti, verifica la lista approvatori e l'abilitazione della funzionalita.
Documentazione correlata: [Approvazioni exec](/docs/tools/exec-approvals)
Strumenti e gate azioni
Le azioni messaggio Discord includono messaggistica, amministrazione canale, moderazione, presenza e azioni metadati.
Esempi principali:
- messaggistica:
sendMessage,readMessages,editMessage,deleteMessage,threadReply - reazioni:
react,reactions,emojiList - moderazione:
timeout,kick,ban - presenza:
setPresence
I gate azioni vivono sotto channels.discord.actions.*.
Comportamento predefinito dei gate:
| Gruppo azione | Predefinito |
|---|---|
| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | abilitato |
| roles | disabilitato |
| moderation | disabilitato |
| presence | disabilitato |
UI componenti v2
OpenClaw usa i componenti v2 di Discord per le approvazioni exec e i marcatori cross-contesto. Le azioni messaggio Discord possono anche accettare components per UI personalizzata (avanzato; richiede istanze componenti Carbon), mentre i legacy embeds rimangono disponibili ma non sono consigliati.
channels.discord.ui.components.accentColorimposta il colore accent usato dai container componenti Discord (hex).- Imposta per account con
channels.discord.accounts.<id>.ui.components.accentColor. embedssono ignorati quando i componenti v2 sono presenti.
Esempio:
{
channels: {
discord: {
ui: {
components: {
accentColor: "#5865F2",
},
},
},
},
}
Canali vocali
OpenClaw puo unirsi ai canali vocali Discord per conversazioni in tempo reale e continue. Questo e separato dagli allegati messaggi vocali.
Requisiti:
- Abilita i comandi nativi (
commands.nativeochannels.discord.commands.native). - Configura
channels.discord.voice. - Il bot necessita dei permessi Connect + Speak nel canale vocale target.
Usa il comando nativo solo Discord /vc join|leave|status per controllare le sessioni. Il comando usa l’agent predefinito dell’account e segue le stesse regole allowlist e policy di gruppo degli altri comandi Discord.
Esempio auto-join:
{
channels: {
discord: {
voice: {
enabled: true,
autoJoin: [
{
guildId: "123456789012345678",
channelId: "234567890123456789",
},
],
daveEncryption: true,
decryptionFailureTolerance: 24,
tts: {
provider: "openai",
openai: { voice: "alloy" },
},
},
},
},
}
Note:
voice.ttssovrascrivemessages.ttssolo per la riproduzione vocale.- I turni di trascrizione vocale derivano lo stato proprietario da
allowFromDiscord (odm.allowFrom); i parlanti non-proprietario non possono accedere agli strumenti solo-proprietario (ad esempiogatewayecron). - La voce e abilitata per impostazione predefinita; imposta
channels.discord.voice.enabled=falseper disabilitarla. voice.daveEncryptionevoice.decryptionFailureTolerancepassano attraverso alle opzioni di join di@discordjs/voice.- I predefiniti di
@discordjs/voicesonodaveEncryption=trueedecryptionFailureTolerance=24se non impostati. - OpenClaw monitora anche i fallimenti di decrittazione in ricezione e si auto-recupera uscendo/rientrando nel canale vocale dopo fallimenti ripetuti in una finestra temporale breve.
- Se i log di ricezione mostrano ripetutamente
DecryptionFailed(UnencryptedWhenPassthroughDisabled), potrebbe trattarsi del bug di ricezione@discordjs/voiceupstream tracciato in discord.js #11419.
Messaggi vocali
I messaggi vocali Discord mostrano un’anteprima della forma d’onda e richiedono audio OGG/Opus piu metadati. OpenClaw genera la forma d’onda automaticamente, ma ha bisogno di ffmpeg e ffprobe disponibili sull’host del gateway per ispezionare e convertire i file audio.
Requisiti e vincoli:
- Fornisci un percorso file locale (gli URL vengono rifiutati).
- Ometti il contenuto testo (Discord non consente testo + messaggio vocale nello stesso payload).
- Qualsiasi formato audio e accettato; OpenClaw converte in OGG/Opus quando necessario.
Esempio:
message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)
Risoluzione problemi
Intent non consentiti usati o il bot non vede messaggi guild
- abilita Message Content Intent
- abilita Server Members Intent quando dipendi dalla risoluzione utente/membro
- riavvia il gateway dopo aver cambiato gli intent
Messaggi guild bloccati inaspettatamente
- verifica `groupPolicy`
- verifica l'allowlist guild sotto `channels.discord.guilds`
- se la mappa `channels` della guild esiste, solo i canali elencati sono consentiti
- verifica il comportamento `requireMention` e i pattern di menzione
Controlli utili:
openclaw doctor
openclaw channels status --probe
openclaw logs --follow
Require mention false ma comunque bloccato
Cause comuni:
- `groupPolicy="allowlist"` senza allowlist guild/canale corrispondente
- `requireMention` configurato nel posto sbagliato (deve essere sotto `channels.discord.guilds` o voce canale)
- mittente bloccato dall'allowlist `users` guild/canale
Handler a lunga esecuzione vanno in timeout o risposte duplicate
Log tipici:
- `Listener DiscordMessageListener timed out after 30000ms for event MESSAGE_CREATE`
- `Slow listener detected ...`
- `discord inbound worker timed out after ...`
Parametro budget listener:
- singolo account: `channels.discord.eventQueue.listenerTimeout`
- multi-account: `channels.discord.accounts.<accountId>.eventQueue.listenerTimeout`
Parametro timeout esecuzione worker:
- singolo account: `channels.discord.inboundWorker.runTimeoutMs`
- multi-account: `channels.discord.accounts.<accountId>.inboundWorker.runTimeoutMs`
- predefinito: `1800000` (30 minuti); imposta `0` per disabilitare
Baseline consigliata:
{
channels: {
discord: {
accounts: {
default: {
eventQueue: {
listenerTimeout: 120000,
},
inboundWorker: {
runTimeoutMs: 1800000,
},
},
},
},
},
}
Usa `eventQueue.listenerTimeout` per setup listener lento e `inboundWorker.runTimeoutMs`
solo se vuoi una valvola di sicurezza separata per i turni agent accodati.
Mismatch audit permessi
I controlli permessi di `channels status --probe` funzionano solo per ID canale numerici.
Se usi chiavi slug, il matching runtime puo comunque funzionare, ma il probe non puo verificare completamente i permessi.
Problemi DM e pairing
- DM disabilitati: `channels.discord.dm.enabled=false`
- Policy DM disabilitata: `channels.discord.dmPolicy="disabled"` (legacy: `channels.discord.dm.policy`)
- in attesa di approvazione pairing in modalita `pairing`
Loop bot-a-bot
Per impostazione predefinita i messaggi scritti da bot vengono ignorati.
Se imposti `channels.discord.allowBots=true`, usa regole di menzione e allowlist rigorose per evitare comportamenti di loop.
Preferisci `channels.discord.allowBots="mentions"` per accettare solo messaggi bot che menzionano il bot.
STT vocale interrotto con DecryptionFailed(...)
- mantieni OpenClaw aggiornato (`openclaw update`) cosi la logica di recupero ricezione vocale Discord e presente
- conferma `channels.discord.voice.daveEncryption=true` (predefinito)
- parti da `channels.discord.voice.decryptionFailureTolerance=24` (predefinito upstream) e regola solo se necessario
- monitora i log per:
- `discord voice: DAVE decrypt failures detected`
- `discord voice: repeated decrypt failures; attempting rejoin`
- se i fallimenti continuano dopo il rejoin automatico, raccogli i log e confronta con [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419)
Riferimenti configurazione
Riferimento primario:
Campi Discord ad alto segnale:
- avvio/auth:
enabled,token,accounts.*,allowBots - policy:
groupPolicy,dm.*,guilds.*,guilds.*.channels.* - comandi:
commands.native,commands.useAccessGroups,configWrites,slashCommand.* - coda eventi:
eventQueue.listenerTimeout(budget listener),eventQueue.maxQueueSize,eventQueue.maxConcurrency - worker in ingresso:
inboundWorker.runTimeoutMs - risposte/storico:
replyToMode,historyLimit,dmHistoryLimit,dms.*.historyLimit - consegna:
textChunkLimit,chunkMode,maxLinesPerMessage - streaming:
streaming(alias legacy:streamMode),draftChunk,blockStreaming,blockStreamingCoalesce - media/retry:
mediaMaxMb,retrymediaMaxMblimita gli upload Discord in uscita (predefinito:8MB)
- azioni:
actions.* - presenza:
activity,status,activityType,activityUrl - UI:
ui.components.accentColor - funzionalita:
threadBindings,bindings[]top-level (type: "acp"),pluralkit,execApprovals,intents,agentComponents,heartbeat,responsePrefix
Sicurezza e operazioni
- Tratta i token bot come segreti (
DISCORD_BOT_TOKENpreferito in ambienti supervisionati). - Concedi permessi Discord con privilegio minimo.
- Se il deploy/stato dei comandi e stale, riavvia il gateway e ricontrolla con
openclaw channels status --probe.