Guía 05

Cómo crear un bot de Slack: scopes, Events API, Socket Mode y Block Kit

Los bots de Slack viven dentro de empresas, así que la confianza lo es todo. Pide pocos scopes, verifica cada petición y responde en menos de tres segundos.

Guía3 min de lecturaActualizado

Crear la app desde un manifiesto

En api.slack.com/apps elige Create New App, From a manifest. Un manifiesto mantiene la configuración bajo control de versiones:

display_information:
  name: Deploy Helper
  description: Publica el estado de los despliegues y ejecuta rollbacks aprobados
features:
  bot_user: { display_name: deploy-helper, always_online: false }
  slash_commands:
    - command: /deploy
      description: Ver o lanzar despliegues
      usage_hint: "status | rollback <servicio>"
      should_escape: false
oauth_config:
  scopes:
    bot: [app_mentions:read, chat:write, commands]
settings:
  event_subscriptions:
    bot_events: [app_mention]
  interactivity: { is_enabled: true }
  socket_mode_enabled: true

Instala la app en tu espacio de trabajo para obtener un bot token (xoxb-...). Copia el signing secret de Basic Information.

Scopes: pide menos

Los scopes definen qué puede hacer el token. chat:write publica mensajes; app_mentions:read recibe menciones; commands habilita comandos slash. Evita scopes amplios como channels:history o users:read.email salvo que una función los necesite de verdad: los administradores revisan los scopes antes de aprobar apps, y cada scope es un riesgo si el token se filtra.

Recibir eventos

Events API por HTTP. Slack envía los eventos por POST a tu Request URL. Al configurarla, Slack manda un payload url_verification: responde con su challenge. Cada petición debe confirmarse con 200 en 3 segundos; si no, Slack reintenta hasta tres veces con las cabeceras X-Slack-Retry-Num y X-Slack-Retry-Reason. Deduplica por event_id.

Socket Mode. Tu app abre un WebSocket con Slack usando un app-level token (xapp-..., scope connections:write). No hace falta URL pública, ideal para herramientas internas detrás de un cortafuegos o para desarrollo local. Igualmente confirmas cada sobre.

Verifica cada petición HTTP

Slack firma las peticiones con tu signing secret. Calcula v0= + HMAC-SHA256 de v0:{X-Slack-Request-Timestamp}:{cuerpo crudo} y compáralo con X-Slack-Signature en tiempo constante. Rechaza marcas de tiempo de más de cinco minutos para bloquear repeticiones. Bolt lo hace por ti; el probador de webhooks tiene un modo Slack para depurar.

Una app con Bolt

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

const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  appToken: process.env.SLACK_APP_TOKEN,   // token xapp- para Socket Mode
  socketMode: true,
});

app.command("/deploy", async ({ command, ack, respond }) => {
  await ack();                                       // confirma en menos de 3 s
  const [action, service] = command.text.trim().split(/\s+/);
  if (action === "status") return respond(await deployStatus());
  if (action === "rollback" && service) {
    return respond({
      response_type: "ephemeral",
      blocks: [
        { type: "section", text: { type: "mrkdwn", text: `¿Revertir *${service}* a la versión anterior?` } },
        { type: "actions", elements: [
          { type: "button", text: { type: "plain_text", text: "Revertir" }, style: "danger", action_id: "rollback", value: service },
          { type: "button", text: { type: "plain_text", text: "Cancelar" }, action_id: "cancel" } ] },
      ],
    });
  }
  return respond("Uso: /deploy status | rollback <servicio>");
});

app.action("rollback", async ({ ack, body, action, respond }) => {
  await ack();
  if (!(await isOnCall(body.user.id))) return respond("Solo la persona de guardia puede revertir.");
  await rollback(action.value, { requestedBy: body.user.id });
  await respond(`Rollback de ${action.value} iniciado por <@${body.user.id}>.`);
});

await app.start();

Fíjate en la comprobación de autorización dentro del manejador de la acción: cualquiera que vea un botón puede pulsarlo.

Block Kit

Los mensajes, modales y la pestaña App Home se construyen con bloques: secciones, acciones, entradas, contexto, separadores. Haz prototipos en el Block Kit Builder. Incluye siempre un text de respaldo para notificaciones y lectores de pantalla.

Límites de tasa

Los métodos de la Web API se agrupan en niveles, desde Tier 1 (aprox. una petición por minuto) hasta Tier 4 (más de 100 por minuto). chat.postMessage tiene un límite especial de aproximadamente un mensaje por segundo por canal, con ráfagas cortas permitidas. Ante un 429 lee la cabecera Retry-After. Para avisos masivos, encola y distribuye.

Distribución

Las apps internas se instalan en un solo espacio de trabajo. Para que otros instalen la tuya, activa la distribución e implementa el flujo OAuth, guardando un token por espacio de trabajo (cifrado en reposo). Publicar en el Slack Marketplace requiere una revisión de seguridad, una política de privacidad y un contacto de soporte.

Comprueba lo aprendido

1. ¿Qué cadena firma Slack?
2. ¿Qué deja de ser necesario con Socket Mode?