Apogee: Cómo construimos nuestro bot de slack open source para dar karma

Imagen generada por inteligencia artificial de un escritorio con un MacBook y una pantalla para ilustrar la publicación "Cómo creamos nuestro bot de Slack de código abierto para dar karma a Orbitant".

Construir tu propia herramienta cuando detectas una necesidad resulta una tarea de lo más satisfactoria. A diferencia del día a día con el cliente, no suele haber requisitos ambiguos, ni meetings continuas, ni discusiones eternas sobre el color de un botón. Estás tú ante un problema concreto, con tu editor de código y el stack que dominas para resolverlo.

Apogee nació así: queríamos tener alguna forma de reconocer públicamente el trabajo de los miembros de nuestro equipo. No vengo a contarte el proyecto más complejo que hemos construido ni el más innovador técnicamente, sino el que representa lo que somos y el que nos da más satisfacciones (y cotilleos) diariamente. Un desarrollo sencillo, pragmático y cuyo código está disponible en nuestro repo de GitHub para quien quiera usarlo.

Qué hace Apogee y por qué existe

El nombre Apogee (“apogeo” en español) hace referencia al punto más alto de una órbita, el más alejado del centro gravitacional. Por eso el bot habla de meters (metros de altitud orbital): cada vez que alguien recibe karma, literalmente sube en su órbita. Cuando pierde karma, desciende. Nos gusta la metáfora espacial y encaja con nuestra identidad.

La mecánica es sencilla: mencionas a un compañero en Slack, añades signos ++ para darle karma o — para restárselo, y el bot registra la transacción públicamente. Cuantos más signos, más puntos mueves:

@carlos ++ Gracias por solucionar el deploy que dejé roto el viernes

El bot confirma automáticamente:

@carlos's apogee increased by 1 meters for a new value of 36.

Para esto tenemos un canal exclusivo llamado #thnx y el bot solo funciona ahí. No se trata de una restricción técnica, sino que es deliberada: el objetivo es que el reconocimiento sea visible para toda la organización. Cuando alguien desbloquea una tarea que tenía atascado a medio equipo, cuando otra persona contribuye con su conocimiento, cuando recibes ese tip o esa ayuda inesperada y resolutiva… todos esos momentos —y muchos más— son susceptibles de agradecimiento público.

Como miembro de equipos que trabajan forma distribuida desde hace una década, sé que el trabajo en remoto puede conllevar un problema de visibilidad: muchas contribuciones ocurren en conversaciones o hilos privados, en llamadas one to one, en momentos en los que no está presente toda la organización. Apogee hace que ese reconocimiento no sólo sea público y explícito, sino también permanente: no solo en el histórico del canal sino en los datos almacenados por la aplicación.

Hace tiempo que comprobamos que la gamificación bien implementada refuerza comportamientos positivos. Aunque también somos conscientes de que puede conllevar un riesgo de competitividad tóxica y métricas vanidosas. Por eso, el reconocimiento de Apogee no está vinculado a dinero o evaluaciones: El karma no afecta bonus ni revisiones de desempeño. En el momento que introduces incentivos materiales, la gente juega al sistema en lugar de usarlo genuinamente. Esta guía sobre gamificación de equipos de desarrollo resulta realmente útil.

Next.js y Vercel como pilares del stack técnico

Al diseñar este bot de Slack open source para uso interno teníamos que ajustarnos a dos condiciones: que tuviera el menor coste posible y que fuera rápido de implementar. Eso nos llevó a buscar herramientas que ofrecieran features gratuitas ajustadas a lo que necesitábamos y a descartar arquitecturas elaboradas.

Next.js como framework 

Next.js permite escribir frontend y lógica de servidor en el mismo proyecto. Las Server Actions eliminan la necesidad de montar APIs REST para operaciones simples: defines una función, la marcas como server action, y ya puedes llamarla desde el cliente. Para un bot que básicamente recibe webhooks y escribe en base de datos, es el equilibrio perfecto entre simplicidad y potencia.

Vercel para deployment 

Elegimos vercel como infra por su integración nativa con Next.js. Cada push a main despliega automáticamente a producción, cada push a staging crea un entorno de pruebas independiente. Para proyectos que necesitan iterar rápido, elimina toda la fricción de CI/CD tradicional. El serverless tiene limitaciones conocidas (timeouts, cold starts), pero para este caso de uso concreto era suficiente.

Turso como base de datos 

Turso nos da PostgreSQL compatible con un plan gratuito muy generoso. Además, incluye una interfaz web decente para consultar datos sin necesidad de instalar clientes pesados. El modelo de datos es intencionadamente simple: una tabla transaction que registra cada operación con el mensaje completo, emisor, receptor, cantidad de karma, timestamp y total acumulado. Funciona perfectamente y permite todas las consultas que necesitamos.

Integracion con Slack API

La integración con Slack API es donde está el trabajo interesante. Configuramos el bot mediante event subscriptions: cada vez que alguien escribe un mensaje en #thnx, Slack envía un POST a nuestro endpoint con todos los detalles.

Hay dos aspectos críticos en esta integración:

  • Validación de autenticidad: No podemos confiar en que cada POST venga realmente de Slack. Cualquiera con la URL de nuestro endpoint podría intentar enviar datos falsos. Slack firma cada request con HMAC usando un signing secret que solo nosotros conocemos. Validamos esa firma antes de procesar cualquier mensaje.
  • Respuesta inmediata: Slack espera un 200 OK en menos de 3 segundos. Si no lo recibe, asume que el evento no fue entregado y lo reenvía, creando potenciales loops infinitos. En Vercel usamos waitUntil para separar la respuesta HTTP del procesamiento real:

javascript

waitUntil(processMessage(body));

return new Response("OK", { status: 200 });

Devolvemos el OK inmediatamente, pero la función serverless continúa ejecutando el procesamiento en background.

Lógica de validación: qué permitimos y qué no

El procesamiento de cada mensaje sigue un flujo claro. Primero, una expresión regular extrae las menciones de usuarios y los símbolos de karma. Luego aplicamos validaciones:

  • ¿Intentas darte karma a ti mismo? Rechazado.

`@carlos you can't give meters to yourself. Apogee is watching you!.`

  • ¿Intentas quitarte karma a ti mismo? También rechazado.

`@carlos you can't take away meters from yourself. Apogee is watching you!.`

  • ¿Has movido más de 15 puntos (positivos o negativos) en las últimas 2 semanas? Límite alcanzado.

`@carlos you have reached the meters' limit. Being too generous or mean lately?`

Esa ventana móvil de 2 semanas evita que usuarios excesivamente generosos o demasiado vengativos distorsionen las puntuaciones de forma desproporcionada. Queremos que el karma refleje un patrón sostenido de contribuciones, no explosiones puntuales de generosidad o venganza —aunque de esto último, casi no tenemos ejemplos—.

El límite al canal #thnx refuerza dos principios arquitectónicos: 

  • Transparencia: todos ven quién reconoce a quién
  • Equidad: el objetivo es evitamos que equipos con dinámicas internas más consolidadas acumulen ventaja simplemente por estar en un proyecto con más ceremonias de reconocimiento).

Roadmap: lo que viene

Versiones anteriores de este bot que tuvimos en otras empresas incluían funcionalidades que planeamos recuperar:

Comandos de consulta para interrogar al bot mediante slash commands de Slack y obtener rankings, posición de un usuario concreto, o estadísticas generales. Ahora mismo no hay interfaz de consulta más allá de meterse directamente en la base de datos.

Karma a equipos completos: mencionar un grupo de usuarios o un equipo (@marketing ++) y que el bot distribuya karma entre todos sus miembros. Útil para reconocer trabajos colaborativos donde individualizar es complicado o injusto.

Resumen semanal generado con LLM: un mensaje automatizado que cuente qué ha pasado durante la semana con tono informal. «Esta semana Carlos ha sido el más generoso, Víctor parece que viene con ganas de polémica, y el equipo X ha recibido karma de prácticamente toda la empresa». Ese tipo de narrativa que hace los datos más digeribles y entretenidos.

También consideramos facilitar la instalación para otras organizaciones, publicándolo en el Slack App Directory con un flujo de configuración simplificado.

Código abierto en GitHub

Todo el código de Apogee está disponible en nuestro repositorio de GitHub. El repositorio incluye:

  • Instrucciones completas de configuración de Slack API
  • Esquema de base de datos con Turso
  • Variables de entorno necesarias
  • Toda la lógica de procesamiento, validación y almacenamiento

Si quieres implementar un bot de Slack open source similar en tu organización, todo lo necesario está documentado. Este MVP inicial se desarrolló durante una sesión de programación en solitario, en pareja con la IA, en una fría noche de invierno, y sin duda deja margen de evolución. Si encuentras formas de mejorar la implementación o añadir funcionalidades, los pull requests son bienvenidos.

Construir herramientas propias para resolver problemas internos tiene un valor que va más allá del código resultante. Demuestra capacidad de ejecución, dominio del stack técnico, y disposición a crear soluciones cuando tiene sentido hacerlo en lugar de depender siempre de terceros. Apogee es un ejemplo de eso: identificamos una necesidad, elegimos el stack más pragmático, implementamos limpio y funcional, y lo compartimos abiertamente. Así trabajamos.

Sigue nuestro viaje construyendo agentes IA desde dentro