Discord (API Bot)
Stato: pronto per DM e canali guild tramite il gateway ufficiale di Discord.Abbinamento
Comandi slash
Risoluzione dei problemi del canale
Configurazione rapida
Dovrai creare una nuova applicazione con un bot, aggiungere il bot al tuo server e abbinarlo a OpenClaw. Ti consigliamo di aggiungere il tuo bot al tuo server privato. Se non ne hai ancora uno, creane prima uno (scegli Create My Own > For me and my friends).Crea un'applicazione Discord e un bot
Abilita gli intent privilegiati
- Message Content Intent (obbligatorio)
- Server Members Intent (consigliato; obbligatorio per allowlist basate sui ruoli e per l’associazione da nome a ID)
- Presence Intent (facoltativo; necessario solo per gli aggiornamenti di presenza)
Copia il token del tuo bot
Genera un URL di invito e aggiungi il bot al tuo server
botapplications.commands
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (facoltativo)
Abilita Developer Mode e raccogli i tuoi ID
- Fai clic su User Settings (icona dell’ingranaggio accanto al tuo avatar) → Advanced → attiva Developer Mode
- Fai clic destro sull’icona del server nella barra laterale → Copy Server ID
- Fai clic destro sul tuo avatar → Copy User ID
Consenti i DM dai membri del server
Imposta in modo sicuro il token del tuo bot (non inviarlo in chat)
openclaw gateway run.Configura OpenClaw ed esegui l'abbinamento
- Chiedi al tuo agente
- CLI / config
“Ho già impostato il token del mio bot Discord nella configurazione. Completa la configurazione di Discord con User ID<user_id>e Server ID<server_id>.”
Approva il primo abbinamento DM
- Chiedi al tuo agente
- CLI
“Approva questo codice di abbinamento Discord: <CODE>”
DISCORD_BOT_TOKEN viene usato solo per l’account predefinito.
Per chiamate avanzate in uscita (strumento messaggi/azioni del canale), viene usato un token esplicito per quella chiamata. Questo si applica alle azioni di invio e di lettura/probe (ad esempio read/search/fetch/thread/pins/permissions). I criteri dell’account e le impostazioni di retry continuano invece a provenire dall’account selezionato nello snapshot di runtime attivo.Consigliato: configura un workspace guild
Una volta che i DM funzionano, puoi configurare il tuo server Discord come workspace completo in cui ogni canale ha la propria sessione agente con il proprio contesto. Questo è consigliato per server privati in cui ci siete solo tu e il tuo bot.Aggiungi il tuo server all'allowlist delle guild
- Chiedi al tuo agente
- Config
“Aggiungi il mio Discord Server ID <server_id> all’allowlist delle guild”
Consenti risposte senza @mention
- Chiedi al tuo agente
- Config
“Consenti al mio agente di rispondere su questo server senza dover essere @menzionato”
Pianifica la memoria nei canali guild
MEMORY.md) viene caricata solo nelle sessioni DM. I canali guild non caricano automaticamente MEMORY.md.- Chiedi al tuo agente
- Manuale
“Quando faccio domande nei canali Discord, usa memory_search o memory_get se ti serve contesto a lungo termine da MEMORY.md.”
#coding, #home, #research o qualunque cosa si adatti al tuo flusso di lavoro.
Modello di runtime
- Il gateway gestisce la connessione Discord.
- L’instradamento delle risposte è deterministico: le risposte in ingresso da Discord tornano su Discord.
- Per impostazione predefinita (
session.dmScope=main), le chat dirette condividono la sessione principale dell’agente (agent:main:main). - I canali guild hanno chiavi di sessione isolate (
agent:<agentId>:discord:channel:<channelId>). - I DM di gruppo vengono ignorati per impostazione predefinita (
channels.discord.dm.groupEnabled=false). - I comandi slash nativi vengono eseguiti in sessioni comando isolate (
agent:<agentId>:discord:slash:<userId>), continuando però a trasportareCommandTargetSessionKeyverso la sessione di conversazione instradata.
Canali forum
I canali forum e media di Discord accettano solo post nei 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 direttamente un thread. Non passare--message-idper i canali forum.
channel:<threadId>).
Componenti interattivi
OpenClaw supporta i contenitori Discord components v2 per i messaggi dell’agente. Usa lo strumento messaggi con un payloadcomponents. I risultati delle interazioni vengono reinstradati all’agente come normali messaggi in ingresso e seguono le impostazioni Discord replyToMode esistenti.
Blocchi supportati:
text,section,separator,actions,media-gallery,file- Le righe di azione consentono fino a 5 pulsanti o un singolo menu di selezione
- Tipi di selezione:
string,user,role,mentionable,channel
components.reusable=true per consentire l’uso multiplo di pulsanti, selezioni e moduli finché non scadono.
Per limitare chi può fare clic su un pulsante, imposta allowedUsers su quel pulsante (ID utente Discord, tag o *). Quando configurato, gli utenti non corrispondenti ricevono un rifiuto effimero.
I comandi slash /model e /models aprono un selettore modello interattivo con menu a discesa di provider e modello più un passaggio Submit. La risposta del selettore è effimera e può essere usata solo dall’utente che l’ha invocata.
Allegati di file:
- i blocchi
filedevono puntare a un riferimento allegato (attachment://<filename>) - fornisci l’allegato tramite
media/path/filePath(file singolo); usamedia-galleryper più file - usa
filenameper sovrascrivere il nome di upload quando deve corrispondere al riferimento allegato
- aggiungi
components.modalcon fino a 5 campi - Tipi di campo:
text,checkbox,radio,select,role-select,user-select - OpenClaw aggiunge automaticamente un pulsante di attivazione
Controllo degli accessi e instradamento
- Criterio DM
- Criterio guild
- Menzioni e DM di gruppo
channels.discord.dmPolicy controlla l’accesso DM (legacy: channels.discord.dm.policy):pairing(predefinito)allowlistopen(richiede chechannels.discord.allowFromincluda"*"; legacy:channels.discord.dm.allowFrom)disabled
pairing).Precedenza multi-account:channels.discord.accounts.default.allowFromsi applica solo all’accountdefault.- Gli account con nome ereditano
channels.discord.allowFromquando il proprioallowFromnon è impostato. - Gli account con nome non ereditano
channels.discord.accounts.default.allowFrom.
user:<id>- menzione
<@id>
Instradamento agente basato sui ruoli
Usabindings[].match.roles per instradare i membri delle guild Discord ad agenti diversi in base all’ID del ruolo. I binding basati sui 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.
Configurazione del Developer Portal
Crea app e bot
Crea app e bot
- Discord Developer Portal -> Applications -> New Application
- Bot -> Add Bot
- Copia il token del bot
Intent privilegiati
Intent privilegiati
- Message Content Intent
- Server Members Intent (consigliato)
setPresence) non richiede l’abilitazione degli aggiornamenti di presenza per i membri.Scope OAuth e permessi di base
Scope OAuth e permessi di base
- scope:
bot,applications.commands
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (facoltativo)
Administrator salvo necessità esplicita.Copia gli ID
Copia gli ID
- ID server
- ID canale
- ID utente
Comandi nativi e autorizzazione dei comandi
commands.nativeha come valore predefinito"auto"ed è abilitato per Discord.- Override per canale:
channels.discord.commands.native. commands.native=falserimuove esplicitamente i comandi nativi Discord registrati in precedenza.- L’autorizzazione dei comandi nativi usa le stesse allowlist/criteri Discord della normale gestione dei messaggi.
- I comandi possono comunque essere visibili nell’interfaccia Discord agli utenti non autorizzati; l’esecuzione continua comunque ad applicare l’autorizzazione OpenClaw e restituisce “non autorizzato”.
ephemeral: true
Dettagli delle funzionalità
Tag di risposta e risposte native
Tag di risposta e risposte native
[[reply_to_current]][[reply_to:<id>]]
channels.discord.replyToMode:off(predefinito)firstallbatched
off disabilita il threading implicito delle risposte. I tag espliciti [[reply_to_*]] vengono comunque rispettati.
first allega sempre il riferimento implicito di risposta nativa al primo messaggio Discord in uscita del turno.
batched allega il riferimento implicito di risposta nativa di Discord solo quando il
turno in ingresso era un batch con debounce di più messaggi. Questo è utile
quando vuoi le risposte native soprattutto per chat ambigue e concitate, non per ogni
singolo turno a messaggio singolo.Gli ID messaggio vengono esposti nel contesto/cronologia così che gli agenti possano puntare a messaggi specifici.Anteprima dello streaming live
Anteprima dello streaming live
channels.discord.streamingcontrolla lo streaming di anteprima (off|partial|block|progress, predefinito:off).- Il valore predefinito resta
offperché le modifiche dell’anteprima su Discord possono raggiungere rapidamente i limiti di velocità, soprattutto quando più bot o gateway condividono lo stesso account o traffico guild. progressè accettato per coerenza tra canali e su Discord viene mappato apartial.channels.discord.streamModeè un alias legacy e viene migrato automaticamente.partialmodifica un singolo messaggio di anteprima man mano che arrivano i token.blockemette blocchi della dimensione della bozza (usadraftChunkper regolare dimensione e punti di interruzione).
block (limitate a channels.discord.textChunkLimit):Cronologia, contesto e comportamento dei thread
Cronologia, contesto e comportamento dei thread
channels.discord.historyLimitpredefinito20- fallback:
messages.groupChat.historyLimit 0disabilita
channels.discord.dmHistoryLimitchannels.discord.dms["<user_id>"].historyLimit
- i thread Discord vengono instradati come sessioni canale
- i metadati del thread padre possono essere usati per il collegamento alla sessione padre
- la configurazione del thread eredita quella del canale padre, a meno che non esista una voce specifica per il thread
Sessioni associate ai thread per subagent
Sessioni associate ai thread per subagent
/focus <target>associa il thread corrente/nuovo a un target subagent/sessione/unfocusrimuove l’associazione del thread corrente/agentsmostra le esecuzioni attive e lo stato delle associazioni/session idle <duration|off>ispeziona/aggiorna il disaccoppiamento automatico per inattività delle associazioni focalizzate/session max-age <duration|off>ispeziona/aggiorna l’età massima rigida per le associazioni focalizzate
session.threadBindings.*imposta i valori predefiniti globali.channels.discord.threadBindings.*sovrascrive il comportamento di Discord.spawnSubagentSessionsdeve essere true per creare/associare automaticamente thread persessions_spawn({ thread: true }).spawnAcpSessionsdeve essere true per creare/associare automaticamente thread per ACP (/acp spawn ... --thread ...osessions_spawn({ runtime: "acp", thread: true })).- Se le associazioni dei thread sono disabilitate per un account,
/focuse le relative operazioni sulle associazioni dei thread non sono disponibili.
Associazioni persistenti dei canali ACP
Associazioni persistenti dei canali ACP
bindings[]contype: "acp"ematch.channel: "discord"
/acp spawn codex --bind hereassocia il canale o thread Discord corrente sul posto e mantiene i messaggi futuri instradati alla stessa sessione ACP.- Questo può comunque significare “avvia una nuova sessione ACP Codex”, ma non crea da solo un nuovo thread Discord. Il canale esistente resta la superficie della chat.
- Codex può comunque essere eseguito nel proprio
cwdo workspace backend su disco. Quel workspace è stato di runtime, non un thread Discord. - I messaggi dei thread possono ereditare l’associazione ACP del canale padre.
- In un canale o thread associato,
/newe/resetreimpostano sul posto la stessa sessione ACP. - Le associazioni temporanee dei thread continuano a funzionare e possono sovrascrivere la risoluzione del target mentre sono attive.
spawnAcpSessionsè richiesto solo quando OpenClaw deve creare/associare un thread figlio tramite--thread auto|here. Non è richiesto per/acp spawn ... --bind herenel canale corrente.
Notifiche di reazione
Notifiche di reazione
offown(predefinito)allallowlist(usaguilds.<id>.users)
Reazioni di conferma
Reazioni di conferma
ackReaction invia un’emoji di conferma mentre OpenClaw sta elaborando un messaggio in ingresso.Ordine di risoluzione:channels.discord.accounts.<accountId>.ackReactionchannels.discord.ackReactionmessages.ackReaction- fallback emoji dell’identità dell’agente (
agents.list[].identity.emoji, altrimenti ”👀”)
- Discord accetta emoji unicode o nomi di emoji personalizzate.
- Usa
""per disabilitare la reazione per un canale o account.
Scritture di configurazione
Scritture di configurazione
/config set|unset (quando le funzionalità dei comandi sono abilitate).Disabilita:Proxy del gateway
Proxy del gateway
channels.discord.proxy.Supporto PluralKit
Supporto PluralKit
- le allowlist possono usare
pk:<memberId> - i nomi visualizzati dei membri vengono associati per nome/slug solo quando
channels.discord.dangerouslyAllowNameMatching: true - le ricerche usano l’ID messaggio originale e sono vincolate nel tempo
- se la ricerca fallisce, i messaggi proxati vengono trattati come messaggi del bot e scartati a meno che
allowBots=true
Configurazione della presenza
Configurazione della presenza
- 0: Playing
- 1: Streaming (richiede
activityUrl) - 2: Listening
- 3: Watching
- 4: Custom (usa il testo dell’attività come stato; l’emoji è facoltativa)
- 5: Competing
autoPresence.healthyTextautoPresence.degradedTextautoPresence.exhaustedText(supporta il segnaposto{reason})
Approvazioni in Discord
Approvazioni in Discord
channels.discord.execApprovals.enabledchannels.discord.execApprovals.approvers(facoltativo; usacommands.ownerAllowFromcome fallback quando possibile)channels.discord.execApprovals.target(dm|channel|both, predefinito:dm)agentFilter,sessionFilter,cleanupAfterResolve
enabled non è impostato o vale "auto" e può essere risolto almeno un approvatore, sia da execApprovals.approvers sia da commands.ownerAllowFrom. Discord non deduce gli approvatori exec da allowFrom del canale, da dm.allowFrom legacy o da defaultTo dei messaggi diretti. Imposta enabled: false per disabilitare esplicitamente Discord come client di approvazione nativo.Quando target è channel o both, la richiesta di approvazione è visibile nel canale. Solo gli approvatori risolti possono usare i pulsanti; gli altri utenti ricevono un rifiuto effimero. Le richieste di approvazione includono il testo del comando, quindi abilita la consegna nel canale solo in canali fidati. Se l’ID canale non può essere ricavato dalla chiave della sessione, OpenClaw torna alla consegna via DM.Discord rende anche i pulsanti di approvazione condivisi usati da altri canali di chat. L’adapter nativo Discord aggiunge principalmente l’instradamento DM degli approvatori e il fanout sul canale.
Quando questi pulsanti sono presenti, rappresentano la UX di approvazione primaria; OpenClaw
dovrebbe includere un comando manuale /approve solo quando il risultato dello strumento indica
che le approvazioni in chat non sono disponibili o che l’approvazione manuale è l’unico percorso.L’autenticazione gateway per questo handler usa lo stesso contratto condiviso di risoluzione delle credenziali degli altri client Gateway:- autenticazione locale env-first (
OPENCLAW_GATEWAY_TOKEN/OPENCLAW_GATEWAY_PASSWORDpoigateway.auth.*) - in modalità locale,
gateway.remote.*può essere usato come fallback solo quandogateway.auth.*non è impostato; SecretRef locali configurati ma non risolti falliscono in modalità chiusa - supporto modalità remota tramite
gateway.remote.*quando applicabile - gli override URL sono sicuri rispetto agli override: gli override CLI non riutilizzano credenziali implicite e gli override env usano solo credenziali env
- Gli ID con prefisso
plugin:vengono risolti tramiteplugin.approval.resolve. - Gli altri ID vengono risolti tramite
exec.approval.resolve. - Discord non esegue qui un ulteriore fallback da exec a plugin; il prefisso dell’id decide quale metodo gateway chiamare.
Strumenti e gate delle azioni
Le azioni dei messaggi Discord includono messaggistica, amministrazione del canale, moderazione, presenza e azioni sui metadati. Esempi principali:- messaggistica:
sendMessage,readMessages,editMessage,deleteMessage,threadReply - reazioni:
react,reactions,emojiList - moderazione:
timeout,kick,ban - presenza:
setPresence
event-create accetta un parametro facoltativo image (URL o percorso file locale) per impostare l’immagine di copertina dell’evento pianificato.
I gate delle azioni si trovano sotto channels.discord.actions.*.
Comportamento predefinito dei gate:
| Gruppo di azioni | 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 components v2
OpenClaw usa Discord components v2 per le approvazioni exec e i marcatori cross-context. Le azioni dei messaggi Discord possono anche accettarecomponents per UI personalizzate (avanzato; richiede la costruzione di un payload dei componenti tramite lo strumento discord), mentre i embeds legacy restano disponibili ma non sono consigliati.
channels.discord.ui.components.accentColorimposta il colore di accento usato dai contenitori dei componenti Discord (hex).- Imposta per account con
channels.discord.accounts.<id>.ui.components.accentColor. embedsvengono ignorati quando sono presenti components v2.
Canali vocali
OpenClaw può unirsi ai canali vocali Discord per conversazioni in tempo reale e continue. Questo è separato dagli allegati dei 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 di destinazione.
/vc join|leave|status per controllare le sessioni. Il comando usa l’agente predefinito dell’account e segue le stesse regole di allowlist e group policy degli altri comandi Discord.
Esempio di join automatico:
voice.ttssovrascrivemessages.ttssolo per la riproduzione vocale.- I turni di trascrizione vocale derivano lo stato owner da Discord
allowFrom(odm.allowFrom); i parlanti non owner non possono accedere agli strumenti riservati agli owner (ad esempiogatewayecron). - Voice è abilitato per impostazione predefinita; imposta
channels.discord.voice.enabled=falseper disabilitarlo. voice.daveEncryptionevoice.decryptionFailureTolerancevengono passati alle opzioni di join di@discordjs/voice.- I valori predefiniti di
@discordjs/voicesonodaveEncryption=trueedecryptionFailureTolerance=24se non impostati. - OpenClaw monitora anche i fallimenti di decrittazione in ricezione e si ripristina automaticamente uscendo e rientrando nel canale vocale dopo fallimenti ripetuti in una finestra temporale breve.
- Se i log in ricezione mostrano ripetutamente
DecryptionFailed(UnencryptedWhenPassthroughDisabled), potrebbe trattarsi del bug di ricezione upstream@discordjs/voicetracciato in discord.js #11419.
Messaggi vocali
I messaggi vocali Discord mostrano un’anteprima della forma d’onda e richiedono audio OGG/Opus più metadati. OpenClaw genera automaticamente la forma d’onda, ma richiede cheffmpeg e ffprobe siano disponibili sull’host gateway per ispezionare e convertire i file audio.
Requisiti e vincoli:
- Fornisci un percorso file locale (gli URL vengono rifiutati).
- Ometti il contenuto testuale (Discord non consente testo + messaggio vocale nello stesso payload).
- Qualsiasi formato audio è accettato; OpenClaw lo converte in OGG/Opus quando necessario.
Risoluzione dei problemi
Sono stati usati intent non consentiti oppure il bot non vede messaggi guild
Sono stati usati intent non consentiti oppure 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 in modo imprevisto
Messaggi guild bloccati in modo imprevisto
- verifica
groupPolicy - verifica l’allowlist guild sotto
channels.discord.guilds - se esiste la mappa guild
channels, sono consentiti solo i canali elencati - verifica il comportamento di
requireMentione i pattern di menzione
Require mention false ma ancora bloccato
Require mention false ma ancora bloccato
groupPolicy="allowlist"senza allowlist guild/canale corrispondenterequireMentionconfigurato nel posto sbagliato (deve trovarsi sottochannels.discord.guildso nella voce del canale)- mittente bloccato dall’allowlist
usersdi guild/canale
Gli handler di lunga durata vanno in timeout o duplicano le risposte
Gli handler di lunga durata vanno in timeout o duplicano le risposte
Listener DiscordMessageListener timed out after 30000ms for event MESSAGE_CREATESlow listener detected ...discord inbound worker timed out after ...
- account singolo:
channels.discord.eventQueue.listenerTimeout - multi-account:
channels.discord.accounts.<accountId>.eventQueue.listenerTimeout
- account singolo:
channels.discord.inboundWorker.runTimeoutMs - multi-account:
channels.discord.accounts.<accountId>.inboundWorker.runTimeoutMs - predefinito:
1800000(30 minuti); imposta0per disabilitare
eventQueue.listenerTimeout per setup lenti del listener e inboundWorker.runTimeoutMs
solo se vuoi una valvola di sicurezza separata per i turni agente in coda.Incongruenze nell'audit dei permessi
Incongruenze nell'audit dei permessi
channels status --probe funzionano solo per ID canale numerici.Se usi chiavi slug, la corrispondenza a runtime può comunque funzionare, ma il probe non può verificare completamente i permessi.Problemi con DM e abbinamento
Problemi con DM e abbinamento
- DM disabilitati:
channels.discord.dm.enabled=false - criterio DM disabilitato:
channels.discord.dmPolicy="disabled"(legacy:channels.discord.dm.policy) - in attesa di approvazione dell’abbinamento in modalità
pairing
Loop bot a bot
Loop bot a bot
channels.discord.allowBots=true, usa regole rigorose di menzione e allowlist per evitare comportamenti a loop.
Preferisci channels.discord.allowBots="mentions" per accettare solo messaggi bot che menzionano il bot.La STT vocale perde messaggi con DecryptionFailed(...)
La STT vocale perde messaggi con DecryptionFailed(...)
- mantieni OpenClaw aggiornato (
openclaw update) così la logica di recupero della ricezione vocale Discord sia presente - conferma
channels.discord.voice.daveEncryption=true(predefinito) - parti da
channels.discord.voice.decryptionFailureTolerance=24(predefinito upstream) e regolalo solo se necessario - osserva i log per:
discord voice: DAVE decrypt failures detecteddiscord voice: repeated decrypt failures; attempting rejoin
- se i fallimenti continuano dopo il rientro automatico, raccogli i log e confrontali con discord.js #11419
Riferimenti alla configurazione
Riferimento principale: Campi Discord ad alto segnale:- avvio/autenticazione:
enabled,token,accounts.*,allowBots - criterio:
groupPolicy,dm.*,guilds.*,guilds.*.channels.* - comandi:
commands.native,commands.useAccessGroups,configWrites,slashCommand.* - coda eventi:
eventQueue.listenerTimeout(budget del listener),eventQueue.maxQueueSize,eventQueue.maxConcurrency - worker in ingresso:
inboundWorker.runTimeoutMs - risposta/cronologia:
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:100MB)
- azioni:
actions.* - presenza:
activity,status,activityType,activityUrl - UI:
ui.components.accentColor - funzionalità:
threadBindings,bindings[]di livello superiore (type: "acp"),pluralkit,execApprovals,intents,agentComponents,heartbeat,responsePrefix
Sicurezza e operazioni
- Tratta i token dei bot come segreti (
DISCORD_BOT_TOKENpreferito negli ambienti supervisionati). - Concedi i permessi Discord minimi necessari.
- Se il deploy/stato dei comandi è obsoleto, riavvia il gateway e ricontrolla con
openclaw channels status --probe.