Discord (Bot API)

Status: pronto para DMs e canais de servidor via o gateway oficial do Discord.

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), um token explí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 carregam CommandTargetSessionKey para 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 create para criar um thread diretamente. Não passe --message-id para 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 file devem apontar para uma referência de anexo (attachment://<filename>)
  • Forneça o anexo via media/path/filePath (arquivo único); use media-gallery para múltiplos arquivos
  • Use filename para sobrescrever o nome do upload quando precisar corresponder à referência do anexo

Formulários modais:

  • Adicione components.modal com 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.native tem valor padrão "auto" e está ativado para o Discord.
  • Override por canal: channels.discord.commands.native.
  • commands.native=false limpa 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çãoPadrão
reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissionsativado
rolesdesativado
moderationdesativado
presencedesativado

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.accentColor define a cor de destaque usada pelos containers de componentes do Discord (hex).
  • Defina por conta com channels.discord.accounts.<id>.ui.components.accentColor.
  • embeds sã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.native ou channels.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.tts sobrescreve messages.tts apenas para reprodução de voz.
  • Turnos de transcrição de voz derivam o status de proprietário de allowFrom do Discord (ou dm.allowFrom); falantes não proprietários não podem acessar ferramentas exclusivas de proprietário (por exemplo gateway e cron).
  • A voz é ativada por padrão; defina channels.discord.voice.enabled=false para desativá-la.
  • voice.daveEncryption e voice.decryptionFailureTolerance são repassados para as opções de join do @discordjs/voice.
  • Os padrões do @discordjs/voice são daveEncryption=true e decryptionFailureTolerance=24 quando 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/voice rastreado 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, retry
    • mediaMaxMb limita 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_TOKEN preferido 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.

Relacionado