En Swapps, diariamente usamos Slack para comunicarnos con los demás miembros del equipo de trabajo; desde para dar un buenos días, hasta para notificar una situación de mucha relevancia. Debido a que Slack es una aplicación que usamos constantemente, hemos integrado diferentes notificaciones a esta herramienta; de forma que, por ejemplo, en cuestión de segundos sabemos si un sitio se ha caído, o si los tests de un pull request han fallado.

Slack permite crear aplicaciones que pueden ser integradas a los canales de conversación. Como anteriormente lo mencioné, estas aplicaciones pueden ser sencillas notificaciones enviadas cuando ocurre un evento en una aplicación externa o aplicaciones que permiten leer y responder mensajes o conversaciones usando Bots. Un Bot es un tipo de aplicación de Slack diseñada para interactuar con los usuarios a través de una conversación. Se pueden construir con eventos o con Real Time Messaging, RTM.

Vamos a crear nuestro pequeño Bot, al que vamos a saludar  y él nos responderá. Para este ejemplo usaremos la suscripción a eventos.

Creamos la APP de slack:

Creamos el usuario Bot

Instalamos la aplicación en el ambiente de trabajo

Después de instalada, copiamos el Bot User OAuth Access Token y el Token de Verificación,  que se encuentra en las credenciales de información básica, y lo guardamos para utilizarlas posteriormente en nuestra aplicación de Python.

Crear el recurso en nuestra Aplicación Python

Antes de activar la suscripción a eventos, debemos crear en nuestra App de python el recurso al que Slack hará las solicitudes.

Slack requiere confirmar que el recurso funcione correctamente. Para este fin, Slack envía una petición con un JSON similar al del  siguiente ejemplo y espera, como respuesta, el valor de “challenge”; que debemos retornar desde nuestra app de Python.

{
    "token": "Jhj1dZrFaK1ZwHjjRyZWjbDl",
    "challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P",
    "type": "url_verification"
}

La app del ejemplo se montó usando Django, pero puede montarse usando otra herramienta similar como Flask, adicionalmente usamos el cliente de Slack para Python:

Se instala la librería con el siguiente comando:

Pip install slackclient

Para inicializar el cliente usamos el token previamente añadido en nuestra App:

from slack import WebClient

class SlackBotTest(object):
   def __init__(self, request):
       self.Client = WebClient(<SLACK_BOT_USER_TOKEN>)
       self.slack_message = request.data
       self.user = None
       self.channel = None

Debemos retornar el mismo atributo challenge, adicionalmente es recomendable validar que el token que recibimos sea el mismo que hemos guardado.

if self.slack_message.get("token") != <SLACK_VERIFICATION_TOKEN>:
           return {"status": HTTP_403}
 # verification challenge
 if self.slack_message.get("type") == "url_verification":
           return self.slack_message.get("challenge")

Activamos la suscripción de eventos

El anterior código lo retornamos en un recurso que creamos “api/slack-events-test”, ingresamos la URL y con la URL verificada podemos continuar configurando la suscripción de eventos. La aplicación Python está desarrollada localmente, para que Slack pueda hacer la solicitud desde afuera he expuesto mi instancia local al acceso público usando ngrok.

En la misma configuración, debemos escoger el evento en que el Bot va a responder, el Evento: message.im, que significa que podemos interactuar con él, cuando mencionemos al bot en el canal directo.

Al final guardamos los cambios. En este momento, ya tenemos configurado el Bot usando suscripción de eventos; solo nos resta implementar la lógica para que el Bot salude.

Al código que tenemos creado, añadimos la lógica para obtener el texto que viene de Slack. En caso de que contenga  la palabra “hello”, procedemos a retornar la respuesta a Slack, con el método api_call():

from slack import WebClient

class SlackBotTest(object):
   def __init__(self, request):
       self.Client = WebClient(<SLACK_BOT_USER_TOKEN>)
       self.slack_message = request.data
       self.user = None
       self.channel = None

if self.slack_message.get("token") != <SLACK_VERIFICATION_TOKEN>:
           return {"status": status.HTTP_403_FORBIDDEN}
 # verification challenge
 if self.slack_message.get("type") == "url_verification":
           return self.slack_message.get("challenge")
if "event" in self.slack_message:
           event_message = self.slack_message.get("event")
           self.user = event_message.get("user")
           self.channel = event_message.get("channel")
           if "hello" in event_message.get("text"):
               self.salute()

           return {"status": HTTP_200}

En el método salute() creamos la respuesta y la enviamos:

def salute(self):
       bot_text = "Hi  <@{}> :wave:".format(self.user)
       self.api_call(bot_text)

Y finalmente hacemos uso del método api_call() del cliente de Slack, para enviar la respuesta:

def api_call(self, bot_text):
       self.Client.api_call(
           "chat.postMessage",
           json={
               "channel": self.channel,
               "text": bot_text,
           },
       )
       return {"status": status.HTTP_200_OK}

Para probar nuestro pequeño Bot, lo buscamos en nuestro ambiente de trabajo:

Y le escribimos:

Si queremos que nuestro Bot sea muy inteligente y sofisticado podemos agregar procesamiento de lenguaje natural a las respuestas. Sin embargo, utilizando condicionales, podemos tener un resultado bastante bueno. Algunas ideas para usar Slack API pueden ser: integrar un proyecto externo para consultar información importante; recibir alertas cuando el presupuesto de un proyecto se ha excedido; felicitar a los miembros de tu equipo de trabajo por su cumpleaños o por su buen desempeño de manera automática; publicar un post a diferentes redes sociales, etc.

Como hemos visto, construir nuestro Bot ha sido fácil, es bastante útil utilizar las herramientas que Slack nos brinda, ya que podemos mejorar la comunicación de los miembros del equipo, podemos automatizar procesos, prevenir y actuar ante eventualidades, el uso que podemos darle depende de nuestra imaginación y necesidades laborales.


Comentarios