Saltar al contenido principal

Discord (API de bot)

Estado: listo para mensajes directos y canales de servidor mediante la gateway oficial de Discord.

Emparejamiento

Los mensajes directos de Discord usan el modo de emparejamiento de forma predeterminada.

Comandos de barra inclinada

Comportamiento nativo de comandos y catálogo de comandos.

Solución de problemas del canal

Diagnóstico y flujo de reparación entre canales.

Configuración rápida

Necesitarás crear una aplicación nueva con un bot, añadir el bot a tu servidor y emparejarlo con OpenClaw. Recomendamos añadir tu bot a tu propio servidor privado. Si todavía no tienes uno, crea uno primero (elige Create My Own > For me and my friends).
1

Crear una aplicación de Discord y un bot

Ve al Portal para desarrolladores de Discord 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 uses para tu agente de OpenClaw.
2

Habilitar intents privilegiados

Aún en la página Bot, desplázate hacia abajo hasta Privileged Gateway Intents y habilita:
  • Message Content Intent (obligatorio)
  • Server Members Intent (recomendado; obligatorio para listas de permitidos por rol y coincidencia de nombre a ID)
  • Presence Intent (opcional; solo se necesita para actualizaciones de presencia)
3

Copiar el token de tu bot

Vuelve a subir en la página Bot y haz clic en Reset Token.
A pesar del nombre, esto genera tu primer token; no se está “restableciendo” nada.
Copia el token y guárdalo en algún lugar. Este es tu Bot Token y lo necesitarás en breve.
4

Generar una URL de invitación y añadir 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 hacia abajo hasta OAuth2 URL Generator y habilita:
  • bot
  • applications.commands
Debajo aparecerá una sección Bot Permissions. Habilita:
  • View Channels
  • Send Messages
  • Read Message History
  • Embed Links
  • Attach Files
  • Add Reactions (opcional)
Copia la URL generada al final, pégala en tu navegador, selecciona tu servidor y haz clic en Continue para conectarlo. Ahora deberías ver tu bot en el servidor de Discord.
5

Habilitar el modo desarrollador y recopilar tus ID

De vuelta en la app de Discord, debes habilitar el modo desarrollador para poder copiar IDs internas.
  1. Haz clic en User Settings (icono de engranaje junto a tu avatar) → Advanced → activa Developer Mode
  2. Haz clic derecho en el icono de tu servidor en la barra lateral → Copy Server ID
  3. Haz clic derecho en tu propio avatarCopy User ID
Guarda tu Server ID y User ID junto con tu Bot Token; enviarás los tres a OpenClaw en el siguiente paso.
6

Permitir mensajes directos de miembros del servidor

Para que el emparejamiento funcione, Discord debe permitir que tu bot te envíe mensajes directos. Haz clic derecho en el icono de tu servidorPrivacy Settings → activa Direct Messages.Esto permite que los miembros del servidor (incluidos los bots) te envíen mensajes directos. Mantén esto habilitado si quieres usar mensajes directos de Discord con OpenClaw. Si solo planeas usar canales de servidor, puedes desactivar los mensajes directos después del emparejamiento.
7

Establecer el token de tu bot de forma segura (no lo envíes en el chat)

El token de tu bot de Discord es un secreto (como una contraseña). Establécelo en la máquina que ejecuta OpenClaw antes de enviar mensajes a tu agente.
export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN"
openclaw config set channels.discord.token --ref-provider default --ref-source env --ref-id DISCORD_BOT_TOKEN --dry-run
openclaw config set channels.discord.token --ref-provider default --ref-source env --ref-id DISCORD_BOT_TOKEN
openclaw config set channels.discord.enabled true --strict-json
openclaw gateway
Si OpenClaw ya se está ejecutando como servicio en segundo plano, reinícialo mediante la app OpenClaw para Mac o deteniendo y reiniciando el proceso openclaw gateway run.
8

Configurar OpenClaw y emparejar

Chatea con tu agente de OpenClaw en cualquier canal existente (por ejemplo, Telegram) y díselo. Si Discord es tu primer canal, usa en su lugar la pestaña de CLI / config.
“Ya configuré el token de mi bot de Discord en la configuración. Completa la configuración de Discord con User ID <user_id> y Server ID <server_id>.”
9

Aprobar el primer emparejamiento por mensaje directo

Espera hasta que la gateway esté en ejecución y luego envía un mensaje directo a tu bot en Discord. Responderá con un código de emparejamiento.
Envía el código de emparejamiento a tu agente en tu canal existente:
“Aprueba este código de emparejamiento de Discord: <CODE>
Los códigos de emparejamiento caducan después de 1 hora.Ahora deberías poder chatear con tu agente en Discord mediante mensaje directo.
La resolución del token tiene en cuenta la cuenta. Los valores del token en la configuración tienen prioridad sobre el respaldo por variable de entorno. DISCORD_BOT_TOKEN solo se usa para la cuenta predeterminada. Para llamadas salientes avanzadas (acciones de canal/herramienta de mensajes), se usa un token explícito por llamada para esa llamada. Esto se aplica a acciones de envío y de lectura/sondeo (por ejemplo read/search/fetch/thread/pins/permissions). La política de cuenta y la configuración de reintentos siguen viniendo de la cuenta seleccionada en la instantánea activa del runtime.

Recomendado: configurar un espacio de trabajo de servidor

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

Añadir tu servidor a la lista de permitidos de servidores

Esto permite que tu agente responda en cualquier canal de tu servidor, no solo en mensajes directos.
“Añade mi Server ID de Discord <server_id> a la lista de permitidos de servidores”
2

Permitir respuestas sin @mention

De forma predeterminada, tu agente solo responde en canales de servidor cuando se le menciona con @. En un servidor privado, probablemente quieras que responda a todos los mensajes.
“Permite que mi agente responda en este servidor sin necesidad de que se le mencione con @”
3

Planificar la memoria en canales de servidor

De forma predeterminada, la memoria a largo plazo (MEMORY.md) solo se carga en sesiones de mensajes directos. Los canales de servidor no cargan automáticamente MEMORY.md.
“Cuando haga preguntas en canales de Discord, usa memory_search o memory_get si necesitas contexto a largo plazo de MEMORY.md.”
Ahora crea algunos canales en tu servidor de Discord y empieza a chatear. Tu agente puede ver el nombre del canal, y cada canal obtiene su propia sesión aislada, por lo que puedes configurar #coding, #home, #research o lo que mejor se adapte a tu flujo de trabajo.

Modelo de runtime

  • La gateway es propietaria de la conexión de Discord.
  • El enrutamiento de respuestas es determinista: las respuestas entrantes de Discord vuelven a Discord.
  • De forma predeterminada (session.dmScope=main), los chats directos comparten la sesión principal del agente (agent:main:main).
  • Los canales de servidor usan claves de sesión aisladas (agent:<agentId>:discord:channel:<channelId>).
  • Los mensajes directos de grupo se ignoran de forma predeterminada (channels.discord.dm.groupEnabled=false).
  • Los comandos nativos de barra inclinada se ejecutan en sesiones de comando aisladas (agent:<agentId>:discord:slash:<userId>), mientras siguen llevando CommandTargetSessionKey a la sesión de conversación enrutada.

Canales de foro

Los canales de foro y multimedia de Discord solo aceptan publicaciones en hilos. OpenClaw admite dos formas de crearlos:
  • Envía un mensaje al padre del foro (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 padre del foro 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 padres de foro no aceptan componentes de Discord. Si necesitas componentes, envíalos al propio hilo (channel:<threadId>).

Componentes interactivos

OpenClaw admite contenedores de componentes v2 de Discord para mensajes del agente. Usa la herramienta de mensajes con una carga útil components. Los resultados de interacción 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
De forma predeterminada, los componentes son de un solo uso. Establece components.reusable=true para permitir que botones, selectores y formularios se usen varias veces hasta que caduquen. Para restringir quién puede hacer clic en un botón, establece allowedUsers en ese botón (IDs de usuario de Discord, etiquetas o *). Cuando está configurado, los usuarios que no coincidan reciben una denegación efímera. Los comandos de barra inclinada /model y /models abren un selector interactivo de modelo con menús desplegables de proveedor y modelo, además de un paso Submit. 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 mediante media/path/filePath (archivo único); usa media-gallery para varios archivos
  • Usa filename para reemplazar 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 disparador 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

channels.discord.dmPolicy controla el acceso a mensajes directos (heredado: channels.discord.dm.policy):
  • pairing (predeterminado)
  • allowlist
  • open (requiere que channels.discord.allowFrom incluya "*"; heredado: channels.discord.dm.allowFrom)
  • disabled
Si la política de mensajes directos no está abierta, los usuarios desconocidos se bloquean (o se les solicita emparejamiento en modo pairing).Precedencia en múltiples cuentas:
  • channels.discord.accounts.default.allowFrom se aplica solo a la cuenta default.
  • Las cuentas con nombre heredan channels.discord.allowFrom cuando su propio allowFrom no está definido.
  • Las cuentas con nombre no heredan channels.discord.accounts.default.allowFrom.
Formato de destino de mensajes directos para la entrega:
  • user:<id>
  • mención <@id>
Los ID numéricos sin prefijo son ambiguos y se rechazan a menos que se proporcione un tipo de destino explícito de usuario/canal.

Enrutamiento de agentes basado en roles

Usa bindings[].match.roles para enrutar miembros de servidores de Discord a distintos agentes por ID de rol. Las vinculaciones basadas en rol aceptan solo IDs de rol y se evalúan después de las vinculaciones de par o par padre y antes de las vinculaciones solo de 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 para desarrolladores

  1. Discord Developer Portal -> Applications -> New Application
  2. Bot -> Add Bot
  3. Copia el token del bot
En Bot -> Privileged Gateway Intents, habilita:
  • Message Content Intent
  • Server Members Intent (recomendado)
Presence intent es opcional y solo es obligatorio si quieres recibir actualizaciones de presencia. Configurar la presencia del bot (setPresence) no requiere habilitar actualizaciones de presencia para los miembros.
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 salvo que sea explícitamente necesario.
Habilita Discord Developer Mode y luego copia:
  • ID del servidor
  • ID del canal
  • ID del usuario
Prefiere IDs numéricos en la configuración de OpenClaw para auditorías y sondeos fiables.

Comandos nativos y autenticación de comandos

  • commands.native usa "auto" de forma predeterminada y está habilitado para Discord.
  • Reemplazo por canal: channels.discord.commands.native.
  • commands.native=false borra explícitamente comandos nativos de Discord registrados anteriormente.
  • La autenticació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 que no están autorizados; la ejecución sigue aplicando la autenticación de OpenClaw y devuelve “no autorizado”.
Consulta Slash commands para el catálogo y el comportamiento de los comandos. Configuración predeterminada de comandos de barra inclinada:
  • ephemeral: true

Detalles de funciones

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
  • batched
Nota: off desactiva el encadenamiento implícito de respuestas. Las etiquetas explícitas [[reply_to_*]] siguen respetándose. first siempre adjunta la referencia implícita de respuesta nativa al primer mensaje saliente de Discord del turno. batched solo adjunta la referencia implícita de respuesta nativa de Discord cuando el turno entrante fue un lote con antirrebote de varios mensajes. Esto es útil cuando quieres respuestas nativas principalmente para chats ambiguos con ráfagas, no para cada turno de un solo mensaje.Los IDs de mensaje se muestran en el contexto/historial para que los agentes puedan dirigirse a mensajes concretos.
OpenClaw puede transmitir borradores de respuesta enviando un mensaje temporal y editándolo a medida que llega texto.
  • channels.discord.streaming controla la transmisión de vista previa (off | partial | block | progress, predeterminado: off).
  • El valor predeterminado sigue siendo off porque las ediciones de vista previa de Discord pueden alcanzar rápidamente los límites de tasa, especialmente cuando varios bots o gateways comparten la misma cuenta o tráfico de servidor.
  • progress se acepta por consistencia entre canales y se asigna a partial en Discord.
  • channels.discord.streamMode es un alias heredado y se migra automáticamente.
  • 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 del modo block (limitados a channels.discord.textChunkLimit):
{
  channels: {
    discord: {
      streaming: "block",
      draftChunk: {
        minChars: 200,
        maxChars: 800,
        breakPreference: "paragraph",
      },
    },
  },
}
La transmisión de vista previa es solo de texto; las respuestas con archivos multimedia vuelven a la entrega normal.Nota: la transmisión de vista previa es independiente de la transmisión por bloques. Cuando la transmisión por bloques está explícitamente habilitada para Discord, OpenClaw omite la vista previa para evitar transmisión doble.
Contexto del historial de servidores:
  • channels.discord.historyLimit predeterminado 20
  • respaldo: messages.groupChat.historyLimit
  • 0 desactiva
Controles del 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 el enlace de sesión padre
  • la configuración del hilo hereda la configuración del canal padre, salvo que exista una entrada específica para el hilo
Los temas de canal se inyectan como contexto no confiable (no como prompt del sistema). El contexto de respuestas y mensajes citados actualmente permanece tal como se recibe. Las listas de permitidos de Discord controlan principalmente quién puede activar el agente, no son un límite completo de redacción de contexto suplementario.
Discord puede vincular un hilo a un destino de sesión para que los mensajes posteriores en ese hilo sigan enrutándose a la misma sesión (incluidas 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 ejecuciones activas y estado de la vinculación
  • /session idle <duration|off> inspecciona/actualiza el desenfoque automático por inactividad para vinculaciones enfocadas
  • /session max-age <duration|off> inspecciona/actualiza la antigüedad máxima estricta para vinculaciones enfocadas
Configuración:
{
  session: {
    threadBindings: {
      enabled: true,
      idleHours: 24,
      maxAgeHours: 0,
    },
  },
  channels: {
    discord: {
      threadBindings: {
        enabled: true,
        idleHours: 24,
        maxAgeHours: 0,
        spawnSubagentSessions: false, // activación opcional
      },
    },
  },
}
Notas:
  • session.threadBindings.* establece los valores predeterminados globales.
  • channels.discord.threadBindings.* reemplaza el comportamiento de Discord.
  • spawnSubagentSessions debe ser true para crear/vincular automáticamente hilos para sessions_spawn({ thread: true }).
  • spawnAcpSessions debe ser true para crear/vincular automáticamente hilos para ACP (/acp spawn ... --thread ... o sessions_spawn({ runtime: "acp", thread: true })).
  • Si las vinculaciones de hilos están deshabilitadas para una cuenta, /focus y las operaciones relacionadas no están disponibles.
Consulta Sub-agents, ACP Agents y Configuration Reference.
Para espacios de trabajo ACP estables “siempre activos”, configura vinculaciones ACP tipadas de nivel superior dirigidas 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:
  • /acp spawn codex --bind here vincula el canal o hilo actual de Discord en el lugar y mantiene los mensajes futuros enrutados a la misma sesión ACP.
  • Esto todavía puede significar “iniciar una sesión ACP nueva de Codex”, pero no crea por sí solo un hilo nuevo de Discord. El canal existente sigue siendo la superficie de chat.
  • Codex puede seguir ejecutándose en su propio cwd o espacio de trabajo de backend en disco. Ese espacio de trabajo es estado de runtime, no un hilo de Discord.
  • Los mensajes del hilo pueden heredar la vinculación ACP del canal padre.
  • En un canal o hilo vinculado, /new y /reset restablecen la misma sesión ACP en el lugar.
  • Las vinculaciones temporales de hilos siguen funcionando y pueden reemplazar la resolución de destino mientras estén activas.
  • spawnAcpSessions solo es obligatorio cuando OpenClaw necesita crear/vincular un hilo hijo mediante --thread auto|here. No es obligatorio para /acp spawn ... --bind here en el canal actual.
Consulta ACP Agents para obtener detalles sobre el comportamiento de las vinculaciones.
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.
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
  • respaldo al emoji de identidad del agente (agents.list[].identity.emoji, o ”👀” si no existe)
Notas:
  • Discord acepta emoji unicode o nombres de emoji personalizados.
  • Usa "" para desactivar la reacción para un canal o cuenta.
Las escrituras de configuración iniciadas desde el canal están habilitadas de forma predeterminada.Esto afecta a los flujos /config set|unset (cuando las funciones de comandos están habilitadas).Desactivar:
{
  channels: {
    discord: {
      configWrites: false,
    },
  },
}
Enruta el tráfico WebSocket de la gateway de Discord y las búsquedas REST de inicio (ID de aplicación + resolución de lista de permitidos) mediante un proxy HTTP(S) con channels.discord.proxy.
{
  channels: {
    discord: {
      proxy: "http://proxy.example:8080",
    },
  },
}
Reemplazo por cuenta:
{
  channels: {
    discord: {
      accounts: {
        primary: {
          proxy: "http://proxy.example:8080",
        },
      },
    },
  },
}
Habilita la resolución de PluralKit para asignar mensajes proxificados 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 visibles de miembro coinciden por nombre/slug solo cuando channels.discord.dangerouslyAllowNameMatching: true
  • las búsquedas usan el ID del mensaje original y están limitadas por una ventana temporal
  • si la búsqueda falla, los mensajes proxificados se tratan como mensajes de bot y se descartan salvo que allowBots=true
Las actualizaciones de presencia se aplican cuando estableces un campo de estado o actividad, o cuando habilitas 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 transmisión:
{
  channels: {
    discord: {
      activity: "Live coding",
      activityType: 1,
      activityUrl: "https://twitch.tv/openclaw",
    },
  },
}
Mapa de tipos de actividad:
  • 0: Playing
  • 1: Streaming (requiere activityUrl)
  • 2: Listening
  • 3: Watching
  • 4: Custom (usa el texto de actividad como estado; el emoji es opcional)
  • 5: Competing
Ejemplo de presencia automática (señal de estado de salud del runtime):
{
  channels: {
    discord: {
      autoPresence: {
        enabled: true,
        intervalMs: 30000,
        minUpdateIntervalMs: 15000,
        exhaustedText: "token exhausted",
      },
    },
  },
}
La presencia automática asigna la disponibilidad del runtime al estado de Discord: healthy => online, degraded o unknown => idle, exhausted o unavailable => dnd. Reemplazos de texto opcionales:
  • autoPresence.healthyText
  • autoPresence.degradedText
  • autoPresence.exhaustedText (admite el marcador {reason})
Discord admite manejo de aprobaciones con botones en mensajes directos y puede, de forma opcional, publicar solicitudes de aprobación en el canal de origen.Ruta de configuración:
  • channels.discord.execApprovals.enabled
  • channels.discord.execApprovals.approvers (opcional; usa commands.ownerAllowFrom como respaldo cuando es posible)
  • channels.discord.execApprovals.target (dm | channel | both, predeterminado: dm)
  • agentFilter, sessionFilter, cleanupAfterResolve
Discord habilita automáticamente las aprobaciones nativas de ejecución cuando enabled no está definido o es "auto" y al menos un aprobador puede resolverse, ya sea desde execApprovals.approvers o desde commands.ownerAllowFrom. Discord no infiere aprobadores de ejecución desde allowFrom del canal, dm.allowFrom heredado ni defaultTo de mensajes directos. Establece enabled: false para desactivar Discord explícitamente como cliente de aprobación nativo.Cuando target es channel o both, la solicitud de aprobación es visible en el canal. Solo los aprobadores resueltos pueden usar los botones; otros usuarios reciben una denegación efímera. Las solicitudes de aprobación incluyen el texto del comando, así que habilita la entrega en canal solo en canales de confianza. Si el ID del canal no puede derivarse de la clave de sesión, OpenClaw vuelve a la entrega por mensaje directo.Discord también renderiza los botones de aprobación compartidos usados por otros canales de chat. El adaptador nativo de Discord añade principalmente enrutamiento por mensaje directo para aprobadores y difusión al canal. Cuando esos botones están presentes, son la experiencia principal de aprobación; OpenClaw solo debería incluir un comando manual /approve cuando el resultado de la herramienta indique que las aprobaciones por chat no están disponibles o que la aprobación manual es la única vía.La autenticación de gateway para este manejador usa el mismo contrato compartido de resolución de credenciales que otros clientes de Gateway:
  • autenticación local con prioridad a entorno (OPENCLAW_GATEWAY_TOKEN / OPENCLAW_GATEWAY_PASSWORD y luego gateway.auth.*)
  • en modo local, gateway.remote.* puede usarse como respaldo solo cuando gateway.auth.* no está configurado; los SecretRef locales configurados pero no resueltos fallan en modo cerrado
  • soporte de modo remoto mediante gateway.remote.* cuando corresponda
  • los reemplazos de URL son seguros para reemplazo: los reemplazos de CLI no reutilizan credenciales implícitas, y los reemplazos de entorno usan solo credenciales del entorno
Comportamiento de resolución de aprobación:
  • Los IDs con prefijo plugin: se resuelven mediante plugin.approval.resolve.
  • Otros IDs se resuelven mediante exec.approval.resolve.
  • Discord no realiza aquí un salto adicional de respaldo de exec a plugin; el prefijo del ID decide qué método de gateway llama.
Las aprobaciones de ejecución caducan después de 30 minutos de forma predeterminada. Si las aprobaciones fallan con IDs de aprobación desconocidos, verifica la resolución de aprobadores, la habilitación de funciones y que el tipo de ID de aprobación entregado coincida con la solicitud pendiente.Documentación relacionada: Exec approvals

Herramientas y controles 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
La acción event-create acepta un parámetro image opcional (URL o ruta de archivo local) para establecer la imagen de portada del evento programado. Los controles de acciones están en channels.discord.actions.*. Comportamiento predeterminado de los controles:
Grupo de accionesPredeterminado
reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissionshabilitado
rolesdeshabilitado
moderationdeshabilitado
presencedeshabilitado

Interfaz Components v2

OpenClaw usa Discord components v2 para aprobaciones de ejecución y marcadores entre contextos. Las acciones de mensajes de Discord también pueden aceptar components para una interfaz personalizada (avanzado; requiere construir una carga útil de componentes mediante la herramienta de Discord), mientras que los embeds heredados siguen estando disponibles, pero no se recomiendan.
  • channels.discord.ui.components.accentColor establece el color de acento usado por los contenedores de componentes de Discord (hex).
  • Establécelo por cuenta con channels.discord.accounts.<id>.ui.components.accentColor.
  • embeds se ignoran cuando hay components 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 adjuntos de mensajes de voz. Requisitos:
  • Habilita comandos nativos (commands.native o channels.discord.commands.native).
  • Configura channels.discord.voice.
  • El bot necesita permisos Connect + Speak en el canal de voz de destino.
Usa el comando nativo exclusivo de Discord /vc join|leave|status para controlar 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 unión automática:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        autoJoin: [
          {
            guildId: "123456789012345678",
            channelId: "234567890123456789",
          },
        ],
        daveEncryption: true,
        decryptionFailureTolerance: 24,
        tts: {
          provider: "openai",
          openai: { voice: "alloy" },
        },
      },
    },
  },
}
Notas:
  • voice.tts reemplaza messages.tts solo para la reproducción de voz.
  • Los turnos de transcripción de voz derivan el estado de propietario desde 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á habilitada de forma predeterminada; 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 supervisa los fallos de descifrado de recepción y se recupera automáticamente saliendo y volviendo a unirse 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 error 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 que ffmpeg y ffprobe estén disponibles en el host de la 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 la misma carga útil).
  • Se acepta cualquier formato de audio; OpenClaw 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

  • habilita Message Content Intent
  • habilita Server Members Intent cuando dependas de la resolución de usuario/miembro
  • reinicia la gateway después de cambiar intents
  • verifica groupPolicy
  • verifica la lista de permitidos del servidor en channels.discord.guilds
  • si existe el mapa guild.channels, solo se permiten los canales listados
  • verifica el comportamiento de requireMention y los patrones de mención
Comprobaciones útiles:
openclaw doctor
openclaw channels status --probe
openclaw logs --follow
Causas comunes:
  • groupPolicy="allowlist" sin una lista de permitidos de servidor/canal que coincida
  • requireMention configurado en el lugar equivocado (debe estar en channels.discord.guilds o en la entrada del canal)
  • remitente bloqueado por la lista de permitidos users del servidor/canal
Registros típicos:
  • Listener DiscordMessageListener timed out after 30000ms for event MESSAGE_CREATE
  • Slow listener detected ...
  • discord inbound worker timed out after ...
Ajuste del presupuesto del listener:
  • cuenta única: channels.discord.eventQueue.listenerTimeout
  • múltiples cuentas: channels.discord.accounts.<accountId>.eventQueue.listenerTimeout
Ajuste del tiempo límite de ejecución del worker:
  • cuenta única: channels.discord.inboundWorker.runTimeoutMs
  • múltiples cuentas: channels.discord.accounts.<accountId>.inboundWorker.runTimeoutMs
  • predeterminado: 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 una configuración lenta del listener y inboundWorker.runTimeoutMs solo si quieres una válvula de seguridad independiente para turnos del agente en cola.
Las comprobaciones de permisos de channels status --probe solo funcionan con IDs numéricos de canal.Si usas claves slug, la coincidencia en runtime aún puede funcionar, pero el sondeo no puede verificar completamente los permisos.
  • mensajes directos deshabilitados: channels.discord.dm.enabled=false
  • política de mensajes directos deshabilitada: channels.discord.dmPolicy="disabled" (heredado: channels.discord.dm.policy)
  • esperando aprobación de emparejamiento en modo pairing
De forma predeterminada, los mensajes creados por bots se ignoran.Si estableces channels.discord.allowBots=true, usa reglas estrictas de mención y lista de permitidos para evitar comportamientos en bucle. Prefiere channels.discord.allowBots="mentions" para aceptar solo mensajes de bot que mencionen al bot.
  • mantén OpenClaw actualizado (openclaw update) para que esté presente la lógica de recuperación de recepción de voz de Discord
  • confirma channels.discord.voice.daveEncryption=true (predeterminado)
  • empieza con channels.discord.voice.decryptionFailureTolerance=24 (valor predeterminado upstream) y ajústalo 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 volver a unirse automáticamente, recopila registros y compáralos con discord.js #11419

Punteros de referencia de configuración

Referencia principal: Campos de Discord de alta señal:
  • inicio/autenticación: enabled, token, accounts.*, allowBots
  • política: groupPolicy, dm.*, guilds.*, guilds.*.channels.*
  • comandos: 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
  • transmisión: streaming (alias heredado: streamMode), draftChunk, blockStreaming, blockStreamingCoalesce
  • multimedia/reintentos: mediaMaxMb, retry
    • mediaMaxMb limita las subidas salientes a Discord (predeterminado: 100MB)
  • 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 de bot como secretos (DISCORD_BOT_TOKEN es lo preferido en entornos supervisados).
  • Otorga permisos de Discord con privilegios mínimos.
  • Si el despliegue/estado de comandos está desactualizado, reinicia la gateway y vuelve a comprobar con openclaw channels status --probe.

Relacionado