Discord (Bot API)

Estado: listo para mensajes directos y canales de servidor a través del gateway oficial de Discord.

Configuración rápida

Necesitarás crear una nueva aplicación con un bot, añadir el bot a tu servidor y vincularlo a OpenClaw. Recomendamos añadir tu bot a tu propio servidor privado. Si aún no tienes uno, crea uno primero (elige Crear uno propio > Para mí y mis amigos).

Paso 1: Crea una aplicación y bot de Discord

Ve al [Portal de Desarrolladores de Discord](https://discord.com/developers/applications) y haz clic en **New Application**. Ponle un nombre como "OpenClaw".

Haz clic en **Bot** en la barra lateral. Establece el **Username** con el nombre que le des a tu agente de OpenClaw.

Paso 2: Activa los intents privilegiados

Aún en la página de **Bot**, desplázate hasta **Privileged Gateway Intents** y activa:

- **Message Content Intent** (obligatorio)
- **Server Members Intent** (recomendado; necesario para listas de permitidos por rol y coincidencia de nombre a ID)
- **Presence Intent** (opcional; solo necesario para actualizaciones de presencia)

Paso 3: Copia tu token del bot

Vuelve arriba en la página de **Bot** y haz clic en **Reset Token**.

> **Nota:** A pesar del nombre, esto genera tu primer token — no se está "restableciendo" nada.

Copia el token y guárdalo en un lugar seguro. Este es tu **Bot Token** y lo necesitarás en breve.

Paso 4: Genera una URL de invitación y añade el bot a tu servidor

Haz clic en **OAuth2** en la barra lateral. Generarás una URL de invitación con los permisos adecuados para añadir el bot a tu servidor.

Desplázate hasta **OAuth2 URL Generator** y activa:

- `bot`
- `applications.commands`

Aparecerá una sección de **Bot Permissions** debajo. Activa:

- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (opcional)

Copia la URL generada en la parte inferior, pégala en tu navegador, selecciona tu servidor y haz clic en **Continue** para conectar. Ahora deberías ver tu bot en el servidor de Discord.

Paso 5: Activa el modo desarrollador y recopila tus IDs

De vuelta en la app de Discord, necesitas activar el modo desarrollador para poder copiar IDs internos.

1. Haz clic en **Configuración de usuario** (icono de engranaje junto a tu avatar) → **Avanzado** → activa **Modo desarrollador**
2. Haz clic derecho en el **icono de tu servidor** en la barra lateral → **Copiar ID del servidor**
3. Haz clic derecho en tu **propio avatar** → **Copiar ID de usuario**

Guarda tu **ID del servidor** y tu **ID de usuario** junto con tu Bot Token — enviarás los tres a OpenClaw en el siguiente paso.

Paso 6: Permite mensajes directos de miembros del servidor

Para que el emparejamiento funcione, Discord necesita permitir que tu bot te envíe mensajes directos. Haz clic derecho en el **icono de tu servidor** → **Configuración de privacidad** → activa **Mensajes directos**.

Esto permite que los miembros del servidor (incluidos los bots) te envíen mensajes directos. Mantén esto activado si quieres usar mensajes directos de Discord con OpenClaw. Si solo planeas usar canales del servidor, puedes desactivar los mensajes directos después del emparejamiento.

Paso 7: Configura tu token del bot de forma segura (no lo envíes por chat)

Tu token del bot de Discord es un secreto (como una contraseña). Configúralo en la máquina que ejecuta OpenClaw antes de enviar mensajes a tu agente.
openclaw config set channels.discord.token '"YOUR_BOT_TOKEN"' --json
openclaw config set channels.discord.enabled true --json
openclaw gateway
Si OpenClaw ya se ejecuta como servicio en segundo plano, usa `openclaw gateway restart` en su lugar.

Paso 8: Configura OpenClaw y empareja

  #### Pregunta a tu agente
    Chatea con tu agente de OpenClaw en cualquier canal existente (p. ej., Telegram) y dile. Si Discord es tu primer canal, usa la pestaña de CLI / config.

    > "Ya configuré mi token del bot de Discord en config. Por favor completa la configuración de Discord con User ID `<user_id>` y Server ID `<server_id>`."

  #### CLI / config
    Si prefieres la configuración por archivo:
{
  channels: {
    discord: {
      enabled: true,
      token: "YOUR_BOT_TOKEN",
    },
  },
}
    Variable de entorno alternativa para la cuenta predeterminada:
DISCORD_BOT_TOKEN=...
    Los valores SecretRef también son compatibles con `channels.discord.token` (proveedores env/file/exec). Consulta [Gestión de secretos](/docs/gateway/secrets).

Paso 9: Aprueba el primer emparejamiento de mensajes directos

Espera hasta que el gateway esté en ejecución, luego envía un mensaje directo a tu bot en Discord. Responderá con un código de emparejamiento.


  #### Pregunta a tu agente
    Envía el código de emparejamiento a tu agente en tu canal existente:

    > "Aprueba este código de emparejamiento de Discord: `<CODE>`"

  #### CLI
openclaw pairing list discord
openclaw pairing approve discord <CODE>
Los códigos de emparejamiento expiran después de 1 hora.

Ahora deberías poder chatear con tu agente en Discord por mensaje directo.

Nota: La resolución de tokens tiene en cuenta la cuenta. Los valores de token en config tienen prioridad sobre la variable de entorno alternativa. DISCORD_BOT_TOKEN solo se usa para la cuenta predeterminada. Para llamadas salientes avanzadas (herramienta de mensaje/acciones de canal), se usa un token explícito por llamada. La política de cuenta/reintentos sigue viniendo de la cuenta seleccionada en la snapshot de runtime activa.

Recomendado: configura un espacio de trabajo del servidor

Una vez que los mensajes directos funcionen, puedes configurar tu servidor de Discord como un espacio de trabajo completo donde cada canal tiene su propia sesión de agente con su propio contexto. Esto es recomendable para servidores privados donde solo estás tú y tu bot.

Paso 1: Añade tu servidor a la lista de servidores permitidos

Esto permite que tu agente responda en cualquier canal de tu servidor, no solo en mensajes directos.


  #### Pregunta a tu agente
    > "Añade mi Server ID de Discord `<server_id>` a la lista de servidores permitidos"

  #### Config
{
  channels: {
    discord: {
      groupPolicy: "allowlist",
      guilds: {
        YOUR_SERVER_ID: {
          requireMention: true,
          users: ["YOUR_USER_ID"],
        },
      },
    },
  },
}

Paso 2: Permite respuestas sin @mención

Por defecto, tu agente solo responde en canales del servidor cuando se le @menciona. Para un servidor privado, probablemente quieres que responda a todos los mensajes.


  #### Pregunta a tu agente
    > "Permite que mi agente responda en este servidor sin tener que ser @mencionado"

  #### Config
    Establece `requireMention: false` en la configuración de tu servidor:
{
  channels: {
    discord: {
      guilds: {
        YOUR_SERVER_ID: {
          requireMention: false,
        },
      },
    },
  },
}

Paso 3: Planifica la memoria en canales del servidor

Por defecto, la memoria a largo plazo (MEMORY.md) solo se carga en sesiones de mensajes directos. Los canales del servidor no cargan MEMORY.md automáticamente.


  #### Pregunta a tu agente
    > "Cuando hago preguntas en los canales de Discord, usa memory_search o memory_get si necesitas contexto a largo plazo de MEMORY.md."

  #### Manual
    Si necesitas contexto compartido en cada canal, pon las instrucciones estables en `AGENTS.md` o `USER.md` (se inyectan en cada sesión). Mantén las notas a largo plazo en `MEMORY.md` y accede a ellas bajo demanda con las herramientas de memoria.

Ahora crea algunos canales en tu servidor de Discord y empieza a chatear. Tu agente puede ver el nombre del canal, y cada canal tiene su propia sesión aislada — así puedes configurar #coding, #home, #research, o lo que se ajuste a tu flujo de trabajo.

Modelo de runtime

  • El gateway gestiona la conexión de Discord.
  • El enrutamiento de respuestas es determinístico: las entradas de Discord se responden en Discord.
  • Por defecto (session.dmScope=main), los chats directos comparten la sesión principal del agente (agent:main:main).
  • Los canales del servidor son claves de sesión aisladas (agent:<agentId>:discord:channel:<channelId>).
  • Los mensajes directos de grupo se ignoran por defecto (channels.discord.dm.groupEnabled=false).
  • Los comandos slash nativos se ejecutan en sesiones de comando aisladas (agent:<agentId>:discord:slash:<userId>), mientras llevan CommandTargetSessionKey a la sesión de conversación enrutada.

Canales de foro

Los canales de foro y medios de Discord solo aceptan publicaciones en hilos. OpenClaw admite dos formas de crearlos:

  • Envía un mensaje al foro padre (channel:<forumId>) para crear automáticamente un hilo. El título del hilo usa la primera línea no vacía de tu mensaje.
  • Usa openclaw message thread create para crear un hilo directamente. No pases --message-id para canales de foro.

Ejemplo: enviar al foro padre para crear un hilo

openclaw message send --channel discord --target channel:<forumId> \
  --message "Topic title\nBody of the post"

Ejemplo: crear un hilo de foro explícitamente

openclaw message thread create --channel discord --target channel:<forumId> \
  --thread-name "Topic title" --message "Body of the post"

Los foros padre no aceptan componentes de Discord. Si necesitas componentes, envía al hilo en sí (channel:<threadId>).

Componentes interactivos

OpenClaw admite contenedores de componentes v2 de Discord para mensajes de agentes. Usa la herramienta de mensaje con un payload components. Los resultados de las interacciones se enrutan de vuelta al agente como mensajes entrantes normales y siguen la configuración existente de replyToMode de Discord.

Bloques compatibles:

  • text, section, separator, actions, media-gallery, file
  • Las filas de acciones permiten hasta 5 botones o un único menú de selección
  • Tipos de selección: string, user, role, mentionable, channel

Por defecto, los componentes son de un solo uso. Establece components.reusable=true para permitir que los botones, selectores y formularios se usen múltiples veces hasta que expiren.

Para restringir quién puede hacer clic en un botón, establece allowedUsers en ese botón (IDs de usuario de Discord, tags o *). Cuando está configurado, los usuarios no coincidentes reciben una denegación efímera.

Los comandos slash /model y /models abren un selector de modelo interactivo con menús desplegables de proveedor y modelo más un paso de confirmación. La respuesta del selector es efímera y solo el usuario que lo invocó puede usarla.

Archivos adjuntos:

  • Los bloques file deben apuntar a una referencia de adjunto (attachment://<filename>)
  • Proporciona el adjunto a través de media/path/filePath (archivo único); usa media-gallery para múltiples archivos
  • Usa filename para sobrescribir el nombre de carga cuando deba coincidir con la referencia del adjunto

Formularios modales:

  • Añade components.modal con hasta 5 campos
  • Tipos de campo: text, checkbox, radio, select, role-select, user-select
  • OpenClaw añade un botón de activación automáticamente

Ejemplo:

{
  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" },
          ],
        },
      ],
    },
  },
}

Control de acceso y enrutamiento

Política de mensajes directos

`channels.discord.dmPolicy` controla el acceso a mensajes directos (legacy: `channels.discord.dm.policy`):

- `pairing` (predeterminado)
- `allowlist`
- `open` (requiere que `channels.discord.allowFrom` incluya `"*"`; legacy: `channels.discord.dm.allowFrom`)
- `disabled`

Si la política de mensajes directos no es abierta, los usuarios desconocidos se bloquean (o se les solicita emparejamiento en modo `pairing`).

Precedencia multicuenta:

- `channels.discord.accounts.default.allowFrom` aplica solo a la cuenta `default`.
- Las cuentas con nombre heredan `channels.discord.allowFrom` cuando su propio `allowFrom` no está establecido.
- Las cuentas con nombre no heredan `channels.discord.accounts.default.allowFrom`.

Formato de destino de mensajes directos para entrega:

- `user:<id>`
- `<@id>` mención

Los IDs numéricos solos son ambiguos y se rechazan a menos que se proporcione un tipo explícito de destino user/channel.

Política de servidor

La gestión de servidores se controla con `channels.discord.groupPolicy`:

- `open`
- `allowlist`
- `disabled`

La línea base segura cuando `channels.discord` existe es `allowlist`.

Comportamiento de `allowlist`:

- el servidor debe coincidir con `channels.discord.guilds` (se prefiere `id`, se acepta slug)
- listas de permitidos opcionales por remitente: `users` (se recomiendan IDs estables) y `roles` (solo IDs de rol); si alguna está configurada, los remitentes se permiten cuando coinciden con `users` O `roles`
- la coincidencia directa por nombre/tag está desactivada por defecto; activa `channels.discord.dangerouslyAllowNameMatching: true` solo como modo de emergencia de compatibilidad
- nombres/tags son compatibles para `users`, pero los IDs son más seguros; `openclaw security audit` advierte cuando se usan entradas de nombre/tag
- si un servidor tiene `channels` configurados, los canales no listados se deniegan
- si un servidor no tiene bloque `channels`, todos los canales de ese servidor permitido están habilitados

Ejemplo:
{
  channels: {
    discord: {
      groupPolicy: "allowlist",
      guilds: {
        "123456789012345678": {
          requireMention: true,
          ignoreOtherMentions: true,
          users: ["987654321098765432"],
          roles: ["123456789012345678"],
          channels: {
            general: { allow: true },
            help: { allow: true, requireMention: true },
          },
        },
      },
    },
  },
}
Si solo estableces `DISCORD_BOT_TOKEN` y no creas un bloque `channels.discord`, el runtime por defecto usa `groupPolicy="allowlist"` (con un aviso en los registros), incluso si `channels.defaults.groupPolicy` es `open`.

Menciones y mensajes directos de grupo

Los mensajes del servidor están controlados por mención por defecto.

La detección de menciones incluye:

- mención explícita del bot
- patrones de mención configurados (`agents.list[].groupChat.mentionPatterns`, alternativa `messages.groupChat.mentionPatterns`)
- comportamiento implícito de respuesta al bot en casos compatibles

`requireMention` se configura por servidor/canal (`channels.discord.guilds...`).
`ignoreOtherMentions` opcionalmente descarta mensajes que mencionan a otro usuario/rol pero no al bot (excluyendo @everyone/@here).

Mensajes directos de grupo:

- por defecto: ignorados (`dm.groupEnabled=false`)
- lista de permitidos opcional vía `dm.groupChannels` (IDs de canal o slugs)

Enrutamiento de agentes basado en roles

Usa bindings[].match.roles para enrutar miembros del servidor de Discord a diferentes agentes por ID de rol. Las vinculaciones basadas en roles aceptan solo IDs de rol y se evalúan después de las vinculaciones por par o par padre y antes de las vinculaciones solo por servidor. Si una vinculación también establece otros campos de coincidencia (por ejemplo peer + guildId + roles), todos los campos configurados deben coincidir.

{
  bindings: [
    {
      agentId: "opus",
      match: {
        channel: "discord",
        guildId: "123456789012345678",
        roles: ["111111111111111111"],
      },
    },
    {
      agentId: "sonnet",
      match: {
        channel: "discord",
        guildId: "123456789012345678",
      },
    },
  ],
}

Configuración del Portal de Desarrolladores

Crear app y bot
1. Discord Developer Portal -> **Applications** -> **New Application**
2. **Bot** -> **Add Bot**
3. Copia el token del bot
Intents privilegiados
En **Bot -> Privileged Gateway Intents**, activa:

- Message Content Intent
- Server Members Intent (recomendado)

El intent de presencia es opcional y solo necesario si quieres recibir actualizaciones de presencia. Establecer la presencia del bot (`setPresence`) no requiere activar las actualizaciones de presencia de los miembros.
Scopes de OAuth y permisos base
Generador de URL OAuth:

- scopes: `bot`, `applications.commands`

Permisos base típicos:

- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (opcional)

Evita `Administrator` a menos que sea explícitamente necesario.
Copiar IDs
Activa el modo desarrollador de Discord, luego copia:

- ID del servidor
- ID del canal
- ID de usuario

Prefiere IDs numéricos en la configuración de OpenClaw para auditorías y sondeos confiables.

Comandos nativos y autorización de comandos

  • commands.native por defecto es "auto" y está activado para Discord.
  • Excepción por canal: channels.discord.commands.native.
  • commands.native=false limpia explícitamente los comandos nativos de Discord registrados previamente.
  • La autorización de comandos nativos usa las mismas listas de permitidos/políticas de Discord que el manejo normal de mensajes.
  • Los comandos pueden seguir siendo visibles en la interfaz de Discord para usuarios no autorizados; la ejecución sigue aplicando la autenticación de OpenClaw y devuelve “no autorizado”.

Consulta Comandos slash para el catálogo y comportamiento de comandos.

Configuración predeterminada de comandos slash:

  • ephemeral: true

Detalles de funcionalidades

Etiquetas de respuesta y respuestas nativas
Discord admite etiquetas de respuesta en la salida del agente:

- `[[reply_to_current]]`
- `[[reply_to:<id>]]`

Controlado por `channels.discord.replyToMode`:

- `off` (predeterminado)
- `first`
- `all`

Nota: `off` desactiva el hilo de respuesta implícito. Las etiquetas explícitas `[[reply_to_*]]` se respetan igualmente.

Los IDs de mensaje se presentan en el contexto/historial para que los agentes puedan apuntar a mensajes específicos.
Vista previa de streaming en vivo
OpenClaw puede transmitir borradores de respuestas enviando un mensaje temporal y editándolo a medida que llega el texto.

- `channels.discord.streaming` controla la transmisión de vista previa (`off` | `partial` | `block` | `progress`, por defecto: `off`).
- `progress` se acepta para consistencia entre canales y se mapea a `partial` en Discord.
- `channels.discord.streamMode` es un alias legacy y se auto-migra.
- `partial` edita un único mensaje de vista previa a medida que llegan los tokens.
- `block` emite fragmentos del tamaño del borrador (usa `draftChunk` para ajustar tamaño y puntos de corte).

Ejemplo:
{
  channels: {
    discord: {
      streaming: "partial",
    },
  },
}
Valores predeterminados de fragmentación en modo `block` (limitados por `channels.discord.textChunkLimit`):
{
  channels: {
    discord: {
      streaming: "block",
      draftChunk: {
        minChars: 200,
        maxChars: 800,
        breakPreference: "paragraph",
      },
    },
  },
}
La transmisión de vista previa es solo texto; las respuestas con medios usan la entrega normal.

Nota: la transmisión de vista previa es separada de la transmisión por bloques. Cuando la transmisión por bloques está habilitada explícitamente para Discord, OpenClaw omite la transmisión de vista previa para evitar doble transmisión.
Historial, contexto y comportamiento de hilos
Contexto de historial del servidor:

- `channels.discord.historyLimit` por defecto `20`
- alternativa: `messages.groupChat.historyLimit`
- `0` desactiva

Controles de historial de mensajes directos:

- `channels.discord.dmHistoryLimit`
- `channels.discord.dms["<user_id>"].historyLimit`

Comportamiento de hilos:

- Los hilos de Discord se enrutan como sesiones de canal
- Los metadatos del hilo padre pueden usarse para vincular sesiones padre
- La configuración de hilos hereda la configuración del canal padre a menos que exista una entrada específica del hilo

Los temas de canal se inyectan como contexto **no confiable** (no como prompt del sistema).
Sesiones vinculadas a hilos para subagentes
Discord puede vincular un hilo a un destino de sesión para que los mensajes de seguimiento en ese hilo sigan enrutándose a la misma sesión (incluidas las sesiones de subagentes).

Comandos:

- `/focus <target>` vincula el hilo actual/nuevo a un destino de subagente/sesión
- `/unfocus` elimina la vinculación del hilo actual
- `/agents` muestra las ejecuciones activas y el estado de vinculación
- `/session idle <duration|off>` inspecciona/actualiza el auto-desenfoque por inactividad para vinculaciones enfocadas
- `/session max-age <duration|off>` inspecciona/actualiza la edad máxima dura para vinculaciones enfocadas

Configuración:
{
  session: {
    threadBindings: {
      enabled: true,
      idleHours: 24,
      maxAgeHours: 0,
    },
  },
  channels: {
    discord: {
      threadBindings: {
        enabled: true,
        idleHours: 24,
        maxAgeHours: 0,
        spawnSubagentSessions: false, // opt-in
      },
    },
  },
}
Notas:

- `session.threadBindings.*` establece los valores predeterminados globales.
- `channels.discord.threadBindings.*` sobrescribe el comportamiento de Discord.
- `spawnSubagentSessions` debe ser true para auto-crear/vincular hilos para `sessions_spawn({ thread: true })`.
- `spawnAcpSessions` debe ser true para auto-crear/vincular hilos para ACP (`/acp spawn ... --thread ...` o `sessions_spawn({ runtime: "acp", thread: true })`).
- Si las vinculaciones de hilo están desactivadas para una cuenta, `/focus` y las operaciones relacionadas no están disponibles.

Consulta [Subagentes](/docs/tools/subagents), [Agentes ACP](/docs/tools/acp-agents) y [Referencia de configuración](/docs/gateway/configuration-reference).
Vinculaciones persistentes de canal ACP
Para espacios de trabajo ACP estables "siempre activos", configura vinculaciones ACP tipadas de nivel superior apuntando a conversaciones de Discord.

Ruta de configuración:

- `bindings[]` con `type: "acp"` y `match.channel: "discord"`

Ejemplo:
{
  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,
            },
          },
        },
      },
    },
  },
}
Notas:

- Los mensajes en hilos pueden heredar la vinculación ACP del canal padre.
- En un canal o hilo vinculado, `/new` y `/reset` restablecen la misma sesión ACP.
- Las vinculaciones temporales de hilo siguen funcionando y pueden sobrescribir la resolución de destino mientras estén activas.

Consulta [Agentes ACP](/docs/tools/acp-agents) para detalles del comportamiento de vinculaciones.
Notificaciones de reacciones
Modo de notificación de reacciones por servidor:

- `off`
- `own` (predeterminado)
- `all`
- `allowlist` (usa `guilds.<id>.users`)

Los eventos de reacción se convierten en eventos del sistema y se adjuntan a la sesión de Discord enrutada.
Reacciones de confirmación
`ackReaction` envía un emoji de confirmación mientras OpenClaw procesa un mensaje entrante.

Orden de resolución:

- `channels.discord.accounts.<accountId>.ackReaction`
- `channels.discord.ackReaction`
- `messages.ackReaction`
- emoji alternativo de identidad del agente (`agents.list[].identity.emoji`, si no "👀")

Notas:

- Discord acepta emoji unicode o nombres de emoji personalizados.
- Usa `""` para desactivar la reacción para un canal o cuenta.
Escrituras de configuración
Las escrituras de configuración iniciadas desde el canal están activadas por defecto.

Esto afecta a los flujos `/config set|unset` (cuando las funciones de comando están activadas).

Desactivar:
{
  channels: {
    discord: {
      configWrites: false,
    },
  },
}
Proxy del gateway
Enruta el tráfico WebSocket del gateway de Discord y las búsquedas REST de inicio (ID de aplicación + resolución de listas de permitidos) a través de un proxy HTTP(S) con `channels.discord.proxy`.
{
  channels: {
    discord: {
      proxy: "http://proxy.example:8080",
    },
  },
}
Excepción por cuenta:
{
  channels: {
    discord: {
      accounts: {
        primary: {
          proxy: "http://proxy.example:8080",
        },
      },
    },
  },
}
Compatibilidad con PluralKit
Activa la resolución de PluralKit para mapear mensajes proxied a la identidad del miembro del sistema:
{
  channels: {
    discord: {
      pluralkit: {
        enabled: true,
        token: "pk_live_...", // opcional; necesario para sistemas privados
      },
    },
  },
}
Notas:

- las listas de permitidos pueden usar `pk:<memberId>`
- los nombres de pantalla de los miembros se comparan por nombre/slug solo cuando `channels.discord.dangerouslyAllowNameMatching: true`
- las búsquedas usan el ID del mensaje original y están limitadas por ventana de tiempo
- si la búsqueda falla, los mensajes proxied se tratan como mensajes de bot y se descartan a menos que `allowBots=true`
Configuración de presencia
Las actualizaciones de presencia se aplican cuando estableces un campo de estado o actividad, o cuando activas la presencia automática.

Ejemplo solo de estado:
{
  channels: {
    discord: {
      status: "idle",
    },
  },
}
Ejemplo de actividad (el estado personalizado es el tipo de actividad predeterminado):
{
  channels: {
    discord: {
      activity: "Focus time",
      activityType: 4,
    },
  },
}
Ejemplo de streaming:
{
  channels: {
    discord: {
      activity: "Live coding",
      activityType: 1,
      activityUrl: "https://twitch.tv/openclaw",
    },
  },
}
Mapa de tipos de actividad:

- 0: Jugando
- 1: Transmitiendo (requiere `activityUrl`)
- 2: Escuchando
- 3: Viendo
- 4: Personalizado (usa el texto de actividad como estado; el emoji es opcional)
- 5: Compitiendo

Ejemplo de presencia automática (señal de salud del runtime):
{
  channels: {
    discord: {
      autoPresence: {
        enabled: true,
        intervalMs: 30000,
        minUpdateIntervalMs: 15000,
        exhaustedText: "token exhausted",
      },
    },
  },
}
La presencia automática mapea la disponibilidad del runtime al estado de Discord: saludable => online, degradado o desconocido => idle, agotado o no disponible => dnd. Textos opcionales personalizados:

- `autoPresence.healthyText`
- `autoPresence.degradedText`
- `autoPresence.exhaustedText` (admite el placeholder `{reason}`)
Aprobaciones de ejecución en Discord
Discord admite aprobaciones de ejecución basadas en botones en mensajes directos y puede opcionalmente publicar solicitudes de aprobación en el canal de origen.

Ruta de configuración:

- `channels.discord.execApprovals.enabled`
- `channels.discord.execApprovals.approvers`
- `channels.discord.execApprovals.target` (`dm` | `channel` | `both`, por defecto: `dm`)
- `agentFilter`, `sessionFilter`, `cleanupAfterResolve`

Cuando `target` es `channel` o `both`, la solicitud de aprobación es visible en el canal. Solo los aprobadores configurados pueden usar los botones; otros usuarios reciben una denegación efímera. Las solicitudes de aprobación incluyen el texto del comando, así que solo activa la entrega al canal en canales confiables. Si no se puede derivar el ID del canal de la clave de sesión, OpenClaw recurre a la entrega por mensaje directo.

La autenticación del gateway para este manejador usa el mismo contrato de resolución de credenciales compartidas que otros clientes del gateway:

- autenticación local con prioridad env (`OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD` luego `gateway.auth.*`)
- en modo local, `gateway.remote.*` puede usarse como alternativa solo cuando `gateway.auth.*` no está establecido; los SecretRef locales configurados pero no resueltos fallan de forma cerrada
- soporte de modo remoto vía `gateway.remote.*` cuando aplique
- las sobrescrituras de URL son seguras: las sobrescrituras de CLI no reutilizan credenciales implícitas, y las sobrescrituras env usan solo credenciales env

Si las aprobaciones fallan con IDs de aprobación desconocidos, verifica la lista de aprobadores y la activación de la función.

Documentación relacionada: [Aprobaciones de ejecución](/docs/tools/exec-approvals)

Herramientas y puertas de acciones

Las acciones de mensajes de Discord incluyen mensajería, administración de canales, moderación, presencia y acciones de metadatos.

Ejemplos principales:

  • mensajería: sendMessage, readMessages, editMessage, deleteMessage, threadReply
  • reacciones: react, reactions, emojiList
  • moderación: timeout, kick, ban
  • presencia: setPresence

Las puertas de acciones están bajo channels.discord.actions.*.

Comportamiento predeterminado de las puertas:

Grupo de accionesPredeterminado
reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissionsactivado
rolesdesactivado
moderationdesactivado
presencedesactivado

Interfaz de componentes v2

OpenClaw usa componentes v2 de Discord para aprobaciones de ejecución y marcadores de contexto cruzado. Las acciones de mensaje de Discord también pueden aceptar components para UI personalizada (avanzado; requiere instancias de componentes Carbon), mientras que los embeds legacy siguen disponibles pero no se recomiendan.

  • channels.discord.ui.components.accentColor establece el color de acento usado por los contenedores de componentes de Discord (hex).
  • Establece por cuenta con channels.discord.accounts.<id>.ui.components.accentColor.
  • Los embeds se ignoran cuando hay componentes v2 presentes.

Ejemplo:

{
  channels: {
    discord: {
      ui: {
        components: {
          accentColor: "#5865F2",
        },
      },
    },
  },
}

Canales de voz

OpenClaw puede unirse a canales de voz de Discord para conversaciones continuas en tiempo real. Esto es independiente de los mensajes de voz como adjuntos.

Requisitos:

  • Activa los comandos nativos (commands.native o channels.discord.commands.native).
  • Configura channels.discord.voice.
  • El bot necesita permisos de Connect + Speak en el canal de voz de destino.

Usa el comando nativo exclusivo de Discord /vc join|leave|status para controlar las sesiones. El comando usa el agente predeterminado de la cuenta y sigue las mismas reglas de lista de permitidos y política de grupo que otros comandos de Discord.

Ejemplo de auto-unión:

{
  channels: {
    discord: {
      voice: {
        enabled: true,
        autoJoin: [
          {
            guildId: "123456789012345678",
            channelId: "234567890123456789",
          },
        ],
        daveEncryption: true,
        decryptionFailureTolerance: 24,
        tts: {
          provider: "openai",
          openai: { voice: "alloy" },
        },
      },
    },
  },
}

Notas:

  • voice.tts sobrescribe messages.tts solo para la reproducción de voz.
  • Los turnos de transcripción de voz derivan el estado de propietario de allowFrom de Discord (o dm.allowFrom); los hablantes que no son propietarios no pueden acceder a herramientas exclusivas del propietario (por ejemplo gateway y cron).
  • La voz está activada por defecto; establece channels.discord.voice.enabled=false para desactivarla.
  • voice.daveEncryption y voice.decryptionFailureTolerance se pasan directamente a las opciones de unión de @discordjs/voice.
  • Los valores predeterminados de @discordjs/voice son daveEncryption=true y decryptionFailureTolerance=24 si no se establecen.
  • OpenClaw también monitorea los fallos de descifrado de recepción y se auto-recupera dejando/reincorporándose al canal de voz después de fallos repetidos en una ventana corta.
  • Si los registros de recepción muestran repetidamente DecryptionFailed(UnencryptedWhenPassthroughDisabled), esto puede ser el bug upstream de recepción de @discordjs/voice rastreado en discord.js #11419.

Mensajes de voz

Los mensajes de voz de Discord muestran una vista previa de forma de onda y requieren audio OGG/Opus más metadatos. OpenClaw genera la forma de onda automáticamente, pero necesita ffmpeg y ffprobe disponibles en el host del gateway para inspeccionar y convertir archivos de audio.

Requisitos y restricciones:

  • Proporciona una ruta de archivo local (las URLs se rechazan).
  • Omite el contenido de texto (Discord no permite texto + mensaje de voz en el mismo payload).
  • Se acepta cualquier formato de audio; OpenClaw lo convierte a OGG/Opus cuando es necesario.

Ejemplo:

message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)

Solución de problemas

Intents no permitidos usados o el bot no ve mensajes del servidor
- activa Message Content Intent
- activa Server Members Intent cuando dependes de la resolución de usuarios/miembros
- reinicia el gateway después de cambiar intents
Mensajes del servidor bloqueados inesperadamente
- verifica `groupPolicy`
- verifica la lista de servidores permitidos en `channels.discord.guilds`
- si el mapa `channels` del servidor existe, solo se permiten los canales listados
- verifica el comportamiento de `requireMention` y los patrones de mención

Comandos útiles:
openclaw doctor
openclaw channels status --probe
openclaw logs --follow
requireMention en false pero sigue bloqueado
Causas comunes:

- `groupPolicy="allowlist"` sin lista de permitidos de servidor/canal correspondiente
- `requireMention` configurado en el lugar incorrecto (debe estar bajo `channels.discord.guilds` o entrada de canal)
- remitente bloqueado por lista de permitidos `users` del servidor/canal
Manejadores de larga duración agotan el tiempo o duplican respuestas
Registros típicos:

- `Listener DiscordMessageListener timed out after 30000ms for event MESSAGE_CREATE`
- `Slow listener detected ...`
- `discord inbound worker timed out after ...`

Control de presupuesto del listener:

- cuenta única: `channels.discord.eventQueue.listenerTimeout`
- multicuenta: `channels.discord.accounts.<accountId>.eventQueue.listenerTimeout`

Control de timeout de ejecución del worker:

- cuenta única: `channels.discord.inboundWorker.runTimeoutMs`
- multicuenta: `channels.discord.accounts.<accountId>.inboundWorker.runTimeoutMs`
- por defecto: `1800000` (30 minutos); establece `0` para desactivar

Línea base recomendada:
{
  channels: {
    discord: {
      accounts: {
        default: {
          eventQueue: {
            listenerTimeout: 120000,
          },
          inboundWorker: {
            runTimeoutMs: 1800000,
          },
        },
      },
    },
  },
}
Usa `eventQueue.listenerTimeout` para la configuración de listener lento e `inboundWorker.runTimeoutMs` solo si quieres una válvula de seguridad separada para turnos de agente en cola.
Inconsistencias en auditoría de permisos
Las verificaciones de permisos de `channels status --probe` solo funcionan para IDs de canal numéricos.

Si usas claves slug, la coincidencia en runtime puede funcionar, pero el sondeo no puede verificar completamente los permisos.
Problemas de mensajes directos y emparejamiento
- Mensajes directos desactivados: `channels.discord.dm.enabled=false`
- Política de mensajes directos desactivada: `channels.discord.dmPolicy="disabled"` (legacy: `channels.discord.dm.policy`)
- esperando aprobación de emparejamiento en modo `pairing`
Bucles de bot a bot
Por defecto, los mensajes de bots se ignoran.

Si estableces `channels.discord.allowBots=true`, usa reglas estrictas de mención y lista de permitidos para evitar comportamiento en bucle.
Prefiere `channels.discord.allowBots="mentions"` para aceptar solo mensajes de bots que mencionen al bot.
Caídas de STT de voz con DecryptionFailed(...)
- mantén OpenClaw actualizado (`openclaw update`) para que la lógica de recuperación de recepción de voz de Discord esté presente
- confirma `channels.discord.voice.daveEncryption=true` (por defecto)
- comienza con `channels.discord.voice.decryptionFailureTolerance=24` (por defecto upstream) y ajusta solo si es necesario
- observa los registros para:
  - `discord voice: DAVE decrypt failures detected`
  - `discord voice: repeated decrypt failures; attempting rejoin`
- si los fallos continúan después de la reconexión automática, recopila registros y compara con [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419)

Referencia de configuración

Referencia principal:

Campos clave de Discord:

  • inicio/auth: enabled, token, accounts.*, allowBots
  • política: groupPolicy, dm.*, guilds.*, guilds.*.channels.*
  • comando: commands.native, commands.useAccessGroups, configWrites, slashCommand.*
  • cola de eventos: eventQueue.listenerTimeout (presupuesto del listener), eventQueue.maxQueueSize, eventQueue.maxConcurrency
  • worker entrante: inboundWorker.runTimeoutMs
  • respuesta/historial: replyToMode, historyLimit, dmHistoryLimit, dms.*.historyLimit
  • entrega: textChunkLimit, chunkMode, maxLinesPerMessage
  • streaming: streaming (alias legacy: streamMode), draftChunk, blockStreaming, blockStreamingCoalesce
  • media/reintentos: mediaMaxMb, retry
    • mediaMaxMb limita las cargas salientes de Discord (por defecto: 8MB)
  • acciones: actions.*
  • presencia: activity, status, activityType, activityUrl
  • UI: ui.components.accentColor
  • funciones: threadBindings, bindings[] de nivel superior (type: "acp"), pluralkit, execApprovals, intents, agentComponents, heartbeat, responsePrefix

Seguridad y operaciones

  • Trata los tokens del bot como secretos (DISCORD_BOT_TOKEN es preferible en entornos supervisados).
  • Otorga los mínimos permisos necesarios en Discord.
  • Si el despliegue/estado de comandos es obsoleto, reinicia el gateway y vuelve a verificar con openclaw channels status --probe.

Relacionado