Discord (Bot API)
Status: pronto para DMs e canais de servidor via o gateway oficial do Discord.
- Pareamento — DMs do Discord usam modo de pareamento por padrão.
- Comandos slash — Comportamento de comandos nativos e catálogo de comandos.
- Solução de problemas de canais — Diagnóstico e fluxo de reparo entre canais.
Configuração rápida
Você precisará criar um novo aplicativo com um bot, adicionar o bot ao seu servidor e pareá-lo com o OpenClaw. Recomendamos adicionar o bot ao seu próprio servidor privado. Se você ainda não tem um, crie um primeiro (escolha Create My Own > For me and my friends).
Passo 1: Crie um aplicativo e bot no Discord
Acesse o [Portal de Desenvolvedores do Discord](https://discord.com/developers/applications) e clique em **New Application**. Dê um nome como "OpenClaw".
Clique em **Bot** na barra lateral. Defina o **Username** com o nome que quiser para seu agente OpenClaw.
Passo 2: Ative os intents privilegiados
Ainda na página **Bot**, role até **Privileged Gateway Intents** e ative:
- **Message Content Intent** (obrigatório)
- **Server Members Intent** (recomendado; necessário para listas de permitidos por role e correspondência nome-para-ID)
- **Presence Intent** (opcional; necessário apenas para atualizações de presença)
Passo 3: Copie o token do bot
Role de volta ao topo da página **Bot** e clique em **Reset Token**.
> **Nota:** Apesar do nome, isso gera o seu primeiro token — nada está sendo "resetado".
Copie o token e guarde-o em um local seguro. Este é o seu **Bot Token** e você vai precisar dele em breve.
Passo 4: Gere a URL de convite e adicione o bot ao servidor
Clique em **OAuth2** na barra lateral. Você vai gerar uma URL de convite com as permissões corretas para adicionar o bot ao seu servidor.
Role até **OAuth2 URL Generator** e ative:
- `bot`
- `applications.commands`
Uma seção **Bot Permissions** aparecerá abaixo. Ative:
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (opcional)
Copie a URL gerada na parte inferior, cole no navegador, selecione seu servidor e clique em **Continue** para conectar. Agora você deve ver o bot no servidor do Discord.
Passo 5: Ative o Modo Desenvolvedor e colete seus IDs
De volta ao aplicativo do Discord, você precisa ativar o Modo Desenvolvedor para copiar IDs internos.
1. Clique em **User Settings** (ícone de engrenagem ao lado do avatar) → **Advanced** → ative **Developer Mode**
2. Clique com o botão direito no **ícone do servidor** na barra lateral → **Copy Server ID**
3. Clique com o botão direito no **seu avatar** → **Copy User ID**
Guarde o **Server ID** e o **User ID** junto com o Bot Token — você vai enviar os três para o OpenClaw no próximo passo.
Passo 6: Permita DMs de membros do servidor
Para o pareamento funcionar, o Discord precisa permitir que o bot envie DMs para você. Clique com o botão direito no **ícone do servidor** → **Privacy Settings** → ative **Direct Messages**.
Isso permite que membros do servidor (incluindo bots) enviem DMs para você. Mantenha ativado se quiser usar DMs do Discord com o OpenClaw. Se planeja usar apenas canais de servidor, pode desativar as DMs após o pareamento.
Passo 7: Defina o token do bot de forma segura (não envie pelo chat)
O token do bot Discord é um segredo (como uma senha). Defina-o na máquina que executa o OpenClaw antes de enviar mensagens ao agente.
openclaw config set channels.discord.token '"YOUR_BOT_TOKEN"' --json
openclaw config set channels.discord.enabled true --json
openclaw gateway
Se o OpenClaw já estiver rodando como serviço em segundo plano, use `openclaw gateway restart`.
Passo 8: Configure o OpenClaw e faça o pareamento
#### Pergunte ao seu agente
Converse com seu agente OpenClaw em qualquer canal existente (ex.: Telegram) e diga. Se o Discord for o seu primeiro canal, use a aba CLI / config.
> "I already set my Discord bot token in config. Please finish Discord setup with User ID `<user_id>` and Server ID `<server_id>`."
#### CLI / config
Se preferir configuração via arquivo, defina:
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN",
},
},
}
Fallback por variável de ambiente para a conta padrão:
DISCORD_BOT_TOKEN=...
Valores SecretRef também são suportados para `channels.discord.token` (providers env/file/exec). Veja [Gerenciamento de Segredos](/docs/gateway/secrets).
Passo 9: Aprove o primeiro pareamento por DM
Aguarde o gateway estar rodando, depois envie uma DM para o bot no Discord. Ele responderá com um código de pareamento.
#### Pergunte ao seu agente
Envie o código de pareamento para o agente em um canal existente:
> "Approve this Discord pairing code: `<CODE>`"
#### CLI
openclaw pairing list discord
openclaw pairing approve discord <CODE>
Códigos de pareamento expiram após 1 hora.
Agora você deve conseguir conversar com o agente via DM no Discord.
Nota: A resolução do token reconhece contas. Valores de token na config têm prioridade sobre o fallback por variável de ambiente.
DISCORD_BOT_TOKENé usado apenas para a conta padrão. Para chamadas de saída avançadas (ferramenta de mensagem/ações de canal), umtokenexplícito por chamada é utilizado. Configurações de política/retry da conta ainda vêm da conta selecionada no snapshot ativo do runtime.
Recomendado: configure um workspace de servidor
Uma vez que as DMs estejam funcionando, você pode configurar o servidor do Discord como um workspace completo onde cada canal tem sua própria sessão de agente com contexto próprio. Isso é recomendado para servidores privados onde é apenas você e o bot.
Passo 1: Adicione o servidor à lista de permitidos de servidores
Isso permite que o agente responda em qualquer canal do servidor, não apenas via DMs.
#### Pergunte ao seu agente
> "Add my Discord Server ID `<server_id>` to the guild allowlist"
#### Config
{
channels: {
discord: {
groupPolicy: "allowlist",
guilds: {
YOUR_SERVER_ID: {
requireMention: true,
users: ["YOUR_USER_ID"],
},
},
},
},
}
Passo 2: Permita respostas sem @menção
Por padrão, o agente só responde em canais de servidor quando é @mencionado. Em um servidor privado, você provavelmente quer que ele responda a todas as mensagens.
#### Pergunte ao seu agente
> "Allow my agent to respond on this server without having to be @mentioned"
#### Config
Defina `requireMention: false` na configuração do servidor:
{
channels: {
discord: {
guilds: {
YOUR_SERVER_ID: {
requireMention: false,
},
},
},
},
}
Passo 3: Planeje o uso de memória em canais de servidor
Por padrão, a memória de longo prazo (MEMORY.md) só é carregada em sessões de DM. Canais de servidor não carregam o MEMORY.md automaticamente.
#### Pergunte ao seu agente
> "When I ask questions in Discord channels, use memory_search or memory_get if you need long-term context from MEMORY.md."
#### Manual
Se precisar de contexto compartilhado em todos os canais, coloque as instruções estáveis em `AGENTS.md` ou `USER.md` (são injetados em toda sessão). Mantenha anotações de longo prazo em `MEMORY.md` e acesse-as sob demanda com as ferramentas de memória.
Agora crie alguns canais no seu servidor do Discord e comece a conversar. O agente pode ver o nome do canal, e cada canal tem sua própria sessão isolada — então você pode criar #coding, #home, #research ou o que se encaixar no seu fluxo de trabalho.
Modelo de runtime
- O gateway gerencia a conexão com o Discord.
- O roteamento de respostas é determinístico: mensagens recebidas pelo Discord respondem pelo Discord.
- Por padrão (
session.dmScope=main), chats diretos compartilham a sessão principal do agente (agent:main:main). - Canais de servidor usam chaves de sessão isoladas (
agent:<agentId>:discord:channel:<channelId>). - Group DMs são ignoradas por padrão (
channels.discord.dm.groupEnabled=false). - Comandos slash nativos rodam em sessões de comando isoladas (
agent:<agentId>:discord:slash:<userId>), enquanto carregamCommandTargetSessionKeypara a sessão de conversa roteada.
Canais de fórum
Canais de fórum e mídia do Discord só aceitam posts em threads. O OpenClaw suporta duas formas de criá-los:
- Envie uma mensagem para o fórum pai (
channel:<forumId>) para criar um thread automaticamente. O título do thread usa a primeira linha não vazia da mensagem. - Use
openclaw message thread createpara criar um thread diretamente. Não passe--message-idpara canais de fórum.
Exemplo: envie para o fórum pai para criar um thread
openclaw message send --channel discord --target channel:<forumId> \
--message "Topic title\nBody of the post"
Exemplo: crie um thread de fórum explicitamente
openclaw message thread create --channel discord --target channel:<forumId> \
--thread-name "Topic title" --message "Body of the post"
Fóruns pais não aceitam componentes do Discord. Se precisar de componentes, envie para o próprio thread (channel:<threadId>).
Componentes interativos
O OpenClaw suporta containers de componentes v2 do Discord para mensagens de agentes. Use a ferramenta de mensagem com um payload components. Os resultados de interação são roteados de volta ao agente como mensagens normais de entrada e seguem as configurações existentes de replyToMode do Discord.
Blocos suportados:
text,section,separator,actions,media-gallery,file- Linhas de ação permitem até 5 botões ou um único menu de seleção
- Tipos de seleção:
string,user,role,mentionable,channel
Por padrão, componentes são de uso único. Defina components.reusable=true para permitir que botões, seleções e formulários sejam usados múltiplas vezes até expirarem.
Para restringir quem pode clicar em um botão, defina allowedUsers nesse botão (IDs de usuário do Discord, tags ou *). Quando configurado, usuários não correspondentes recebem uma negação efêmera.
Os comandos slash /model e /models abrem um seletor de modelo interativo com dropdowns de provedor e modelo, além de um passo de confirmação. A resposta do seletor é efêmera e somente o usuário que invocou pode usá-la.
Anexos de arquivo:
- Blocos
filedevem apontar para uma referência de anexo (attachment://<filename>) - Forneça o anexo via
media/path/filePath(arquivo único); usemedia-gallerypara múltiplos arquivos - Use
filenamepara sobrescrever o nome do upload quando precisar corresponder à referência do anexo
Formulários modais:
- Adicione
components.modalcom até 5 campos - Tipos de campo:
text,checkbox,radio,select,role-select,user-select - O OpenClaw adiciona um botão de acionamento automaticamente
Exemplo:
{
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" },
],
},
],
},
},
}
Controle de acesso e roteamento
Política de DM
`channels.discord.dmPolicy` controla o acesso a DMs (legado: `channels.discord.dm.policy`):
- `pairing` (padrão)
- `allowlist`
- `open` (requer que `channels.discord.allowFrom` inclua `"*"`; legado: `channels.discord.dm.allowFrom`)
- `disabled`
Se a política de DM não for open, usuários desconhecidos são bloqueados (ou recebem solicitação de pareamento no modo `pairing`).
Precedência multiconta:
- `channels.discord.accounts.default.allowFrom` se aplica apenas à conta `default`.
- Contas nomeadas herdam `channels.discord.allowFrom` quando seu próprio `allowFrom` não está definido.
- Contas nomeadas não herdam `channels.discord.accounts.default.allowFrom`.
Formato de destino de DM para entrega:
- `user:<id>`
- `<@id>` menção
IDs numéricos soltos são ambíguos e rejeitados, a menos que um tipo explícito de destino user/channel seja fornecido.
Política de servidor
O tratamento de servidor é controlado por `channels.discord.groupPolicy`:
- `open`
- `allowlist`
- `disabled`
A baseline segura quando `channels.discord` existe é `allowlist`.
Comportamento de `allowlist`:
- o servidor deve corresponder a `channels.discord.guilds` (`id` preferido, slug aceito)
- listas de permitidos de remetente opcionais: `users` (IDs estáveis recomendados) e `roles` (apenas IDs de role); se qualquer uma estiver configurada, remetentes são permitidos quando correspondem a `users` OU `roles`
- correspondência direta por nome/tag é desativada por padrão; ative `channels.discord.dangerouslyAllowNameMatching: true` apenas como modo de compatibilidade emergencial
- nomes/tags são suportados para `users`, mas IDs são mais seguros; `openclaw security audit` avisa quando entradas por nome/tag são usadas
- se um servidor tiver `channels` configurado, canais não listados são negados
- se um servidor não tiver bloco `channels`, todos os canais nesse servidor permitido são autorizados
Exemplo:
{
channels: {
discord: {
groupPolicy: "allowlist",
guilds: {
"123456789012345678": {
requireMention: true,
ignoreOtherMentions: true,
users: ["987654321098765432"],
roles: ["123456789012345678"],
channels: {
general: { allow: true },
help: { allow: true, requireMention: true },
},
},
},
},
},
}
Se você definir apenas `DISCORD_BOT_TOKEN` sem criar um bloco `channels.discord`, o fallback do runtime é `groupPolicy="allowlist"` (com aviso nos logs), mesmo que `channels.defaults.groupPolicy` seja `open`.
Menções e group DMs
Mensagens de servidor são filtradas por menção por padrão.
A detecção de menção inclui:
- menção explícita ao bot
- padrões de menção configurados (`agents.list[].groupChat.mentionPatterns`, fallback `messages.groupChat.mentionPatterns`)
- comportamento implícito de resposta ao bot nos casos suportados
`requireMention` é configurado por servidor/canal (`channels.discord.guilds...`).
`ignoreOtherMentions` opcionalmente descarta mensagens que mencionam outro usuário/role mas não o bot (excluindo @everyone/@here).
Group DMs:
- padrão: ignoradas (`dm.groupEnabled=false`)
- lista de permitidos opcional via `dm.groupChannels` (IDs de canal ou slugs)
Roteamento de agentes por role
Use bindings[].match.roles para rotear membros do servidor do Discord para diferentes agentes por ID de role. Bindings baseados em role aceitam apenas IDs de role e são avaliados após bindings de peer ou parent-peer e antes de bindings somente de servidor. Se um binding também definir outros campos de correspondência (por exemplo peer + guildId + roles), todos os campos configurados devem corresponder.
{
bindings: [
{
agentId: "opus",
match: {
channel: "discord",
guildId: "123456789012345678",
roles: ["111111111111111111"],
},
},
{
agentId: "sonnet",
match: {
channel: "discord",
guildId: "123456789012345678",
},
},
],
}
Configuração do Portal de Desenvolvedores
Criar aplicativo e bot
1. Discord Developer Portal -> **Applications** -> **New Application**
2. **Bot** -> **Add Bot**
3. Copie o token do bot
Intents privilegiados
Em **Bot -> Privileged Gateway Intents**, ative:
- Message Content Intent
- Server Members Intent (recomendado)
O Presence Intent é opcional e necessário apenas se quiser receber atualizações de presença. Definir a presença do bot (`setPresence`) não requer ativar atualizações de presença dos membros.
Escopos OAuth e permissões básicas
Gerador de URL OAuth:
- escopos: `bot`, `applications.commands`
Permissões básicas típicas:
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (opcional)
Evite `Administrator` a menos que seja explicitamente necessário.
Copiar IDs
Ative o Modo Desenvolvedor do Discord, depois copie:
- server ID
- channel ID
- user ID
Prefira IDs numéricos na configuração do OpenClaw para auditorias e sondagens confiáveis.
Comandos nativos e autenticação de comandos
commands.nativetem valor padrão"auto"e está ativado para o Discord.- Override por canal:
channels.discord.commands.native. commands.native=falselimpa explicitamente comandos nativos do Discord registrados anteriormente.- A autenticação de comandos nativos usa as mesmas listas de permitidos/políticas do Discord que o tratamento normal de mensagens.
- Os comandos podem ainda ser visíveis na UI do Discord para usuários não autorizados; a execução ainda aplica a autenticação do OpenClaw e retorna “not authorized”.
Veja Comandos slash para catálogo e comportamento dos comandos.
Configurações padrão de comandos slash:
ephemeral: true
Detalhes de recursos
Tags de resposta e respostas nativas
O Discord suporta tags de resposta na saída do agente:
- `[[reply_to_current]]`
- `[[reply_to:<id>]]`
Controlado por `channels.discord.replyToMode`:
- `off` (padrão)
- `first`
- `all`
Observação: `off` desativa o threading implícito de respostas. Tags explícitas `[[reply_to_*]]` continuam sendo respeitadas.
IDs de mensagem são expostos no contexto/histórico para que os agentes possam direcionar mensagens específicas.
Preview de streaming ao vivo
O OpenClaw pode transmitir rascunhos de respostas enviando uma mensagem temporária e editando-a conforme o texto chega.
- `channels.discord.streaming` controla o streaming de preview (`off` | `partial` | `block` | `progress`, padrão: `off`).
- `progress` é aceito para consistência entre canais e mapeia para `partial` no Discord.
- `channels.discord.streamMode` é um alias legado e é migrado automaticamente.
- `partial` edita uma única mensagem de preview conforme os tokens chegam.
- `block` emite chunks do tamanho de rascunho (use `draftChunk` para ajustar tamanho e pontos de quebra).
Exemplo:
{
channels: {
discord: {
streaming: "partial",
},
},
}
Padrões de chunking do modo `block` (limitados por `channels.discord.textChunkLimit`):
{
channels: {
discord: {
streaming: "block",
draftChunk: {
minChars: 200,
maxChars: 800,
breakPreference: "paragraph",
},
},
},
}
O streaming de preview funciona apenas com texto; respostas com mídia usam a entrega normal.
Observação: o streaming de preview é separado do block streaming. Quando o block streaming é explicitamente ativado para o Discord, o OpenClaw pula o preview stream para evitar streaming duplicado.
Histórico, contexto e comportamento de threads
Contexto de histórico de servidor:
- `channels.discord.historyLimit` padrão `20`
- fallback: `messages.groupChat.historyLimit`
- `0` desativa
Controles de histórico de DM:
- `channels.discord.dmHistoryLimit`
- `channels.discord.dms["<user_id>"].historyLimit`
Comportamento de threads:
- Threads do Discord são roteados como sessões de canal
- metadados do thread pai podem ser usados para vinculação de sessão pai
- configuração de thread herda a configuração do canal pai, a menos que exista uma entrada específica para o thread
Tópicos de canal são injetados como contexto **não confiável** (não como prompt de sistema).
Sessões vinculadas a threads para subagentes
O Discord pode vincular um thread a um alvo de sessão para que mensagens de acompanhamento naquele thread continuem sendo roteadas para a mesma sessão (incluindo sessões de subagentes).
Comandos:
- `/focus <target>` vincular thread atual/novo a um subagente/alvo de sessão
- `/unfocus` remover vinculação do thread atual
- `/agents` mostrar execuções ativas e estado de vinculação
- `/session idle <duration|off>` inspecionar/atualizar auto-unfocus por inatividade para vinculações focadas
- `/session max-age <duration|off>` inspecionar/atualizar idade máxima para vinculações focadas
Config:
{
session: {
threadBindings: {
enabled: true,
idleHours: 24,
maxAgeHours: 0,
},
},
channels: {
discord: {
threadBindings: {
enabled: true,
idleHours: 24,
maxAgeHours: 0,
spawnSubagentSessions: false, // opt-in
},
},
},
}
Observações:
- `session.threadBindings.*` define padrões globais.
- `channels.discord.threadBindings.*` sobrescreve o comportamento do Discord.
- `spawnSubagentSessions` deve ser true para auto-criar/vincular threads para `sessions_spawn({ thread: true })`.
- `spawnAcpSessions` deve ser true para auto-criar/vincular threads para ACP (`/acp spawn ... --thread ...` ou `sessions_spawn({ runtime: "acp", thread: true })`).
- Se as vinculações de thread estiverem desativadas para uma conta, `/focus` e operações relacionadas não estarão disponíveis.
Veja [Subagentes](/docs/tools/subagents), [Agentes ACP](/docs/tools/acp-agents) e [Referência de Configuração](/docs/gateway/configuration-reference).
Vinculações persistentes de canal ACP
Para workspaces ACP estáveis "sempre ativos", configure vinculações ACP tipadas de nível raiz direcionadas a conversas do Discord.
Caminho de config:
- `bindings[]` com `type: "acp"` e `match.channel: "discord"`
Exemplo:
{
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,
},
},
},
},
},
},
}
Observações:
- Mensagens em threads podem herdar a vinculação ACP do canal pai.
- Em um canal ou thread vinculado, `/new` e `/reset` resetam a mesma sessão ACP no local.
- Vinculações temporárias de thread ainda funcionam e podem sobrescrever a resolução de destino enquanto estiverem ativas.
Veja [Agentes ACP](/docs/tools/acp-agents) para detalhes do comportamento de vinculação.
Notificações de reação
Modo de notificação de reação por servidor:
- `off`
- `own` (padrão)
- `all`
- `allowlist` (usa `guilds.<id>.users`)
Eventos de reação são transformados em eventos de sistema e anexados à sessão do Discord roteada.
Reações de confirmação
`ackReaction` envia um emoji de confirmação enquanto o OpenClaw processa uma mensagem de entrada.
Ordem de resolução:
- `channels.discord.accounts.<accountId>.ackReaction`
- `channels.discord.ackReaction`
- `messages.ackReaction`
- fallback do emoji de identidade do agente (`agents.list[].identity.emoji`, senão "👀")
Observações:
- O Discord aceita emoji unicode ou nomes de emoji customizados.
- Use `""` para desativar a reação para um canal ou conta.
Escritas de configuração
Escritas de configuração iniciadas pelo canal estão ativadas por padrão.
Isso afeta os fluxos `/config set|unset` (quando os recursos de comando estão ativados).
Desativar:
{
channels: {
discord: {
configWrites: false,
},
},
}
Proxy do gateway
Roteie o tráfego WebSocket do gateway do Discord e lookups REST de inicialização (ID do aplicativo + resolução de lista de permitidos) por um proxy HTTP(S) com `channels.discord.proxy`.
{
channels: {
discord: {
proxy: "http://proxy.example:8080",
},
},
}
Override por conta:
{
channels: {
discord: {
accounts: {
primary: {
proxy: "http://proxy.example:8080",
},
},
},
},
}
Suporte PluralKit
Ative a resolução PluralKit para mapear mensagens via proxy para a identidade do membro do sistema:
{
channels: {
discord: {
pluralkit: {
enabled: true,
token: "pk_live_...", // opcional; necessário para sistemas privados
},
},
},
}
Observações:
- listas de permitidos podem usar `pk:<memberId>`
- nomes de exibição de membros são correspondidos por nome/slug apenas quando `channels.discord.dangerouslyAllowNameMatching: true`
- lookups usam o ID da mensagem original e são restritos por janela de tempo
- se o lookup falhar, mensagens via proxy são tratadas como mensagens de bot e descartadas, a menos que `allowBots=true`
Configuração de presença
Atualizações de presença são aplicadas quando você define um campo de status ou atividade, ou quando ativa a presença automática.
Exemplo apenas com status:
{
channels: {
discord: {
status: "idle",
},
},
}
Exemplo com atividade (status customizado é o tipo de atividade padrão):
{
channels: {
discord: {
activity: "Focus time",
activityType: 4,
},
},
}
Exemplo de streaming:
{
channels: {
discord: {
activity: "Live coding",
activityType: 1,
activityUrl: "https://twitch.tv/openclaw",
},
},
}
Mapa de tipos de atividade:
- 0: Playing
- 1: Streaming (requer `activityUrl`)
- 2: Listening
- 3: Watching
- 4: Custom (usa o texto de atividade como estado do status; emoji é opcional)
- 5: Competing
Exemplo de presença automática (sinal de saúde do runtime):
{
channels: {
discord: {
autoPresence: {
enabled: true,
intervalMs: 30000,
minUpdateIntervalMs: 15000,
exhaustedText: "token exhausted",
},
},
},
}
A presença automática mapeia a disponibilidade do runtime para o status do Discord: healthy => online, degraded ou unknown => idle, exhausted ou unavailable => dnd. Overrides de texto opcionais:
- `autoPresence.healthyText`
- `autoPresence.degradedText`
- `autoPresence.exhaustedText` (suporta placeholder `{reason}`)
Aprovações de exec no Discord
O Discord suporta aprovações de exec baseadas em botões via DM e pode opcionalmente postar prompts de aprovação no canal de origem.
Caminho de config:
- `channels.discord.execApprovals.enabled`
- `channels.discord.execApprovals.approvers`
- `channels.discord.execApprovals.target` (`dm` | `channel` | `both`, padrão: `dm`)
- `agentFilter`, `sessionFilter`, `cleanupAfterResolve`
Quando `target` é `channel` ou `both`, o prompt de aprovação é visível no canal. Apenas aprovadores configurados podem usar os botões; outros usuários recebem uma negação efêmera. Os prompts de aprovação incluem o texto do comando, então só ative a entrega por canal em canais confiáveis. Se o ID do canal não puder ser derivado da chave de sessão, o OpenClaw recorre à entrega por DM.
A autenticação do gateway para esse handler usa o mesmo contrato de resolução de credenciais compartilhado de outros clientes do Gateway:
- auth local env-first (`OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD`, depois `gateway.auth.*`)
- em modo local, `gateway.remote.*` pode ser usado como fallback apenas quando `gateway.auth.*` não está definido; SecretRefs locais configurados-mas-não-resolvidos falham fechados
- suporte em modo remoto via `gateway.remote.*` quando aplicável
- overrides de URL são override-safe: overrides do CLI não reutilizam credenciais implícitas, e overrides por env usam apenas credenciais do env
Se as aprovações falharem com IDs de aprovação desconhecidos, verifique a lista de aprovadores e se o recurso está ativado.
Documentação relacionada: [Aprovações de exec](/docs/tools/exec-approvals)
Ferramentas e gates de ações
As ações de mensagem do Discord incluem mensagens, administração de canal, moderação, presença e ações de metadados.
Exemplos principais:
- mensagens:
sendMessage,readMessages,editMessage,deleteMessage,threadReply - reações:
react,reactions,emojiList - moderação:
timeout,kick,ban - presença:
setPresence
Os gates de ação ficam em channels.discord.actions.*.
Comportamento padrão dos gates:
| Grupo de ação | Padrão |
|---|---|
| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | ativado |
| roles | desativado |
| moderation | desativado |
| presence | desativado |
UI de componentes v2
O OpenClaw usa componentes v2 do Discord para aprovações de exec e marcadores de contexto cruzado. As ações de mensagem do Discord também podem aceitar components para UI customizada (avançado; requer instâncias de componentes Carbon), enquanto embeds legados permanecem disponíveis mas não são recomendados.
channels.discord.ui.components.accentColordefine a cor de destaque usada pelos containers de componentes do Discord (hex).- Defina por conta com
channels.discord.accounts.<id>.ui.components.accentColor. embedssão ignorados quando componentes v2 estão presentes.
Exemplo:
{
channels: {
discord: {
ui: {
components: {
accentColor: "#5865F2",
},
},
},
},
}
Canais de voz
O OpenClaw pode entrar em canais de voz do Discord para conversas contínuas em tempo real. Isso é separado dos anexos de mensagem de voz.
Requisitos:
- Ative comandos nativos (
commands.nativeouchannels.discord.commands.native). - Configure
channels.discord.voice. - O bot precisa das permissões Connect + Speak no canal de voz alvo.
Use o comando nativo exclusivo do Discord /vc join|leave|status para controlar sessões. O comando usa o agente padrão da conta e segue as mesmas regras de lista de permitidos e política de grupo que outros comandos do Discord.
Exemplo de auto-join:
{
channels: {
discord: {
voice: {
enabled: true,
autoJoin: [
{
guildId: "123456789012345678",
channelId: "234567890123456789",
},
],
daveEncryption: true,
decryptionFailureTolerance: 24,
tts: {
provider: "openai",
openai: { voice: "alloy" },
},
},
},
},
}
Observações:
voice.ttssobrescrevemessages.ttsapenas para reprodução de voz.- Turnos de transcrição de voz derivam o status de proprietário de
allowFromdo Discord (oudm.allowFrom); falantes não proprietários não podem acessar ferramentas exclusivas de proprietário (por exemplogatewayecron). - A voz é ativada por padrão; defina
channels.discord.voice.enabled=falsepara desativá-la. voice.daveEncryptionevoice.decryptionFailureTolerancesão repassados para as opções de join do@discordjs/voice.- Os padrões do
@discordjs/voicesãodaveEncryption=trueedecryptionFailureTolerance=24quando não definidos. - O OpenClaw também monitora falhas de descriptografia de recebimento e se auto-recupera saindo/reentrando no canal de voz após falhas repetidas em uma janela curta.
- Se os logs de recebimento mostram repetidamente
DecryptionFailed(UnencryptedWhenPassthroughDisabled), isso pode ser o bug de recebimento do@discordjs/voicerastreado em discord.js #11419.
Mensagens de voz
Mensagens de voz do Discord mostram uma pré-visualização de forma de onda e exigem áudio OGG/Opus mais metadados. O OpenClaw gera a forma de onda automaticamente, mas precisa de ffmpeg e ffprobe disponíveis no host do gateway para inspecionar e converter arquivos de áudio.
Requisitos e restrições:
- Forneça um caminho de arquivo local (URLs são rejeitadas).
- Omita conteúdo de texto (o Discord não permite texto + mensagem de voz no mesmo payload).
- Qualquer formato de áudio é aceito; o OpenClaw converte para OGG/Opus quando necessário.
Exemplo:
message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)
Solução de problemas
Intents não permitidos utilizados ou bot não vê mensagens de servidor
- ative Message Content Intent
- ative Server Members Intent quando depender de resolução de usuário/membro
- reinicie o gateway após alterar intents
Mensagens de servidor bloqueadas inesperadamente
- verifique `groupPolicy`
- verifique a lista de permitidos de servidor em `channels.discord.guilds`
- se o mapa `channels` do servidor existir, apenas canais listados são permitidos
- verifique o comportamento de `requireMention` e padrões de menção
Verificações úteis:
openclaw doctor
openclaw channels status --probe
openclaw logs --follow
requireMention false mas ainda bloqueado
Causas comuns:
- `groupPolicy="allowlist"` sem lista de permitidos de servidor/canal correspondente
- `requireMention` configurado no lugar errado (deve estar em `channels.discord.guilds` ou na entrada do canal)
- remetente bloqueado pela lista de permitidos `users` do servidor/canal
Handlers de longa duração expiram ou respostas duplicadas
Logs típicos:
- `Listener DiscordMessageListener timed out after 30000ms for event MESSAGE_CREATE`
- `Slow listener detected ...`
- `discord inbound worker timed out after ...`
Ajuste do orçamento de listener:
- conta única: `channels.discord.eventQueue.listenerTimeout`
- multiconta: `channels.discord.accounts.<accountId>.eventQueue.listenerTimeout`
Ajuste do timeout de execução do worker:
- conta única: `channels.discord.inboundWorker.runTimeoutMs`
- multiconta: `channels.discord.accounts.<accountId>.inboundWorker.runTimeoutMs`
- padrão: `1800000` (30 minutos); defina `0` para desativar
Baseline recomendada:
{
channels: {
discord: {
accounts: {
default: {
eventQueue: {
listenerTimeout: 120000,
},
inboundWorker: {
runTimeoutMs: 1800000,
},
},
},
},
},
}
Use `eventQueue.listenerTimeout` para setup de listeners lentos e `inboundWorker.runTimeoutMs`
apenas se quiser uma válvula de segurança separada para turnos de agente enfileirados.
Incompatibilidades na auditoria de permissões
Verificações de permissão do `channels status --probe` só funcionam para IDs numéricos de canal.
Se usar chaves por slug, a correspondência em runtime ainda pode funcionar, mas o probe não consegue verificar permissões completamente.
Problemas de DM e pareamento
- DM desativada: `channels.discord.dm.enabled=false`
- Política de DM desativada: `channels.discord.dmPolicy="disabled"` (legado: `channels.discord.dm.policy`)
- aguardando aprovação de pareamento no modo `pairing`
Loops de bot para bot
Por padrão, mensagens de autoria de bots são ignoradas.
Se definir `channels.discord.allowBots=true`, use regras estritas de menção e listas de permitidos para evitar comportamento de loop.
Prefira `channels.discord.allowBots="mentions"` para aceitar apenas mensagens de bot que mencionem o bot.
Quedas de STT de voz com DecryptionFailed(...)
- mantenha o OpenClaw atualizado (`openclaw update`) para que a lógica de recuperação de recebimento de voz do Discord esteja presente
- confirme `channels.discord.voice.daveEncryption=true` (padrão)
- comece com `channels.discord.voice.decryptionFailureTolerance=24` (padrão upstream) e ajuste apenas se necessário
- monitore os logs para:
- `discord voice: DAVE decrypt failures detected`
- `discord voice: repeated decrypt failures; attempting rejoin`
- se as falhas continuarem após rejoin automático, colete logs e compare com [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419)
Referência de configuração
Referência principal:
Campos de alto impacto do Discord:
- inicialização/autenticação:
enabled,token,accounts.*,allowBots - política:
groupPolicy,dm.*,guilds.*,guilds.*.channels.* - comando:
commands.native,commands.useAccessGroups,configWrites,slashCommand.* - fila de eventos:
eventQueue.listenerTimeout(orçamento de listener),eventQueue.maxQueueSize,eventQueue.maxConcurrency - worker de entrada:
inboundWorker.runTimeoutMs - resposta/histórico:
replyToMode,historyLimit,dmHistoryLimit,dms.*.historyLimit - entrega:
textChunkLimit,chunkMode,maxLinesPerMessage - streaming:
streaming(alias legado:streamMode),draftChunk,blockStreaming,blockStreamingCoalesce - mídia/retry:
mediaMaxMb,retrymediaMaxMblimita uploads de saída do Discord (padrão:8MB)
- ações:
actions.* - presença:
activity,status,activityType,activityUrl - UI:
ui.components.accentColor - recursos:
threadBindings,bindings[]de nível raiz (type: "acp"),pluralkit,execApprovals,intents,agentComponents,heartbeat,responsePrefix
Segurança e operações
- Trate tokens de bot como segredos (
DISCORD_BOT_TOKENpreferido em ambientes supervisionados). - Conceda permissões de menor privilégio no Discord.
- Se o deploy/estado de comandos estiver obsoleto, reinicie o gateway e verifique novamente com
openclaw channels status --probe.