En el mundo en el que vivimos actualmente, cada vez es más necesario automatizar tareas que resulta tedioso realizarlas de forma manual, desde pruebas funcionales de una aplicación, a envío de emails o casi cualquier tarea que se nos pueda ocurrir. Es por eso que los bots están creciendo exponencialmente en muchas de las aplicaciones que usamos a diario como Facebook, Twitter, Telegram, etc. Hoy veremos cómo realizar bots para Slack de una forma muy sencilla, usando la API RTM (Real Time Message) de Slack y la librería JBot, que permite utilizar Spring Boot facilitando mucho la vida al desarrollador.
Qué vas as ver en esta entrada
Creación de nuestros bots en Slack
En primer lugar, debemos dar de alta nuestro bot en nuestro workspace de Slack, para poder obtener un token con el que realizar la conexión en tiempo real entre nuestro bot y Slack. De esta forma podremos recoger cualquier evento que se produzca.
Para ello accedemos a la dirección https://nombredetuworkspace.slack.com/apps/search?q=bots y nos aparecerá una pantalla como la siguiente:
Entramos en la sección Bots y hacemos click en Añadir a Slack para acceder a la siguiente pantalla:
Aquí damos un nombre a nuestro bot y vamos a Añadir integración robot.
De esta forma, ya tendremos nuestro bot dado de alta en nuestro workspace. En la pantalla que aparece, podemos personalizar distintos parámetros sobre el bot, como nombre de usuario, imagen, funciones, canales donde aparece, etc. Aunque lo más significativo para nuestro caso sería el apartado Token, el cual usaremos en nuestra aplicación para conectarnos:
Creación del bot con JBot
Una vez tenemos nuestro bot dado de alta en nuestro workspace, nos quedaría implementar la funcionalidad que queremos que realice nuestro bot. En este caso, vamos a implementar una sencilla conversación con nuestro bot, que nos permita crear tarjetas en Trello de forma automática a través de Slack.
Nota aclaratoria: Nos centraremos en la configuración e implementación del bot y no en la configuración y uso de la API de Trello.
Creación del proyecto
En primer lugar, nos creamos un proyecto Spring Boot desde https://start.spring.io/ y añadimos las librerías necesarias para la casuística a realizar. En nuestro caso bastaría con la dependencia de WebFlux para el consumo de la API de Trello y Lombok para facilitar la creación de los modelos.
Una vez tengamos nuestro proyecto descargado y abierto en nuestro IDE, procederemos a añadir la dependencia siguiente de JBot:
me.ramswaroop.jbot jbot 4.0.0
En el siguiente enlace os dejo la documentación de JBot.
Configuración
En nuestro fichero application.yml debemos poner las siguientes propiedades para conectarnos a la API de RTM:
rtmUrl: ‘https://slack.com/api/rtm.start?token={token}&simple_latest&no_unreads‘
api.slack.token = vuestro token obtenido en la creación del bot en slack
La propiedad rtmUrl indica la dirección donde tiene que conectarse para realizar la comunicación en tiempo real, mientras que api.slack.token se refiere al token propio de nuestro bot.
Creación de la lógica del bot
En primer lugar, debemos escanear el paquete de la librería JBot para que Spring reconozca sus beans:
@SpringBootApplication(scanBasePackages = {“me.ramswaroop.jbot”, “es.profile.slackbot”}) public class FridaysTechApplication { public static void main(String[] args) { SpringApplication.run(FridaysTechApplication.class, args); } }
Una vez tenemos los beans de JBot en el contexto de Spring, nuestra aplicación está lista para funcionar.
Nuestra clase principal del bot será SlackBot y esta deberá extender de la clase Bot, la cual ya nos provee de varios métodos y utilidades como enviar un mensaje al destinatario, empezar una conversación, terminar una conversación, etc. Además, deberá ser anotada con @JBot.
@Value(“${api.slack.token}”) private String token; @Override public String getSlackToken() { return this.token; } @Override public Bot getSlackBot() { return this; }
Ya solo nos quedaría recoger los eventos que se produzcan con nuestro bot y realizar la lógica deseada. Para ello, JBot nos provee de la anotación @Controller, la cual tiene un atributo events donde podemos indicarle todos los eventos que queremos escuchar (en la clase EventType tenemos todos los disponibles).
Además, esta anotación nos permite añadir cuál será el controller siguiente en caso de que queramos empezar una conversación mediante el atributo next.
@Controller(events = {EventType.DIRECT_MESSAGE, EventType.DIRECT_MENTION}, next = Steps.PROCESS_URL) public void welcome(WebSocketSession session, Event event) { SessionUtils.registerStep(session, Steps.INITIAL_STEP); SessionUtils.registerUser(session, slackService.getUsers(), event.getUserId()); startConversation(event, Steps.PROCESS_URL); reply(session, event, ReplyMessages.WELCOME); }
Como vemos en la imagen anterior, estamos escuchando los eventos de mensaje directo al bot o una mención directa para poder reaccionar ante ellos. De igual forma, estamos indicando cuál sería nuestro próximo “paso” en la conversación, apoyándonos en una clase propia llamada Steps donde indicamos todos los pasos posibles.
JBot nos ofrece una sesión con la que poder jugar con los parámetros que nos van llegando en los distintos eventos que escuchemos, de forma que podamos ir recopilando todos los datos de esta conversación para interactuar con ellos en el último paso. Para ello, nos apoyamos en una clase propia llamada SessionUtils, encargada de leer o escribir en la sesión. De esta forma, registramos el paso de la conversación en que estamos y el usuario que ha realizado el evento.
Mediante startConversation indicamos a JBot que vamos a empezar una conversación y que el siguiente evento que escuche deberá ir al controller indicado y utilizamos reply para devolver mensajes a nuestra conversación de slack, en este caso, apoyándonos de nuevo en una clase auxiliar donde pondremos todos los mensajes:
@Controller(events = EventType.DIRECT_MESSAGE) public void processUrl(WebSocketSession session, Event event) { if (continueConversation(session, event)) { SessionUtils.registerStep(session, Steps.CREATE_CARD); fridaysTechService.sendCard(session, event.getText()).subscribe(response -> validateResponse(session, event, response)); stopConversation(event); SessionUtils.cleanSession(session); } }
Por último, definimos el siguiente paso, que se encargaría de recoger el valor que nos manden y enviarlo a Trello para crear la tarjeta correspondiente.
De igual forma que en el primer paso, escuchamos el evento de mensaje directo, pero esta vez no indicamos el siguiente paso, puesto que será nuestro último paso de la conversación.
En primer lugar comprobamos que la palabra que ha escrito el usuario no es “salir” (u otra palabra para terminar la conversación). Registramos el paso y llamamos al servicio correspondiente para enviar a Trello nuestro mensaje.
El método validate response comprueba si la petición ha ido correctamente y envía un mensaje u otro a Slack:
private void validateResponse(WebSocketSession session, Event event, TrelloResponse response) { if (response.isSuccess()) { reply(session, event, ReplyMessages.FridaysTech.SEND_TRELLO_OK); } else { reply(session, event, ReplyMessages.ERROR_SEND_TRELLO); } }
Por último, le indicamos a JBot que cerramos la conversación y limpiamos la sesión.
En la siguiente imagen podemos ver una ejecución del bot en el que le añadimos un paso más para incluir una descripción en la tarjeta:
Conclusión
Con estos breves pasos, hemos conseguido crear nuestro primer bot en menos de una hora, dando así la posibilidad de implementar cualquier funcionalidad que necesitemos en poco tiempo.
¡Dad rienda suelta a vuestra imaginación y animaros a contarnos qué funcionalidad realizaríais para vuestro workspace de Slack!