Slack

Estado: listo para producción en mensajes directos + canales vía integraciones de apps de Slack. El modo predeterminado es Socket Mode; el modo HTTP Events API también es compatible.

Configuración rápida

Socket Mode (predeterminado)

  ### Paso 1: Crea la app de Slack y los tokens
    En la configuración de la app de Slack:

    - activa **Socket Mode**
    - crea **App Token** (`xapp-...`) con `connections:write`
    - instala la app y copia el **Bot Token** (`xoxb-...`)


  ### Paso 2: Configura OpenClaw
{
  channels: {
    slack: {
      enabled: true,
      mode: "socket",
      appToken: "xapp-...",
      botToken: "xoxb-...",
    },
  },
}
    Variable de entorno alternativa (solo cuenta predeterminada):
SLACK_APP_TOKEN=xapp-...
SLACK_BOT_TOKEN=xoxb-...
  ### Paso 3: Suscribe eventos de la app
    Suscribe los eventos del bot:

    - `app_mention`
    - `message.channels`, `message.groups`, `message.im`, `message.mpim`
    - `reaction_added`, `reaction_removed`
    - `member_joined_channel`, `member_left_channel`
    - `channel_rename`
    - `pin_added`, `pin_removed`

    También activa la **pestaña de Messages** en App Home para mensajes directos.


  ### Paso 4: Inicia el gateway
openclaw gateway

Modo HTTP Events API

  ### Paso 1: Configura la app de Slack para HTTP

    - establece el modo a HTTP (`channels.slack.mode="http"`)
    - copia el **Signing Secret** de Slack
    - establece las URLs de Event Subscriptions + Interactivity + Slash command Request URL a la misma ruta de webhook (por defecto `/slack/events`)



  ### Paso 2: Configura OpenClaw en modo HTTP
{
  channels: {
    slack: {
      enabled: true,
      mode: "http",
      botToken: "xoxb-...",
      signingSecret: "your-signing-secret",
      webhookPath: "/slack/events",
    },
  },
}
  ### Paso 3: Usa rutas de webhook únicas para HTTP multicuenta
    El modo HTTP por cuenta es compatible.

    Asigna a cada cuenta un `webhookPath` distinto para que los registros no colisionen.

Modelo de tokens

  • botToken + appToken son obligatorios para Socket Mode.
  • El modo HTTP requiere botToken + signingSecret.
  • Los tokens de configuración sobrescriben la alternativa de variable de entorno.
  • Las variables SLACK_BOT_TOKEN / SLACK_APP_TOKEN solo aplican a la cuenta predeterminada.
  • userToken (xoxp-...) es solo de configuración (sin alternativa env) y por defecto tiene comportamiento de solo lectura (userTokenReadOnly: true).
  • Opcional: añade chat:write.customize si quieres que los mensajes salientes usen la identidad del agente activo (nombre de usuario e icono personalizados). icon_emoji usa la sintaxis :emoji_name:.

Consejo: Para acciones/lecturas de directorio, se puede preferir el token de usuario cuando está configurado. Para escrituras, se prefiere el token del bot; las escrituras con token de usuario solo se permiten cuando userTokenReadOnly: false y el token del bot no está disponible.

Control de acceso y enrutamiento

Política de mensajes directos

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

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

Indicadores de mensajes directos:

- `dm.enabled` (por defecto true)
- `channels.slack.allowFrom` (preferido)
- `dm.allowFrom` (legacy)
- `dm.groupEnabled` (mensajes directos de grupo por defecto false)
- `dm.groupChannels` (lista de permitidos MPIM opcional)

Precedencia multicuenta:

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

El emparejamiento en mensajes directos usa `openclaw pairing approve slack <code>`.

Política de canales

`channels.slack.groupPolicy` controla el manejo de canales:

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

La lista de permitidos de canales está bajo `channels.slack.channels` y debe usar IDs de canal estables.

Nota de runtime: si `channels.slack` está completamente ausente (configuración solo por env), el runtime recurre a `groupPolicy="allowlist"` y registra una advertencia (incluso si `channels.defaults.groupPolicy` está establecido).

Resolución de nombre/ID:

- las entradas de la lista de permitidos de canales y mensajes directos se resuelven al iniciar cuando el acceso por token lo permite
- las entradas no resueltas de nombre de canal se mantienen configuradas pero se ignoran para el enrutamiento por defecto
- la autorización entrante y el enrutamiento de canales son ID-first por defecto; la coincidencia directa por nombre/slug requiere `channels.slack.dangerouslyAllowNameMatching: true`

Menciones y usuarios de canal

Los mensajes de canal están controlados por mención por defecto.

Fuentes de mención:

- mención explícita de la app (`<@botId>`)
- patrones regex de mención (`agents.list[].groupChat.mentionPatterns`, alternativa `messages.groupChat.mentionPatterns`)
- comportamiento implícito de respuesta al bot en hilo

Controles por canal (`channels.slack.channels.<id>`; nombres solo vía resolución al iniciar o `dangerouslyAllowNameMatching`):

- `requireMention`
- `users` (lista de permitidos)
- `allowBots`
- `skills`
- `systemPrompt`
- `tools`, `toolsBySender`
- formato de clave `toolsBySender`: `id:`, `e164:`, `username:`, `name:` o comodín `"*"`
  (las claves legacy sin prefijo aún se mapean solo a `id:`)

Comandos y comportamiento slash

  • El modo auto de comandos nativos está desactivado para Slack (commands.native: "auto" no activa los comandos nativos de Slack).
  • Activa los manejadores de comandos nativos de Slack con channels.slack.commands.native: true (o global commands.native: true).
  • Cuando los comandos nativos están activados, registra los comandos slash correspondientes en Slack (/<command>), con una excepción:
    • registra /agentstatus para el comando de estado (Slack reserva /status)
  • Si los comandos nativos no están activados, puedes ejecutar un único comando slash configurado vía channels.slack.slashCommand.
  • Los menús de argumentos nativos ahora adaptan su estrategia de renderizado:
    • hasta 5 opciones: bloques de botones
    • 6-100 opciones: menú de selección estático
    • más de 100 opciones: selección externa con filtrado asíncrono de opciones cuando los manejadores de opciones de interactividad están disponibles
    • si los valores de opciones codificados exceden los límites de Slack, el flujo recurre a botones
  • Para payloads de opciones largos, los menús de argumentos de comandos slash usan un diálogo de confirmación antes de enviar un valor seleccionado.

Respuestas interactivas

Slack puede renderizar controles de respuesta interactivos creados por el agente, pero esta función está desactivada por defecto.

Actívala globalmente:

{
  channels: {
    slack: {
      capabilities: {
        interactiveReplies: true,
      },
    },
  },
}

O actívala solo para una cuenta de Slack:

{
  channels: {
    slack: {
      accounts: {
        ops: {
          capabilities: {
            interactiveReplies: true,
          },
        },
      },
    },
  },
}

Cuando está activada, los agentes pueden emitir directivas de respuesta exclusivas de Slack:

  • [[slack_buttons: Approve:approve, Reject:reject]]
  • [[slack_select: Choose a target | Canary:canary, Production:production]]

Estas directivas se compilan en Slack Block Kit y enrutan los clics o selecciones a través de la ruta existente de eventos de interacción de Slack.

Notas:

  • Esta es UI específica de Slack. Otros canales no traducen las directivas de Slack Block Kit a sus propios sistemas de botones.
  • Los valores de callback interactivos son tokens opacos generados por OpenClaw, no valores escritos por el agente.
  • Si los bloques interactivos generados excederían los límites de Slack Block Kit, OpenClaw recurre a la respuesta de texto original en vez de enviar un payload de bloques inválido.

Configuración predeterminada de comandos slash:

  • enabled: false
  • name: "openclaw"
  • sessionPrefix: "slack:slash"
  • ephemeral: true

Las sesiones slash usan claves aisladas:

  • agent:<agentId>:slack:slash:<userId>

y aún enrutan la ejecución de comandos contra la sesión de conversación destino (CommandTargetSessionKey).

Hilos, sesiones y etiquetas de respuesta

  • Los mensajes directos se enrutan como direct; los canales como channel; los MPIMs como group.
  • Con session.dmScope=main por defecto, los mensajes directos de Slack se unifican en la sesión principal del agente.
  • Sesiones de canal: agent:<agentId>:slack:channel:<channelId>.
  • Las respuestas en hilo pueden crear sufijos de sesión de hilo (:thread:<threadTs>) cuando aplica.
  • channels.slack.thread.historyScope por defecto es thread; thread.inheritParent por defecto es false.
  • channels.slack.thread.initialHistoryLimit controla cuántos mensajes existentes del hilo se obtienen cuando se inicia una nueva sesión de hilo (por defecto 20; establece 0 para desactivar).

Controles de hilos de respuesta:

  • channels.slack.replyToMode: off|first|all (por defecto off)
  • channels.slack.replyToModeByChatType: por direct|group|channel
  • alternativa legacy para chats directos: channels.slack.dm.replyToMode

Etiquetas de respuesta manuales compatibles:

  • [[reply_to_current]]
  • [[reply_to:<id>]]

Nota: replyToMode="off" desactiva todos los hilos de respuesta en Slack, incluyendo las etiquetas explícitas [[reply_to_*]]. Esto difiere de Telegram, donde las etiquetas explícitas se respetan en modo "off". La diferencia refleja los modelos de hilos de las plataformas: los hilos de Slack ocultan mensajes del canal, mientras que las respuestas de Telegram permanecen visibles en el flujo principal del chat.

Medios, fragmentación y entrega

Adjuntos entrantes
Los archivos adjuntos de Slack se descargan de URLs privadas hospedadas en Slack (flujo de solicitud autenticada por token) y se escriben en el almacén de medios cuando la obtención tiene éxito y los límites de tamaño lo permiten.

El límite de tamaño entrante en runtime es por defecto `20MB` a menos que se sobrescriba con `channels.slack.mediaMaxMb`.
Texto y archivos salientes
- los fragmentos de texto usan `channels.slack.textChunkLimit` (por defecto 4000)
- `channels.slack.chunkMode="newline"` activa la división primero por párrafo
- los envíos de archivos usan las API de carga de Slack y pueden incluir respuestas en hilo (`thread_ts`)
- el límite de medios salientes sigue `channels.slack.mediaMaxMb` cuando está configurado; de lo contrario, los envíos del canal usan los valores predeterminados por tipo MIME del pipeline de medios
Destinos de entrega
Destinos explícitos preferidos:

- `user:<id>` para mensajes directos
- `channel:<id>` para canales

Los mensajes directos de Slack se abren vía las API de conversación de Slack al enviar a destinos de usuario.

Acciones y puertas

Las acciones de Slack se controlan con channels.slack.actions.*.

Grupos de acciones disponibles en las herramientas actuales de Slack:

GrupoPredeterminado
messagesactivado
reactionsactivado
pinsactivado
memberInfoactivado
emojiListactivado

Eventos y comportamiento operativo

  • Las ediciones/eliminaciones/difusiones de mensajes en hilos se mapean en eventos del sistema.
  • Los eventos de añadir/eliminar reacciones se mapean en eventos del sistema.
  • Los eventos de unirse/salir de miembros, creación/renombrado de canales, y añadir/eliminar pins se mapean en eventos del sistema.
  • Las actualizaciones de estado de hilos del asistente (para indicadores “está escribiendo…” en hilos) usan assistant.threads.setStatus y requieren el scope del bot assistant:write.
  • channel_id_changed puede migrar claves de configuración de canal cuando configWrites está activado.
  • Los metadatos de tema/propósito del canal se tratan como contexto no confiable y pueden inyectarse en el contexto de enrutamiento.
  • Las acciones de bloque e interacciones de modal emiten eventos del sistema estructurados Slack interaction: ... con campos de payload ricos:
    • acciones de bloque: valores seleccionados, etiquetas, valores de picker y metadatos workflow_*
    • eventos modales view_submission y view_closed con metadatos de canal enrutado e inputs de formulario

Reacciones de confirmación

ackReaction envía un emoji de confirmación mientras OpenClaw procesa un mensaje entrante.

Orden de resolución:

  • channels.slack.accounts.<accountId>.ackReaction
  • channels.slack.ackReaction
  • messages.ackReaction
  • emoji alternativo de identidad del agente (agents.list[].identity.emoji, si no ”👀”)

Notas:

  • Slack espera shortcodes (por ejemplo "eyes").
  • Usa "" para desactivar la reacción para la cuenta de Slack o globalmente.

Reacción de escritura alternativa

typingReaction añade una reacción temporal al mensaje entrante de Slack mientras OpenClaw procesa una respuesta, luego la elimina cuando la ejecución termina. Es una alternativa útil cuando la escritura nativa del asistente de Slack no está disponible, especialmente en mensajes directos.

Orden de resolución:

  • channels.slack.accounts.<accountId>.typingReaction
  • channels.slack.typingReaction

Notas:

  • Slack espera shortcodes (por ejemplo "hourglass_flowing_sand").
  • La reacción es de mejor esfuerzo y la limpieza se intenta automáticamente después de que la respuesta o la ruta de fallo se completen.

Manifiesto y checklist de scopes

Ejemplo de manifiesto de app de Slack
{
  "display_information": {
    "name": "OpenClaw",
    "description": "Slack connector for OpenClaw"
  },
  "features": {
    "bot_user": {
      "display_name": "OpenClaw",
      "always_online": false
    },
    "app_home": {
      "messages_tab_enabled": true,
      "messages_tab_read_only_enabled": false
    },
    "slash_commands": [
      {
        "command": "/openclaw",
        "description": "Send a message to OpenClaw",
        "should_escape": false
      }
    ]
  },
  "oauth_config": {
    "scopes": {
      "bot": [
        "chat:write",
        "channels:history",
        "channels:read",
        "groups:history",
        "im:history",
        "im:read",
        "im:write",
        "mpim:history",
        "mpim:read",
        "mpim:write",
        "users:read",
        "app_mentions:read",
        "assistant:write",
        "reactions:read",
        "reactions:write",
        "pins:read",
        "pins:write",
        "emoji:read",
        "commands",
        "files:read",
        "files:write"
      ]
    }
  },
  "settings": {
    "socket_mode_enabled": true,
    "event_subscriptions": {
      "bot_events": [
        "app_mention",
        "message.channels",
        "message.groups",
        "message.im",
        "message.mpim",
        "reaction_added",
        "reaction_removed",
        "member_joined_channel",
        "member_left_channel",
        "channel_rename",
        "pin_added",
        "pin_removed"
      ]
    }
  }
}
Scopes opcionales de token de usuario (operaciones de lectura)
Si configuras `channels.slack.userToken`, los scopes de lectura típicos son:

- `channels:history`, `groups:history`, `im:history`, `mpim:history`
- `channels:read`, `groups:read`, `im:read`, `mpim:read`
- `users:read`
- `reactions:read`
- `pins:read`
- `emoji:read`
- `search:read` (si dependes de lecturas de búsqueda de Slack)

Solución de problemas

Sin respuestas en canales
Verifica, en orden:

- `groupPolicy`
- lista de permitidos de canales (`channels.slack.channels`)
- `requireMention`
- lista de permitidos `users` por canal

Comandos útiles:
openclaw channels status --probe
openclaw logs --follow
openclaw doctor
Los mensajes directos se ignoran
Verifica:

- `channels.slack.dm.enabled`
- `channels.slack.dmPolicy` (o legacy `channels.slack.dm.policy`)
- aprobaciones de emparejamiento / entradas de lista de permitidos
openclaw pairing list slack
Socket mode no se conecta
Valida los tokens del bot + app y la activación de Socket Mode en la configuración de la app de Slack.
El modo HTTP no recibe eventos
Valida:

- signing secret
- ruta del webhook
- URLs de solicitud de Slack (Events + Interactivity + Slash Commands)
- `webhookPath` único por cuenta HTTP
Los comandos nativos/slash no se activan
Verifica si pretendías:

- modo de comando nativo (`channels.slack.commands.native: true`) con comandos slash correspondientes registrados en Slack
- o modo de comando slash único (`channels.slack.slashCommand.enabled: true`)

También verifica `commands.useAccessGroups` y las listas de permitidos de canal/usuario.

Streaming de texto

OpenClaw admite streaming de texto nativo de Slack vía la API de Agents and AI Apps.

channels.slack.streaming controla el comportamiento de vista previa en vivo:

  • off: desactivar streaming de vista previa.
  • partial (predeterminado): reemplazar el texto de vista previa con la última salida parcial.
  • block: añadir actualizaciones de vista previa fragmentadas.
  • progress: mostrar texto de estado de progreso mientras genera, luego enviar el texto final.

channels.slack.nativeStreaming controla la API de streaming nativa de Slack (chat.startStream / chat.appendStream / chat.stopStream) cuando streaming es partial (por defecto: true).

Desactivar streaming nativo de Slack (mantener comportamiento de vista previa de borrador):

channels:
  slack:
    streaming: partial
    nativeStreaming: false

Claves legacy:

  • channels.slack.streamMode (replace | status_final | append) se auto-migra a channels.slack.streaming.
  • boolean channels.slack.streaming se auto-migra a channels.slack.nativeStreaming.

Requisitos

  1. Activa Agents and AI Apps en la configuración de tu app de Slack.
  2. Asegúrate de que la app tenga el scope assistant:write.
  3. Debe haber un hilo de respuesta disponible para ese mensaje. La selección de hilo sigue replyToMode.

Comportamiento

  • El primer fragmento de texto inicia un stream (chat.startStream).
  • Los fragmentos posteriores se añaden al mismo stream (chat.appendStream).
  • El fin de la respuesta finaliza el stream (chat.stopStream).
  • Los medios y payloads no textuales recurren a la entrega normal.
  • Si el streaming falla a mitad de respuesta, OpenClaw recurre a la entrega normal para los payloads restantes.

Referencia de configuración

Referencia principal:

  • Referencia de configuración - Slack

    Campos clave de Slack:

    • modo/auth: mode, botToken, appToken, signingSecret, webhookPath, accounts.*
    • acceso a MD: dm.enabled, dmPolicy, allowFrom (legacy: dm.policy, dm.allowFrom), dm.groupEnabled, dm.groupChannels
    • toggle de compatibilidad: dangerouslyAllowNameMatching (emergencia; mantén desactivado a menos que sea necesario)
    • acceso a canales: groupPolicy, channels.*, channels.*.users, channels.*.requireMention
    • hilos/historial: replyToMode, replyToModeByChatType, thread.*, historyLimit, dmHistoryLimit, dms.*.historyLimit
    • entrega: textChunkLimit, chunkMode, mediaMaxMb, streaming, nativeStreaming
    • ops/funciones: configWrites, commands.native, slashCommand.*, actions.*, userToken, userTokenReadOnly

Relacionado