O'T CRM es un SaaS (Software as a Service) empresarial que unifica la atencion al cliente a traves de multiples canales de mensajeria. Integra WhatsApp y Telegram en un tablero Kanban interactivo con chat en tiempo real, gestion de equipo, sistema de suscripciones y analiticas de negocio.
Este proyecto nacio del esfuerzo conjunto de dos amigos apasionados por la tecnologia. Durante 2 intensos meses (aprox. 8 horas diarias), construimos esta plataforma desde cero. Combinamos nuestros conocimientos previos, aprendizaje autodidacta a traves de documentacion y videos, y el uso estrategico de Inteligencia Artificial para acelerar el desarrollo y resolver problemas de arquitectura compleja. El resultado es un SaaS funcional, escalable y listo para produccion.
- Caracteristicas Principales
- Arquitectura del Sistema
- Stack Tecnologico
- Estructura del Proyecto
- Backend en Detalle
- Frontend en Detalle
- Bot de WhatsApp
- Bot de Telegram
- Sistema de Planes y Suscripciones
- Pasarelas de Pago
- Seguridad
- Despliegue con Docker
- Guia de Instalacion Local
- Variables de Entorno
- Creditos y Contacto
- Tablero Kanban con drag & drop para gestionar leads a traves de etapas personalizables (colores, orden, nombres).
- Sistema de etiquetas con colores para categorizar contactos.
- Gestion de saldos/presupuestos por cliente con operaciones de carga y retiro.
- Notas y actividades por contacto.
- Busqueda global avanzada por nombre, telefono y etiquetas.
- WhatsApp via Baileys (escaneo QR, envio/recepcion de texto, imagenes, videos, documentos, audio y stickers).
- Telegram via Telethon (multiples sesiones, soporte de media completo).
- Chat unificado en tiempo real con historial de conversaciones.
- Respuestas rapidas (templates predefinidos para agilizar la atencion).
- WebSockets (STOMP + SockJS) para actualizaciones instantaneas en el Kanban, chat y notificaciones.
- Presencia online/offline de cada miembro del equipo.
- Notificaciones de escritorio y alertas de audio para mensajes nuevos.
- Sistema de agencias con roles (Admin, Agente).
- Solicitudes de union a equipos con flujo de aprobacion.
- Codigos de invitacion para incorporar miembros.
- Plan compartido: el plan del Admin aplica a todo el equipo.
- KPIs en tiempo real: leads del dia, mensajes sin leer, total de contactos.
- Monitoreo de dispositivos conectados.
- Estado de suscripcion y uso del plan.
- Vista de equipo con estado de presencia.
- Importar contactos desde archivos Excel (.xlsx/.xls) con validacion de plan.
- Exportar contactos a Excel.
- Reportes de transacciones exportables a Excel.
- Integracion con Cloudinary para imagenes, documentos y archivos multimedia.
- Generacion de codigos QR para vinculacion de dispositivos.
El proyecto sigue una arquitectura de microservicios distribuidos orquestados con Docker Compose:
+------------------+
| Frontend |
| React 19 SPA |
| (Vite Build) |
+--------+---------+
|
HTTPS / WSS
|
+--------------+--------------+
| Backend (Java 21) |
| Spring Boot 3.5 |
| REST API + WebSocket STOMP |
| PostgreSQL (JPA) |
+---------+----------+--------+
| |
Webhooks HTTP| |Webhooks HTTP
| |
+---------+--+ +----+----------+
| Bot WhatsApp| | Bot Telegram |
| Node.js 20 | | Python 3.11 |
| Baileys | | Telethon |
| Socket.io | | Flask |
+-------------+ +---------------+
Flujo de datos:
- Los bots reciben mensajes de WhatsApp/Telegram.
- Envian los datos al backend via webhooks HTTP autenticados con
BOT_SECRET_KEY. - El backend procesa, persiste en PostgreSQL y notifica al frontend via WebSocket.
- El frontend actualiza el Kanban, chat y notificaciones en tiempo real.
| Capa | Tecnologia | Version |
|---|---|---|
| Backend | Java + Spring Boot | 21 / 3.5.10 |
| Frontend | React + Vite | 19.2 / 8.0 |
| Base de Datos | PostgreSQL + Hibernate | 16+ |
| Bot WhatsApp | Node.js + Baileys + Express | 20+ |
| Bot Telegram | Python + Telethon + Flask | 3.8+ |
| WebSockets | STOMP + SockJS | - |
| Autenticacion | JWT (JJWT 0.11.5) + Spring Security | - |
| Pagos | MercadoPago API + PayPal SDK | - |
| Resend API | 3.1.0 | |
| Archivos | Cloudinary SDK | 1.36.0 |
| Excel | Apache POI | 5.2.5 |
| QR Code | ZXing | 3.5.1 |
| Contenedores | Docker + Docker Compose | - |
| Hosting | Railway | - |
| DNS/CDN | Cloudflare | - |
OT-crm/
|-- Backend/
| |-- src/
| |-- config/ # WebSocket, MVC, Security, Properties
| |-- controller/ # 21 REST controllers
| |-- dto/ # Data Transfer Objects
| |-- exception/ # Excepciones custom
| |-- initializer/ # DataInitializer (planes, admin, etapas)
| |-- listener/ # WebSocket presence events
| |-- model/ # 12 entidades JPA
| |-- repository/ # 12 repositorios Spring Data
| |-- security/ # JWT, filtros, interceptores
| |-- service/ # 20 servicios de logica de negocio
| |-- application.properties
|
|-- Frontend/
| |-- src/
| |-- components/ # KanbanCard, ChatModal, Sidebar, etc.
| |-- context/ # UserContext, ToastContext
| |-- hooks/ # useWebSocket, useAudio
| |-- pages/ # 11 paginas (Auth, Dashboard, Kanban, etc.)
| |-- utils/ # api.js (Axios config), notifications.js
| |-- App.jsx # Rutas principales
|
|-- Bot-Whatsapp/
| |-- index.js # Servidor Express + Baileys
| |-- package.json
| |-- Dockerfile
|
|-- Bot-Telegram/
| |-- telegram_bridge.py # Flask + Telethon bridge
| |-- requirements.txt
|
|-- Dockerfile # Multi-stage (React + Maven + Runtime)
|-- docker-compose.yml # Orquestacion de servicios
|-- pom.xml # Dependencias Maven
|-- .env.example # Template de variables de entorno
|-- .gitignore
| Controller | Ruta Base | Descripcion |
|---|---|---|
AuthController |
/api/v1/auth |
Login, registro, verificacion de email, recuperacion de contrasena |
ClienteController |
/api/v1/contactos, /api/v1/clientes |
CRUD de contactos, importar/exportar Excel, etiquetas, saldos |
ChatController |
/api/v1/chat |
Historial de mensajes, envio de mensajes, subida de archivos |
WhatsAppController |
/api/v1/whatsapp |
QR, conexion de dispositivos, estado de instancias |
TelegramDispositivoController |
/api/v1/telegram |
Setup y validacion de dispositivos Telegram |
WhatsAppWebhookController |
/api/webhook/whatsapp |
Receptor de webhooks del bot Node.js |
TelegramWebhookController |
/api/telegram |
Receptor de webhooks del bot Python |
DashboardRestController |
/api/v1/dashboard |
KPIs en tiempo real, gestion de equipo |
MercadoPagoController |
/api/v1/mp, /api/mp |
Suscripciones y webhooks de MercadoPago |
PayPalController |
/api/v1/paypal |
Creacion de suscripciones PayPal |
PayPalWebhookController |
/api/paypal/webhook |
Webhooks de PayPal |
PlanController |
/api/v1/planes |
CRUD de planes, info de suscripcion |
EtapaController |
/api/v1/etapas |
Gestion de etapas del pipeline |
RespuestaRapidaController |
/api/v1/respuestas-rapidas |
Templates de respuestas rapidas |
PerfilController |
/api/v1/perfil |
Perfil de usuario, cambio de contrasena |
AgenciaController |
/api/v1/agencia |
Gestion de agencia/organizacion |
PresenceController |
/api/v1/presence |
Presencia online/offline via WebSocket |
ReporteController |
/api/v1/reportes |
Reportes y analiticas |
TransaccionApiController |
/api/v1/transacciones |
Transacciones financieras por cliente |
TableroSocketController |
WebSocket | Actualizaciones en tiempo real del tablero |
SpaController |
/** |
Sirve el index.html del SPA para rutas del frontend |
| Entidad | Descripcion |
|---|---|
Usuario |
Usuario con rol, verificacion de email, plan, agencia |
Agencia |
Organizacion con multiples usuarios, dispositivos y clientes |
Cliente |
Lead/contacto con telefono, etapa, etiquetas, saldo, historial |
Dispositivo |
Dispositivo WhatsApp/Telegram con estado de conexion |
Etapa |
Etapa del pipeline (orden, color, flag de inicial) |
Mensaje |
Mensaje con contenido, timestamp, archivo adjunto, estado de entrega |
Plan |
Plan de suscripcion (FREE, PRO, BUSINESS, ENTERPRISE) |
Transaccion |
Transaccion financiera vinculada a cliente y usuario |
Etiqueta |
Sistema de tags con colores para clientes |
RespuestaRapida |
Templates de respuestas predefinidas |
SolicitudUnionEquipo |
Solicitudes de ingreso a un equipo |
ProcessedWebhook |
Idempotencia de webhooks para evitar procesamiento duplicado |
| Servicio | Responsabilidad |
|---|---|
WhatsAppService |
Procesamiento de mensajes WA, sincronizacion de clientes, archivos |
TelegramBridgeService |
Puente entre bot Python y backend Java |
ChatService |
Historial de chat, organizacion de mensajes |
UsuarioService |
Registro, verificacion de email (codigos), recuperacion de contrasena |
DashboardService |
Agregacion de KPIs (leads, mensajes sin leer, contactos) |
PlanService |
Activacion/expiracion de planes, upgrades/downgrades |
SubscriptionValidationService |
Enforcement de limites (contactos, dispositivos) |
PlanPriceScheduler |
Sincronizacion automatica de precios con MercadoPago |
EmailService |
Emails transaccionales via Resend API |
CloudStorageService |
Uploads a Cloudinary (imagenes, documentos, media) |
ExcelService |
Importacion/exportacion de contactos y reportes en .xlsx |
QrCodeService |
Generacion de codigos QR para vincular dispositivos |
- Endpoint:
/ws-crm(SockJS + STOMP) - Canales de broadcast:
/topic/agencia/{agenciaId}- Eventos de la agencia (nuevos mensajes, clientes actualizados, etc.)/topic/embudo/{agenciaId}- Cambios en el pipeline/Kanban/topic/global-notifications- Notificaciones del sistema
- Heartbeat configurable para mantener conexiones activas
- Interceptor de presencia para tracking online/offline
| Pagina | Ruta | Descripcion |
|---|---|---|
Auth.jsx |
/ |
Login, registro, verificacion de email, recuperacion de contrasena |
Dashboard.jsx |
/dashboard |
KPIs, equipo, presencia, estado de dispositivos |
Kanban.jsx |
/kanban |
Tablero drag & drop con chat integrado |
Contactos.jsx |
/contactos |
Lista de contactos, importar/exportar Excel, busqueda |
WhatsAppVincular.jsx |
/whatsapp-vincular |
Vincular dispositivo WhatsApp via QR |
TelegramVincular.jsx |
/telegram-vincular |
Conectar bot de Telegram |
Planes.jsx |
/planes |
Comparacion y seleccion de planes |
Checkout.jsx |
/checkout |
Procesamiento de pagos |
MiSuscripcion.jsx |
/mi-suscripcion |
Detalles de plan actual, miembros del equipo |
RespuestasRapidas.jsx |
/respuestas-rapidas |
Gestion de templates de respuestas |
Perfil.jsx |
/perfil |
Perfil, cambio de contrasena, avatar |
- KanbanCard / KanbanColumn - Tarjetas y columnas del pipeline con drag & drop
- ChatModal - Interfaz de chat integrada con emoji picker y subida de archivos
- SlashCommandMenu - Menu de comandos rapidos (/)
- NotificationBell - Campana de notificaciones con contador
- Sidebar - Navegacion principal con indicadores de estado
- MainLayout - Shell de la aplicacion autenticada
| Libreria | Uso |
|---|---|
react-router-dom |
Routing SPA |
axios |
Cliente HTTP con JWT auto-inject |
@stomp/stompjs |
Cliente WebSocket STOMP |
sockjs-client |
Fallback para WebSocket |
emoji-picker-react |
Selector de emojis en el chat |
@fortawesome/fontawesome-free |
Iconos (bundled localmente) |
Stack: Node.js 20+ / Express / Baileys / Socket.io
- Autenticacion QR: Endpoint
/auth/qrgenera el codigo QR para escanear con WhatsApp. - Sesiones persistentes: Los datos de autenticacion se guardan en
auth_info_v2/(volume Docker). - Multi-dispositivo: Soporte para multiples instancias de WhatsApp simultaneas.
- Tipos de mensaje soportados: Texto, imagenes, videos, audio, documentos, stickers.
- Cola de mensajes: Una cola por JID para prevenir race conditions.
- Deduplicacion: Cache de 5 minutos para evitar mensajes duplicados.
- Webhook: Envia mensajes entrantes al backend Java via POST autenticado con
BOT_SECRET_KEY.
Stack: Python 3.11 / Flask / Telethon / httpx
- Multi-sesion: Diccionario de clientes activos para sesiones concurrentes.
- Procesamiento de media: Deteccion automatica del tipo (foto, video, audio, documento, sticker, voz).
- Fotos de perfil: Descarga y cache automatica de avatares de contactos.
- Webhook: Envia mensajes entrantes al backend Java via POST autenticado.
| Plan | Dispositivos | Contactos | Precio (ARS/mes) | Descripcion |
|---|---|---|---|---|
| FREE | 1 | 25 | $0 | Plan gratuito para pruebas |
| PRO | 5 | 75 | $15.000 | Para equipos de ventas en crecimiento |
| BUSINESS | 10 | 250 | $30.000 | Para agencias consolidadas |
| ENTERPRISE | Ilimitado | Ilimitado | $60.000 | Plan VIP sin restricciones |
- Dispositivos conectados: Al intentar vincular un dispositivo que excede el limite, se retorna HTTP 402 (Payment Required).
- Contactos unicos: Cuando un nuevo contacto escribe por WhatsApp/Telegram y se alcanzo el limite, se rechaza y se notifica al usuario via WebSocket.
- Importacion de contactos: Si una importacion de Excel superaria el limite de contactos del plan, se rechaza la importacion completa con un mensaje descriptivo.
- Mensajes: Son ilimitados en todos los planes.
El plan del usuario con rol ADMIN aplica a todos los miembros de la agencia. Al hacer downgrade, los dispositivos excedentes se desconectan automaticamente.
- Suscripciones mensuales recurrentes en ARS.
- El usuario es redirigido al
init_pointde MercadoPago para completar el pago. - Webhooks procesan eventos:
subscription_authorized_payment,subscription_preapproval. - Sincronizacion automatica de precios via
PlanPriceScheduler.
- Suscripciones via REST API con OAuth2.
- Webhooks escuchan:
BILLING.SUBSCRIPTION.ACTIVATED,BILLING.SUBSCRIPTION.CANCELLED,BILLING.SUBSCRIPTION.EXPIRED,BILLING.SUBSCRIPTION.SUSPENDED. - Soporte para modo sandbox y produccion.
- El usuario selecciona un plan en
/planes. - Se crea la suscripcion en MercadoPago o PayPal.
- El usuario completa el pago en la pasarela.
- Un webhook confirma el pago y activa el plan por 1 mes.
- Al cancelar o expirar, el usuario baja automaticamente a FREE.
- JWT (JSON Web Tokens) con expiracion configurable (default 10 horas).
- BCrypt para hash de contrasenas.
- Spring Security con sesiones stateless.
- Verificacion de email con codigos de 6 digitos y expiracion de 15 minutos.
- Recuperacion de contrasena via email con codigos temporales y expiracion.
- Comparacion timing-safe de codigos con
MessageDigest.isEqual()para prevenir ataques de timing.
- Publicos:
/api/v1/auth/**,/api/webhook/**,/api/telegram/**, webhooks de pago. - Protegidos: Todos los demas endpoints requieren JWT valido.
- CORS: Whitelist de origenes permitidos.
- Rate Limiting: Bucket4j con limites diferenciados por endpoint (auth: 10 req/min, webhooks: 60 req/min, API general: 120 req/min).
- Correlation IDs: Cada request recibe un ID unico para trazabilidad en logs.
- Ownership checks: Los endpoints de eliminacion/modificacion verifican que el recurso pertenezca a la agencia del usuario.
- Autenticacion bot-to-backend via
BOT_SECRET_KEYen headers con comparacion constant-time. - Validacion de payloads en webhooks de MercadoPago y PayPal.
- HSTS con max-age de 1 ano e includeSubDomains.
- X-Frame-Options: DENY para prevencion de clickjacking.
- X-Content-Type-Options: nosniff para prevenir MIME sniffing.
- Referrer-Policy: strict-origin-when-cross-origin.
- Permissions-Policy: Camara, microfono y geolocalizacion deshabilitados.
- Arquitectura Zero Trust basada en la metodologia 12-Factor App.
- Ninguna credencial existe en el codigo fuente; todo se inyecta via variables de entorno.
- Archivo
.env.examplecomo template sin valores reales.
El Dockerfile principal utiliza 3 etapas para optimizar el tamano de la imagen:
# Etapa 1: Build del frontend React con Node 20
FROM node:20-alpine AS frontend
# Etapa 2: Build del backend Java con Maven
FROM maven:3.9.6-eclipse-temurin-21 AS backend
# Etapa 3: Runtime minimo con Alpine
FROM eclipse-temurin:21-jre-alpineEl frontend se compila y se sirve como archivos estaticos desde Spring Boot en un unico puerto (8080).
docker-compose up --buildLevanta 4 servicios:
- postgres (puerto 5432) - PostgreSQL 16 con volumen persistente
- backend (puerto 8080) - Spring Boot + React estatico
- Bot-Whatsapp (puerto 3000) - Bot de WhatsApp con volumen persistente para sesiones
- Bot-Telegram (puerto 5000) - Bot de Telegram con Telethon
- Railway: Hosting con escalabilidad horizontal, variables de entorno inyectadas y volumenes persistentes.
- Cloudflare: DNS, proxy inverso, cache perimetral y proteccion DDoS.
- Docker y Docker Compose
- Java 21 (opcional, si se corre fuera de Docker)
- Node.js 20+ (opcional, para desarrollo del bot)
- Python 3.11 (opcional, para el bot de Telegram)
- PostgreSQL 16+ (o usar uno remoto)
-
Clonar el repositorio:
git clone https://github.com/fabrithompson/ot-crm.git cd ot-crm -
Configurar variables de entorno:
cp .env.example .env
Edita
.envy completa todas las credenciales requeridas. -
Levantar con Docker:
docker-compose up --build
-
Acceder a la aplicacion:
- URL:
http://localhost:8080 - Credenciales por defecto:
admin/ (la que configures enAPP_DEFAULT_ADMIN_PASSWORD)
- URL:
Todas las variables necesarias estan documentadas en .env.example:
| Variable | Descripcion | Requerida |
|---|---|---|
SPRING_DATASOURCE_URL |
URL de conexion PostgreSQL (jdbc:postgresql://...) | Si |
SPRING_DATASOURCE_USERNAME |
Usuario de la base de datos | Si |
SPRING_DATASOURCE_PASSWORD |
Contrasena de la base de datos | Si |
JWT_SECRET |
Clave secreta para firmar tokens JWT | Si |
BOT_SECRET_KEY |
Clave compartida para autenticacion bot-backend | Si |
NODE_BOT_URL |
URL del bot de WhatsApp | Si |
APP_DEFAULT_ADMIN_PASSWORD |
Contrasena del admin por defecto | Si |
APP_BASE_URL |
URL base de la aplicacion | Si |
MERCADOPAGO_ACCESS_TOKEN |
Token de acceso de MercadoPago | Si |
PAYPAL_CLIENT_ID |
Client ID de PayPal | Si |
PAYPAL_CLIENT_SECRET |
Client Secret de PayPal | Si |
PAYPAL_MODE |
Modo de PayPal (sandbox o live) |
No |
CLOUDINARY_CLOUD_NAME |
Nombre del cloud en Cloudinary | Si |
CLOUDINARY_API_KEY |
API Key de Cloudinary | Si |
CLOUDINARY_API_SECRET |
API Secret de Cloudinary | Si |
RESEND_API_KEY |
API Key de Resend para emails | Si |
APP_EMAIL_ENABLED |
Habilitar envio de emails (true/false) |
No |
TELEGRAM_API_ID |
API ID de Telegram (para el bot) | Si* |
TELEGRAM_API_HASH |
API Hash de Telegram (para el bot) | Si* |
*Requeridas solo si se despliega el bot de Telegram.
Desarrollado con dedicacion por:
- Fabricio Thompson - fabrithompson - fabriciothompson16@gmail.com
- Ivan O'Connor - IvanOCNN - ivanoconnor28@gmail.com
Para consultas empresariales, despliegues personalizados o dudas tecnicas, no dudes en contactarnos.