Desafíos y Aprendizajes construyendo un Bot de Slack

Juli y Debi nos cuentan su experiencia construyendo un bot de Slack, los obstáculos que se toparon en el camino y la sorpresa que se llevaron por lo simple que puede resultar hacerlo!

Desafíos y Aprendizajes construyendo un Bot de Slack

Para quienes no están familiarizados con Slack, es una aplicación usada comúnmente en las empresas para comunicarse interna y externamente. Tiene muchas funcionalidades e integraciones con otras plataformas como Google Calendar, Google Drive, Trello, Github, etc. Los bots de Slack juegan un papel importante en estas integraciones ya que pueden realizar recordatorios, enviar mensajes, automatizar tareas, entre otras funciones.

Nosotras tuvimos la oportunidad de trabajar en nuestra última etapa del apprenticeship en Jaguar, una aplicación interna de 10Pines que se encarga de administrar todo el Hardware de la empresa. Dado que el equipo de Hardware se comunica mediante Slack, tuvieron la necesidad de acceder a la información de la app de una forma más dinámica. Allí nació la idea de crear un Bot. Nos pareció interesante hacerlo ya que era la primera experiencia investigando y desarrollando algo totalmente nuevo.

Primeros pasos


Nuestro primer objetivo como desarrolladoras era investigar esta nueva tecnología y crear un bot que nos salude. Esto es lo que se conoce como un Spike, una tarea más relacionada con conocer las herramientas con las que se va a trabajar y no con desarrollar la funcionalidad específica que necesita el cliente. Empezamos leyendo la documentación de la API e investigamos sobre las diferentes interacciones posibles con los bots de slack. Allí indagamos sobre los Slash Commands. Básicamente para que nos salude un Bot, necesitábamos crear un Slash Command “/saludo” que nos respondiera “Holis [tu nombre]!”.

Ahí encontramos nuestro primer desafío. Slack tiene dos formas de implementar bots: una antigua y otra más actual. Muchos de los ejemplos que habíamos investigado eran de la forma clásica y no la moderna. ¿Por qué era esto un problema? La aplicación con la que queríamos integrar el bot de Slack está hecha en Ruby on Rails, tecnología que hoy en día no está tan “de moda” como antes. Esto implicaba que la oferta de ejemplos que pudimos encontrar con “bots modernos” en Rails era acotada.

Lo bueno es que uno tiene que confiar en que cuando las cosas cambian es para mejor. La forma actual de desarrollar bot de Slack es muchísimo más simple, así que entre el código de ejemplo que habíamos encontrado sobre cómo configurar cosas en rails, más lo que encontramos sobre cómo implementar un bot moderno en node era más que suficiente.

Nuestro primer comando

Para poder crear tu propio bot de Slack, primero hay que crear una Slack App en la página oficial de Slack. Esta “aplicación” es la que vamos a instalar en nuestro workspace donde queremos usar el bot. Cuando creamos la aplicación tenemos que estar logueados con un usuario que sea parte del workspace. Una vez creada la app, tenemos que agregarla en el espacio de trabajo.

Flujo de comunicación entre la Slack app, el bot de Slack y nuestra aplicación
Slack workspace: espacio de trabajo en donde se usa el bot. Slack API: página web donde se encuentra la configuración de la Slack App. API Jaguar: aplicación interna de donde se va a extraer la información que usará el bot.

Una vez que tengamos eso listo, podemos empezar a configurar nuestro primer comando.

Lo primero que hicimos fue crear el endpoint para poder configurar el comportamiento del comando. Como podemos ver en el gráfico, la API de slack realiza un método POST cuando un comando es llamado, por lo que teníamos que configurarlo así en nuestra API Jaguar.

scope '/api' do
    post :slack_bot, to: 'slack_bot#create'

Los parámetros que recibe el endpoint nos dan información sobre la persona que hace el uso del comando, como también del canal o espacio de trabajo, entre otros. A nosotras solo nos interesaba el nombre del usuario para poder saludarlo, por lo que desarrollamos lo siguiente:

def create
  render json: "Holis #{params[:user_name]}!"
end

Configurar la autenticación

Ahora que ya sabíamos como comunicarnos entre Slack, la API de Slack y nuestra API, el siguiente desafío era saber como verificar que el comando provenga únicamente de nuestro workspace. Hasta ahora, cualquier workspace que agregue a nuestro bot saludador iba a ser saludado por Jaguar.

Investigando, encontramos que una forma de verificar la  “autenticación” era agregando el token que pertenecía a las credenciales de nuestra app como variable de entorno y compararlo con el que venía en la request.

def verify_slack_token
  unless TOKEN == params[:token]
     render json: { error: "No tiene permisos."}, status: :forbidden
end

Al hablarlo con pines y leyendo un poco más en internet, esta forma funcionaba correctamente pero era muy poco segura y antigua. Por lo que una mejor forma de hacerlo, era comparando otras características que venían de los headers de la request.

Nos resultó bastante engorroso ya que esta forma consistía en el uso de varios parámetros de los headers ( HTTP_X_SLACK_SIGNATURE y HTTP_X_SLACK_REQUEST_TIMESTAMP).

Primero lo configuramos en las variables de entorno; esta información está disponible en las credenciales de la aplicación, al igual que el token.

Luego, desde el método que recibe el comando, verificamos los headers de la request con las variables de entorno usando hashes para mejorar la seguridad. De esta forma pudimos estar seguras que la request proviene de nuestro bot y de nuestro espacio de trabajo.

 timestamp = request.headers["HTTP_X_SLACK_REQUEST_TIMESTAMP"]
 signature = request.headers["HTTP_X_SLACK_SIGNATURE"]

 sig_basestring = 'v0:' + timestamp + ':' + request.body.read
 digest = OpenSSL::Digest.new('sha256')
 my_signature = 'v0=' + OpenSSL::HMAC.hexdigest(digest,   
 ENV['SLACK_SIGNING_SECRET'], sig_basestring)

 unless signature == my_signature
    return message_error
 end

Desarrollando los requerimientos

Ahora sí nos sentíamos confiadas para empezar a implementar las nuevas funcionalidades. Nuestro primer requerimiento era que el bot sepa responder la información de una computadora dado un número de serie. Gracias a que nos dimos el tiempo de realizar un spike, investigar y tener resuelto el flujo de comunicación con la autenticación incluida, realizar esta nueva tarea fue bastante sencillo. Nuestro último desafío fue ver cómo “embellecer” la respuesta del bot en slack.

El editor de texto de slack interpreta markdown y tiene acceso a todos los emojis personalizados del workspace donde se encuentra, por lo que sin mucho esfuerzo pudimos realizar un lindo diseño de una lista con la información de la computadora.

Ejemplo de respuesta de nuestro bot de Slack

Finalizando el recorrido

En resumen, fue una experiencia muy enriquecedora, en especial para nosotras que nunca habíamos realizado un spike y pudimos experimentar lo intimidante e intrigante de tener que cumplir con requerimientos que utilizan una tecnología desconocida.

Aunque nos encontramos con dificultades en el camino, estamos muy contentas con el recorrido, el resultado y el trabajo en equipo.

Les recomendamos que prueben desarrollar un bot de slack porque puede resultar muy gratificante el proceso de desarrollo y emocionante cuando ves que el bot TE RESPONDE. Pero les queremos advertir que, según nuestra experiencia, después van a querer crear bots de slack para todo 😛.