Referencias Open Source
Visión General
Este sección analiza los proyectos open source de referencia para la construcción de nuestra plataforma. Cada proyecto es evaluado por su arquitectura, funcionalidades, licencia, y utilidad como referencia.
Chatwoot
| Aspecto | Detalle |
|---|---|
| Repositorio | github.com/chatwoot/chatwoot |
| Stack | Ruby on Rails 7.2, Vue 3, PostgreSQL, Redis, Sidekiq |
| Licencia | MIT (core), AGPL (enterprise features) |
| Estrellas | 21k+ |
| Enfoque | Gestión de conversaciones omnicanal |
Arquitectura
Chatwoot sigue una arquitectura de monolito Rails con separación clara entre backend (Rails) y frontend (Vue 3).
Componentes principales:
- Rails API: Backend REST con serializers JSON:API
- Vue 3 Frontend: SPA con Vuex, composables
- PostgreSQL: Base de datos principal
- Redis: Cache, colas, pub/sub
- Sidekiq: Procesamiento asíncrono de jobs
Channel Adapter Pattern
El patrón de adaptadores de canales es el aspecto más reutilizable de Chatwoot:
Inbox (polimórfico)
├── Channel::WebWidget
├── Channel::Facebook
├── Channel::Twitter
├── Channel::WhatsApp
├── Channel::Email
├── Channel::Telegram
├── Channel::Line
├── Channel::Sms
├── Channel::Api
├── Channel::WhatsApp (Twilio)
├── Channel::Instagram
└── Channel::SignalConceptos clave:
Inbox: Representa un canal de entrada (polimórfico)Channel: Implementación específica del canalConversation: Hilo de mensajes con un contactoMessage: Un mensaje individual (texto, archivo, etc.)
Event Dispatching
Chatwoot implementa un sistema de eventos basado en callbacks de ActiveJob:
- Eventos de conversación (creada, actualizada, resuelta)
- Eventos de mensaje (recibido, enviado, leído)
- Eventos de agente (asignado, removido)
- Webhooks configurables por tenant
License
MIT (core): Licencia permisiva que permite:
- Uso comercial
- Modificación sin开源
- Distribución sin开源
- Uso en productos proprietarios
Enterprise features (AGPL): Algunas funcionalidades avanzadas como SSO, macros, y reportes están bajo AGPL.
¿Qué Reutilizar?
| Aspecto | ¿Reutilizar? | Notas |
|---|---|---|
| Patrón de canales polimórficos | Sí (como referencia) | Modelo conceptual, no código |
| Event dispatching | Sí (como referencia) | Patrón de diseño |
| Conversation lifecycle | Sí (como referencia) | Estados y transiciones |
| Código fuente | No | Licencia MIT lo permite, pero es Ruby |
Zammad
| Aspecto | Detalle |
|---|---|
| Repositorio | github.com/zammad/zammad |
| Stack | Ruby on Rails 8.0, Vue 3, PostgreSQL, GraphQL |
| Licencia | AGPL-3.0 |
| Estrellas | 6k+ |
| Enfoque | Helpdesk y ticketing |
Arquitectura
Zammad es un sistema de helpdesk/ticketing con arquitectura moderna:
- Rails 8.0: Backend con Hotwire/Turbo
- Vue 3: Frontend SPA
- PostgreSQL: Base de datos
- GraphQL API: API moderna para el frontend
- Elasticsearch: Búsqueda full-text (opcional)
Fortalezas
- RBAC (Role-Based Access Control): 53 políticas de permisos granulares
- SLA y Escalación: Sistema completo de SLA con reglas de escalamiento automático
- Knowledge Base: Sistema de artículos de ayuda integrado
- Ticket States: Estados personalizables con transiciones
- Triggers: Sistema de automatización basado en reglas
- Reporting: Dashboards y reportes personalizables
Debilidades
- Enfoque en ticketing: No es un contact center completo (sin discador, IVR)
- Sin telefónica nativa: Integra con sistemas externos pero no tiene su propia pila telefónica
License
AGPL-3.0: Licencia fuertemente copyleft:
| Escenario | ¿Permitido? |
|---|---|
| Usar como referencia conceptual | Sí |
| Copiar fragmentos de código | No |
| Modificar internamente y usar | No (obliga a开源 todo) |
| Distribuir como servicio SaaS | No (obliga a开源) |
| Estudiar patrones de diseño | Sí |
Decisión
No reutilizar código. Estudiar únicamente los patrones de diseño y funcionalidades.
VICIdial
| Aspecto | Detalle |
|---|---|
| Repositorio | sourceforge.net/projects/vicidial |
| Stack | Perl, PHP, MySQL, Apache (LAMP) |
| Licencia | AGPLv2 |
| Enfoque | Dialer y campañas outbound |
| Producción | 15+ años en producción activa |
Arquitectura
VICIdial es un sistema de discador maduro con arquitectura LAMP legacy:
- Perl: Core del discador y servicios
- PHP: Interfaz web
- MySQL: Base de datos
- Asterisk: Sustrato telefónica
Modos de Discador
VICIdial implementa 6 modos de discador:
| Modo | Descripción |
|---|---|
| Manual | Agente marca uno a uno |
| Adaptive | Ajusta ratio basado en respuestas |
| Predictive | Predice disponibilidad de agentes |
| Power | Ratio fijo de llamadas paralelas |
| Progressive | Una llamada por agente disponible |
| Agent | El agente controla la marcación |
Algoritmo de Pacing
El algoritmo de pacing adaptativo es el activo más valioso de VICIdial:
Parámetros clave:
ratio: Número de llamadas por agente disponibledrop_percentage: Porcentaje máximo de llamadas abandonadasavg_hold_time: Tiempo promedio de esperacalls_per_minute: Llamadas por minuto
Lógica adaptativa:
- Calcula ratio basado en agentes disponibles y métricas históricas
- Ajusta ratio en tiempo real basado en:
- Tasa de respuesta
- Tiempo promedio de llamada
- Abandon rate
- Disponibilidad de agentes
- Limita por
drop_percentagemáximo (típicamente 3%)
License
AGPLv2: Similar a AGPL-3.0 pero versión 2. Restricciones equivalentes.
¿Qué Reutilizar?
| Aspecto | ¿Reutilizar? | Notas |
|---|---|---|
| Algoritmo de pacing | Sí (como referencia) | Lógica transferible a Go |
| Estados de campaña | Sí (como referencia) | Ciclo de vida completo |
| Código fuente | No | Perl/PHP legacy, AGPLv2 |
Omnidialer
| Aspecto | Detalle |
|---|---|
| Repositorio | github.com/omnidialer/omnidialer |
| Stack | Python 3.12, Flask, Gearman, PostgreSQL, Redis |
| Licencia | No especificada |
| Enfoque | Discador basado en ARI |
Arquitectura
Omnidialer es un discador moderno que utiliza ARI (Asterisk REST Interface) en lugar de AMI:
- Python 3.12: Lenguaje moderno, tipado opcional
- Flask: Framework web ligero
- Gearman: Distribución de trabajo
- PostgreSQL: Persistencia
- Redis: Cache y colas
Integración vía ARI
Omnidialer demuestra la integración moderna con Asterisk:
Omnidialer → ARI REST API → Asterisk
← WebSocket eventsVentajas de ARI vs AMI:
- API REST moderna y bien documentada
- WebSocket para eventos en tiempo real
- Control granular de canales y bridges
- Mejor soporte para aplicaciones de terceros
Modos de Discador
- Predictive: Algoritmo adaptativo
- Power: Ratio fijo
License
No especificada. Se requiere verificación antes de usar cualquier código.
¿Qué Reutilizar?
| Aspecto | ¿Reutilizar? | Notas |
|---|---|---|
| Patrón de integración ARI | Sí (como referencia) | Excelente modelo para Go |
| Código fuente | Verificar | Sin licencia especificada |
Asterisk
| Aspecto | Detalle |
|---|---|
| Repositorio | github.com/asterisk/asterisk |
| Stack | C, dynamic module loading |
| Licencia | GPLv2 con excepción de protocolo |
| Enfoque | Plataforma telefónica completa |
| Producción | 25+ años, estándar de facto |
Arquitectura
Asterisk es una plataforma de comunicaciones unificada:
- C: Core de alto rendimiento
- Dynamic modules: Carga dinámica de módulos
- Multiple interfaces: CLI, AMI, ARI, AGI
- Codec support: Transcoding completo
Interfaces de Control
| Interface | Descripción | Uso Recomendado |
|---|---|---|
| CLI | Command-line interface | Administración, debugging |
| AMI | Asterisk Manager Interface | Legacy, integración antigua |
| ARI | Asterisk REST Interface | Recomendado: Integración moderna |
| AGI | Asterisk Gateway Interface | Scripts de IVR legacy |
ARI (Asterisk REST Interface)
ARI es la interfaz moderna para controlar Asterisk desde aplicaciones externas:
Capacidades:
- Crear/destruir canales
- Controle de bridges (conference, transfers)
- IVR navigation
- Play/record audio
- Eventos en tiempo real vía WebSocket
Endpoints principales:
GET /channels- Listar canales activosPOST /channels/create- Crear un canalPOST /channels/{id}/answer- Contestar llamadaPOST /channels/{id}/play- Reproducir audioPOST /channels/{id}/record- Grabar audioPOST /channels/{id}/redirect- Redirigir- `DELETE /channels/{id}# - Colgar
License
GPLv2 con excepción de protocolo:
| Escenario | ¿Permitido? |
|---|---|
| Usar ARI desde aplicación proprietaria | Sí (excepción de protocolo) |
| Modificar el core de Asterisk | No (obliga a开源) |
| Distribuir Asterisk modificado | No (obliga a开源) |
| Usar como servicio externo | Sí |
| Comunicarse vía REST/WebSocket | Sí |
La excepción de protocolo permite que aplicaciones externas se comuniquen con Asterisk sin obligar a que la aplicación sea GPL. Esto es crítico para nuestro producto.
Decisión
Usar Asterisk como sustrato telefónica vía ARI. Nunca reimplementar SIP/RTP. Comunicación exclusiva vía REST API y WebSocket.
Tabla Comparativa
| Aspecto | OMniLeads | Chatwoot | Zammad | VICIdial | Omnidialer | Asterisk |
|---|---|---|---|---|---|---|
| Lenguaje | Python | Ruby | Ruby | Perl/PHP | Python | C |
| Framework | Django 7.2 | Rails 7.2 | Rails 8.0 | LAMP | Flask | N/A |
| Base de datos | PostgreSQL | PostgreSQL | PostgreSQL | MySQL | PostgreSQL | N/A |
| Licencia | LGPL v3 | MIT | AGPL-3.0 | AGPLv2 | No spec | GPLv2+ex |
| Contact Center | Sí | Parcial | No | Sí | Solo dialer | Sí |
| Helpdesk | Parcial | Sí | Sí | No | No | No |
| Discador | Externo | No | No | Nativo | Nativo | Nativo |
| Telefónica | Kamailio+AS | No | No | Asterisk | Asterisk | Nativo |
| Multi-tenant | No | Sí | Sí | No | No | N/A |
| API REST | Sí | Sí | GraphQL | Parcial | Sí | Sí |
| WebSocket | Sí | Sí | Sí | No | Sí | Sí |
| Reutilizable | Referencia | MIT | Estudio | Algoritmo | Patrón ARI | Sustrato |
| Riesgo Legal | Alto | Bajo | Alto | Alto | Verificar | Bajo |
Clasificación por Utilidad
| Utilidad | Proyectos | Acción |
|---|---|---|
| Sustrato telefónica | Asterisk | Usar como servicio externo vía ARI |
| Referencia de diseño | Chatwoot, OMniLeads | Estudiar patrones, no código |
| Algoritmo de discador | VICIdial | Estudiar lógica de pacing |
| Patrón ARI | Omnidialer | Referencia de integración moderna |
| No usar código | Zammad, OMniLeads, VICIdial | Licencias restrictivas |
| Referencia de canales | Chatwoot | Patrón polimórfico (MIT) |
Decisiones Derivadas del Análisis
1. Telefónica: Asterisk vía ARI
- Nunca reimplementar SIP/RTP
- Comunicación vía REST + WebSocket
- Aplicación Go se conecta como cliente ARI
2. Canales: Patrón de Chatwoot
- Inbox polimórfico → Channel → Conversation → Message
- Adaptador por canal con interfaz común
- Licencia MIT permite referencia directa
3. Discador: Lógica de VICIdial
- Algoritmo adaptativo de pacing
- Reimplementar en Go, no copiar Perl/PHP
- Referencia conceptual, no código
4. Modelo de Dominio: OMniLeads como referencia
- Estados de campaña (4 estados)
- IVR como grafo
- Colas y routing
5. No Reutilizar Código de:
- Zammad (AGPL)
- OMniLeads (LGPL)
- VICIdial (AGPLv2, Perl/PHP legacy)
6. Verificar Licencia de:
- Omnidialer (sin licencia especificada)
- Cualquier dependencia nueva