Mi primer bot en Slack

Slack es una herramienta de comunicación de equipos muy utilizada tanto en proyectos abiertos como en entornos laborales. Aunque las comunidades que conozco lo han ido abandonando por otras soluciones más ligeras, creo que la presencia en entornos labores es aún muy importante.

Entre las características típicas de mensajería de uno a uno, en grupo, canales, videollamadas, etc se añade un ecosistema de aplicaciones muy amplio. Permite integrar procesos propios de la empresa en él de tal forma que podamos crear nuestras propias aplicaciones que actúen como un miembro más del equipo reaccionando ante eventos, escribiendo en los canales, etc.

En este post voy a explicar de forma resumida cómo podemos hacer un bot que responda a un comando enviado por los usuarios. En Internet hay tutoriales muy completos y la propia documentación de Slack es bastante extensa con ejemplos y herramientas de testeo, por lo que aquí vamos a ver algo muy sencillo pero que podrás instalar y adaptar en el workspace de vuestro slack (si tenéis permisos para ello)

Por otra parte, como el bot tiene que ejecutarse en algún sitio, voy a contar cómo podemos usar Netlify para alojarlo. Netlify proporciona diferentes tipos de cuenta donde alojar tus proyectos, siendo la gratuita muy interesante:

  • ilimitados proyectos de contenido estático

  • integración con los principales repositorios (Github, Gitlab,…​)

  • despliegues automáticos (o manuales con posibilidad de revisión previa)

  • ejecución de funciones Serverless (Lambdas de Amazon) 125.000 al mes

  • formularios inteligentes (ni idea, no los he probado todavía)

Así pues para este post vamos a necesitar:

  • Una cuenta en Netlify, la gratuita nos sirve de sobra

  • Un workspace en Slack (prueba primero en un workspace nuevo y si te mola instalas el bot en el de la empresa)

  • Node para desarrollar.

    INFO

    Como bola extra podríamos enlazar la cuenta de Netlify con nuestra cuenta en Gitlab/Github para desplegar automáticamente cuando actualicemos el repo. Por ahora lo haremos manualmente)

Además para desarrollar en nuestro local vamos a tener instalado npm y el cli de Netlify netlify-cli (https://docs.netlify.com/cli/get-started/)

Por último ngrok es una herramienta muy útil para probar en local nuestro bot antes de subirlo a producción. La cuenta gratuita es suficiente, con el único inconveniente de que cada vez que mates el proceso ngrok te cambia la url y tienes que reconfigurar en slack donde está tu bot.

Politicamente Correcto Bot

El bot a desarrollar es realmente sencillo y servirá para que ante solicitudes por parte de algún compañero para realizar alguna tarea podamos soltar un exabrupto y que el bot nos lo cambie por una frase políticamente correcta.

Básicamente cuando escribamos el comando /hastalapolla (o el que quieras implementar) el bot se activará y en lugar de este comando se mandará al canal una frase más adecuada seleccionada aleatoriamente de una lista de candidatas.

La utilidad del bot es más bien poca salvo para servir como punto de partida de algunas funcionalidades más complejas que se te puedan ocurrir

Así mismo debido a la simplicidad del bot no requeriremos de ninguna librería ni framework extra de las existentes.

Arquitectura

Entorno

Debemos asegurarnos que tenemos npm instalado:

npm -v

así como que hemos instalado el cliente de Netlify:

netlify -v

y hemos hecho login a nuestra cuenta con él

netlify login

Creando proyecto

En un directorio limpio inicializaremos el proyecto:

npm init

proporcionando un nombre, version, etc por defecto (si vas publicar el código tal vez sí te interese rellenar esta parte más detenidamente)

con lo que tendremos un fichero package.json parecido a:

package.json
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

así mismo crearemos un subdirectorio public donde crearemos un fichero index.html con el contenido que quieras (si quieres hacer un landing page para tu bot, este es tu directorio)

  1. public/index.html

<html><body>HastaLaPolla Slack bot</body></html>

Y por último crearemos un fichero netlify.toml para configurar a netlify:

netlify.toml
[build]
  functions = "functions"
  publish = "public"

Ejecutaremos netlify para comprobar que tenemos la infra preparada

netlify dev

lo cual nos abrirá la página index.html en un navegador

Paramos el proceso y procedemos a crear la función para nuestro bot

Function

Crearemos nuestra primera función

netlify function:create

  • seleccionamos hello-world (total, luego lo vamos a cambiar por nuestro código)

  • como nombre especificaremos hastalapolla

lo cual nos creará un subdirectorio y un fichero JS en él

y procedemos a probar de nuevo que vamos bien

netlify dev

y desde el navegador accederemos a http://localhost:8888/.netlify/functions/hastalapolla

Ngrok

Una vez que te hayas creado una cuenta en ngrok y descargado el ejecutable podemos crear un tunel entre el netlify que está corriendo en tu máquina con el mundo exterior:

ngrok http PUERTO_NETLIFY_FUNCTION

WARNING

Como no estoy seguro que Netlify siempre escuche en el mismo puerto para ejecutar las funciones te toca revisar el que te muestre a tí. En mi caso es el 37947

ngrok te muestra dos URLs (http y https) que son diferentes cada vez que lo ejecutes. Copia la direccion https y prueba a cambiarla por localhot:8888 en la prueba anterior, por ejempo https://a9123123xxxxx.ngrok.io/.netlify/functions/hastalapolla

Slack

Ahora avanzaremos un poco por el lado de Slack.

INFO

Lo mejor es crearse un workspace en blanco donde poder instalar y depurar el bot antes de intentarlo en el de la empresa.

App

Lo primero que haremos será crear una App desde https://api.slack.com/apps donde deberemos indicar el nombre y workspace donde queremos crearla.

WARNING

Desconozco todas las funcionalidades que ofrece una App de Slack (espero irlas descubriendo) pero para este bot vamos a necesitar lo mínimo

Command

Nuestro bot es tan simple que lo único que va a hacer (por ahora) es reaccionar a un comando /hastalapolla por lo que lo daremos de alta en la seccion Slash Commands y rellenaremos los campos que nos pide:

hastalapolla1
Figure 1. formulario.png

En Request URL prestaremos especial atención para poner la URL que nos generó ngrok (la https)

Workspace

Una vez configurado el comando podemos proceder a probarlo desde el workspace donde lo hemos instalado, por ejemplo ejecutando el comando en el canal #random

/hastalapolla

Si todo está bien configurado, Slack nos debería ir completando el comando según lo escribes y se enviaría al canal tal cual

Hastalapolla

Es hora de añadir un poco de código a nuestra function

WARNING

No cortes ngrok o te tocará volver a lanzarlo y reconfigurar la URL en Slack

Sustituiermos la funcion hastalapolla.js por esta:

const querystring = require("querystring");  (1)
const axios = require("axios");

const { SLACK_BOT_TOKEN } = process.env; (2)

const list = [
  ':thumbsup: no te preocupes, ahora mismo me pongo con ello',
  'vale, termino una cosa :watch: y me pongo con ello asap',
  'uff, bueno, lo miro y te digo algo',
  'ahora mismo me pillas un poco ocupado, pero en cuanto pueda te cuento',
  'Genial, no te preocupes, ya te cuento luego',
]

const handler = async (event) => {

  if (event.httpMethod !== "POST") {
    return { statusCode: 405, body: "Method Not Allowed" };
  }

  const params = querystring.parse(event.body);

  const selected = list[Math.floor(Math.random() * list.length)]; (3)

  const data = {
    text: selected,
    channel: params.channel_id,
    as_user: true
  };

  const result = await axios.post('https://slack.com/api/chat.postMessage', data, { (4)
    headers:{
      'Authorization': `Bearer ${SLACK_BOT_TOKEN}`,
      'X-Slack-User': params.user_id
    }
  })

  return {
    statusCode: 200 (5)
  }
}

module.exports = { handler }
1 Las únicas dependencias que usaremos
2 No hemos visto todavia el token ni para que sirve, lo haremos a continuación
3 La frase aleatoria a enviar
4 Con un "simple" post enviaremos la frase políticamente correcta al canal en nombre del usuario
5 con un 200 le decimos a Slack que hemos ejecutado su comando. Si añades texto lo leerá el sólo el usuario

Como puedes ver son 15 líneas excasas de Javascript donde lo más interesante es que utilizamos un paquete de node muy popular para enviar el post (podíamos haberlo hecho usando puro node)

Simplemente instalaremos las dependencias indicadas:

npm install --save axios

npm install --save querystring

lo cual nos modifica nuestro package.json tal que:

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^0.21.0",
    "querystring": "^0.2.0"
  }
}

Y podremos probar de nuevo a enviar el comando desde nuestro workspace de Slack. Si todo va bien NO veremos NADA en el canal mientras que en la consola donde está corriendo Netlify veremos que ha llegado la petición.

Simplemente es que estamos intentando enviar un mensaje a un canal sin estar autentificados.

Token

Para que el bot pueda escribir en un canal hay que darle permisos. Para ello iremos a "OAuth&Permissions" y añadiremos los scopes que muestra la imagen (como bot los scopes chat:write y commands y como user chat:write)

hastalapolla2
Figure 2. scopes.png

Así mismo copiaremos el token de bot que se nos muestra al principio xoxb-XXXXXXXXXXXXXXXXXXXXXx

Vamos a proceder a ejecutar de nuevo la consola de netlify pero ahora proporcionandole el token copiado para que el bot pueda escribir en el canal. (Desconozco cómo se hace en Window$)

SLACK_BOT_TOKEN=xoxb-XXXXXXXXXXX netlify dev

Seguramente tendrás que reconfigurar de nuevo ngrok y la consola de la app con la nueva url generada. Ten en cuenta que esto es así porque vamos paso a paso incrementando la aplicación, una vez lo tengamos todo no sería necesario más que una vez.

Y probamos de nuevo a enviar el comando /hastalapolla

Si todo ha ido bien ahora tendremos un mensaje políticamente correcto en el canal.

Deploy

Es hora de subir nuestra aplicación a Netlify y dejar que se ejecute en la capa gratuita (recuerda, tienes hasta 125K llamadas al mes)

netlify deploy

y crearemos un nuevo site donde desplegar la aplicacion. Netlify elegirá un nombre aleatorio lo cual es bueno para nuestro bot, aunque si lo prefieres luego lo puedes cambiar por otro que este libre.

Simplemente resta configurar el nuevo site creado con la variable SLACK_BOT_TOKEN para lo que desde la consola de Netlify iremos a build, environment y crearemos la variable con el valor del token (de la misma forma que hicimos por consola en el paso anterior)

Una vez configurado deberemos realizar un nuevo deploy para que tome la variable creada. Simplemente desde la consola de Netlify iremos a build y seleccionamos redeploy.

Por ultimo sólo resta decirle a Slack dónde encontrar ahora el bot para el comando tal como hacíamos con 'ngrok'

TIP

Yo lo que hago es tener un comando "test" que apunta al entorno local con ngrok y el "oficial" que apunte a Netlify

Si todo ha ido bien, una vez configurado, cada vez que ejecutes el comando /hastalapolla estarás invocando a la función alojada en Netlify por lo que no necesitas ya tu entorno de desarrollo levantado.

Bola extra

Puedes alojar tu proyecto en un repot git en Gitlab o Github y "enlazarlo" con Netlify de tal forma que cada vez que hagas un push se despliegue automáticamente, pero eso es para otro post (Si estás interesado simplemente comentamelo y lo vemos)

Follow comments at Telegram groupOr subscribe to the Channel Telegram channel

2019 - 2020 | Mixed with Bootstrap | Baked with JBake v2.6.5