Guía11 min

Cómo crear un bot de Slack con IA paso a paso (2026)

Resumen

Un bot de Slack con IA no es un chatbot suelto: es una app con Events API, token xoxb, ack en menos de 3 segundos y respuestas en hilo. Esta guía cubre Socket Mode vs HTTP, Bolt, tools, scopes mínimos y el checklist de producción.

SlackOpenAI
Espacio de trabajo de Slack conectado a un agente de IA que responde en un hilo

Qué resuelve

Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.

Un bot de Slack con IA vive donde el equipo ya trabaja. No compite con Telegram ni con WhatsApp: ahí el usuario es una persona; aquí el usuario es un canal, un hilo y un conjunto de permisos. Si mezclas los tres canales en un solo webhook, empieza por la arquitectura multicanal. Esta guía es un solo canal, hecho bien.

La pieza que más se rompe no es el modelo. Es el contrato de Slack: ack en menos de tres segundos, token de bot (xoxb-), scopes mínimos y respuestas en thread_ts para no ensuciar el canal.

Paso 1: app, bot token y scopes

Crea una Slack app en api.slack.com. Lo que necesitas para un agente de lectura/respuesta:

  1. Bot token (xoxb-). Según la documentación de tokens, representa a la app, no a un usuario. Si desactivan a quien la instaló, el bot sigue instalado.
  2. Scopes de bot, no de usuario, salvo que debas actuar como alguien: chat:write para chat.postMessage, app_mentions:read o channels:history según si responde a menciones o a todo el canal.
  3. Un Signing Secret para verificar que el HTTP viene de Slack. El campo token del payload de Events API está deprecado; no lo uses como autenticación.
  4. Instala la app en un workspace de prueba. El bot no ve canales privados si no lo invitaste.

Guarda SLACK_BOT_TOKEN y SLACK_SIGNING_SECRET como secretos de entorno. Cualquiera con el xoxb- publica como tu bot.

Paso 2: Socket Mode vs HTTP (Events API)

Slack te llama. La Events API entrega un evento por request. Tienes dos transportes:

CriterioSocket ModeHTTP Request URL
URL públicaNoSí, HTTPS
Dónde prototiparLaptop, VPN, red cerradaServerless o VPS
FirewallSale tu procesoSlack entra a ti
ProducciónVálido si el proceso viveEl default en Vercel/Workers
Fallo típicoProceso muerto = bot mudoURL o firma mal configurada

Regla: prototipa con Socket Mode, producción con HTTP. Bolt para JavaScript y Python cubre OAuth, retries y rate limits de ambos; no reinventes el handshake.

En HTTP, Slack espera HTTP 2xx en menos de tres segundos. Si tardas más, el intento falla y reintenta tres veces con backoff. El header x-slack-retry-reason: http_timeout significa exactamente eso: tu servidor pensó en vez de acusar recibo. La doc pide además un success rate ≥ 5% de eventos por 60 minutos; si no, deshabilitan las entregas.

El patrón correcto es ack inmediato y trabajo en cola:

import { App } from "@slack/bolt";

const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  signingSecret: process.env.SLACK_SIGNING_SECRET,
});

app.event("app_mention", async ({ event, say }) => {
  // Bolt acusa el evento solo; no llames al LLM aquí si tarda más de 3 s
  const job = {
    channel: event.channel,
    thread_ts: event.thread_ts ?? event.ts,
    user: event.user,
    text: event.text,
  };
  await enqueue(job); // Redis, SQS, o un worker in-process
  await say({
    text: "Lo miro y te respondo en este hilo.",
    thread_ts: job.thread_ts,
  });
});

Si el LLM cabe en 3 segundos en tu p95, puedes responder inline. El día que una tool tarde 8 s, el mismo código empieza a duplicar respuestas por retry. Diseña el ack primero.

Paso 3: el agente, no el eco

Entre el evento y chat.postMessage vive el agente: system prompt, tools y memoria por conversación. La conversación en Slack no es el canal: es el hilo (thread_ts). Indexa memoria por ${team_id}:${channel}:${thread_ts}.

async function responder(job: Job) {
  const respuesta = await agente.responder({
    conversationId: `${job.channel}:${job.thread_ts}`,
    mensaje: job.text,
    tools: [buscarTicket, crearIssue],
  });

  await slack.chat.postMessage({
    channel: job.channel,
    thread_ts: job.thread_ts,
    text: respuesta.slice(0, 4000), // fallback; Block Kit si hay estructura
  });
}

Tres decisiones ya tomadas: respuesta en hilo (el canal no se llena de ensayos), tools con schema estricto —la mecánica está en la guía de function calling y en tools confiables— y un tope de caracteres. chat.postMessage acepta markdown_text hasta 12.000 caracteres; no mandes el dump del LLM sin recortar.

Flujo: mención en Slack, ack inmediato, cola, agente con tools y respuesta en el hilo

Paso 4: qué escuchar (y qué no)

Empieza por app_mention y mensajes directos al bot. No te suscribas a message.channels en todos los canales públicos el día uno: cada mensaje es un evento, un ack y, si tu filtro falla, una llamada al modelo.

Otras reglas de Slack que sí te van a tocar:

  • El bot no ve un canal hasta que lo invitan (/invite @tu-bot).
  • En hilos, usa el ts del padre, nunca el de una respuesta, como thread_ts.
  • Dedup por event_id. Los retries reenvían el mismo evento; sin idempotencia publicas dos veces.
  • No proceses eventos de tu propio bot (bot_id / subtype: bot_message) o entras en loop.
  • Scopes de usuario (xoxp-) solo si debes actuar como la persona. Para un agente de equipo, bot token basta.

Costos y ruido

Slack no cobra la Events API. El costo es el LLM más el hosting. El riesgo de factura no es el precio por mención: es el canal ruidoso con message.channels y un prompt que reenvía 40 mensajes de contexto. Ventana de 10–20 turnos del hilo, resumen rodante, hechos durables (ticket, repo, owner) fuera del prompt.

Pon dos topes el día uno: máximo de inferencias por hilo por minuto, y máximo de tokens de entrada. Cinco líneas evitan el 95% de las sorpresas.

Checklist de producción

Checklist: firma verificada, ack < 3 s, cola, hilos, scopes mínimos y dedup por event_id

  1. Bot token xoxb- y Signing Secret en entorno, nunca en el repo.
  2. Scopes mínimos: chat:write + el evento que realmente escuchas.
  3. HTTP 2xx en menos de 3 s; LLM y tools después del ack.
  4. Cola + worker; chat.postMessage desde el worker, no desde el handler.
  5. Respuestas con thread_ts del padre.
  6. Dedup por event_id; ignora bot_message.
  7. Memoria por hilo, no por canal.
  8. Topes de turnos/minuto y tokens/mensaje.
  9. Logs con team_id + channel + event_id, sin texto sensible.
  10. Un mensaje de “qué hago / qué no” cuando te mencionan sin tarea.

Preguntas frecuentes

¿Necesito URL pública? No para prototipar: Socket Mode abre el socket desde tu laptop. En producción, HTTP con firma es más simple de operar en serverless.

¿Por qué no uso Incoming Webhooks? Un webhook entra; no lee menciones ni hilos. Para un agente que responde, Events API + chat.postMessage.

¿Puedo usar el mismo código que Telegram? El núcleo del agente sí (prompt, tools, memoria). El adaptador no: Slack exige ack, hilos y scopes. Mezclar canales en un solo handler es el fallo que cubre la guía multicanal.

¿Block Kit o texto? Texto o markdown_text para la v1. Block Kit cuando hay botones de aprobación (cerrar ticket, abrir PR). No diseñes UI el día que todavía no tienes ack estable.

El siguiente paso

Cuando el bot aguante un canal real, añade cola, retries e idempotencia como en la arquitectura de producción. El curso gratuito de instalación recorre el primer agente de punta a punta; el resto de piezas está en el hub de construcción.