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.
- Emparejamiento — Los mensajes directos de Slack usan modo de emparejamiento por defecto.
- Comandos slash — Comportamiento de comandos nativos y catálogo de comandos.
- Solución de problemas de canales — Diagnóstico y playbooks de reparación entre canales.
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+appTokenson 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_TOKENsolo 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.customizesi quieres que los mensajes salientes usen la identidad del agente activo (nombre de usuario e icono personalizados).icon_emojiusa 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: falsey 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 globalcommands.native: true). - Cuando los comandos nativos están activados, registra los comandos slash correspondientes en Slack (
/<command>), con una excepción:- registra
/agentstatuspara el comando de estado (Slack reserva/status)
- registra
- 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: falsename: "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 comochannel; los MPIMs comogroup. - Con
session.dmScope=mainpor 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.historyScopepor defecto esthread;thread.inheritParentpor defecto esfalse.channels.slack.thread.initialHistoryLimitcontrola cuántos mensajes existentes del hilo se obtienen cuando se inicia una nueva sesión de hilo (por defecto20; establece0para desactivar).
Controles de hilos de respuesta:
channels.slack.replyToMode:off|first|all(por defectooff)channels.slack.replyToModeByChatType: pordirect|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:
| Grupo | Predeterminado |
|---|---|
| messages | activado |
| reactions | activado |
| pins | activado |
| memberInfo | activado |
| emojiList | activado |
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.setStatusy requieren el scope del botassistant:write. channel_id_changedpuede migrar claves de configuración de canal cuandoconfigWritesestá 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_submissionyview_closedcon metadatos de canal enrutado e inputs de formulario
- acciones de bloque: valores seleccionados, etiquetas, valores de picker y metadatos
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>.ackReactionchannels.slack.ackReactionmessages.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>.typingReactionchannels.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 achannels.slack.streaming.- boolean
channels.slack.streamingse auto-migra achannels.slack.nativeStreaming.
Requisitos
- Activa Agents and AI Apps en la configuración de tu app de Slack.
- Asegúrate de que la app tenga el scope
assistant:write. - 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
- modo/auth: