Charla sobre el diseño de soluciones de PBX multitenant orientadas a operadores de telefonía y basadas en Asterisk. Estudio del caso real del diseño y desarrollo de PekePBX.
Esta charla fue dada en ElastixWorld 2016.
2. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
CONTEXTO
‣ VoIP2day2009: El Rombo
‣ 4K2012: Solución softswitch para operadores
‣ EW2013: Arquitecturas de operador de HostedPBX
‣ EW2014: Elastix3 (ElastixMT)
‣ EW2015: Escalabilidad de sistemas VoIP
3. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
BASADO EN HECHOS REALES
‣ PekePBX
‣ ¿Por qué tuve que desarrollarla?
4. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
OBJETIVOS
‣ Multitenant (multiempresa)
‣ Completamente orientada a ser manejada por el
usuario: 100% web.
‣ No soporte
‣ No personal cualificado
5. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
OBJETIVOS
‣ Seguro de vida: Tecnologías usadas
‣ Debian stable
‣ Asterisk 11
‣ Laravel
‣ AngularJS
‣ MySQL
http://www.barnetik.com
6. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
DESARROLLO PARTE I: DB
‣ Schema DB. Conceptos y relaciones:
‣ DID, Empresa, 3 niveles de usuario y 3 niveles de
acceso
‣ Destinos y aplicaciones: Usuario, IVR, locuciones,
Sala de conferencia, Moh, Voicemail, Grupos de
extensiones, Números externos, colas de
atención… etc
8. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
DESARROLLO PARTE II: LA WEB
‣ Web MINIMALISTA. No FreePBX
‣ No doc!
‣ Cada rol tiene sus tareas. 3 niveles de acceso
‣ Minimiza las opciones
‣ Responsive!
‣ Dos objetivos: Vender y evitar soporte
11. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
DESARROLLO PARTE II: LA WEB
‣ Administrador de empresa: Le gustan los colores y
las animaciones.
‣ Lo más importante es la configuración de entrantes
INTUITIVA. Son muchas opciones y a más
opciones más fácil es complicar la web.
‣ Recordamos objetivo: No debe tener que
llamarnos en el día a día.
17. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
DESARROLLO PARTE II: LA WEB
‣ Mención aparte para el CDR
‣ El CDR VENDE
‣ Tratad por todos los medios no facturar con él.
Usad un class5 para facturar por trunk de empresa
19. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
DESARROLLO PARTE II: LA WEB
‣ El rol usuario ha de sentirse cómodo
‣ Con el tiempo, querremos que la web de la PBX
sea un tab permanente en el browser.
21. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
DESARROLLO PARTE III: ASTERISK
‣ La configuración se adapta a la web, al db
schema.
‣ Tenemos toda la info en DB → Realtime
‣ ODBC por supuesto
‣ Elegimos Asterisk 11. Y puede que nos
arrepintamos
‣ Cuanto menos carguemos menos cosas pueden
fallar: modules.conf
22. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
DESARROLLO PARTE III: ASTERISK
‣ Dialplan
‣ No tiene sentido tener un contexto por empresa.
Debemos separar a nivel de variable
‣ Las entrantes no se pueden discriminar por trunk. Hay
que hacerlo por DID
‣ => Dialplan unificado para todas las empresas.
‣ from-pstn
‣ from-users
23. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
DESARROLLO PARTE III: ASTERISK
‣ Dialplan
‣ Tenemos que estar leyendo configuraciones en base
de datos continuamente
‣ La mayor parte de las lecturas de DB no requieren
tratamientos complejos sino setear variables de canal
‣ => func_odbc
24. [from-pstn]
exten => _X.,1,Verbose(Llamada entrante desde la PSTN ${CHANNEL(peername)} al número ${EXTEN})
same => n,Set(CDR(type)=incoming)
same => n,Set(CDR(src_callerid)=${CALLERID(num)})
same => n,Set(CDR(dst_dialed)=${EXTEN})
same => n,Gosub(sub_geolocation_caller,start,1)
same => n,Set(ARRAY(EMPRESA,DIDCUSTOM,DIDID)=${ODBC_DIDEMPRESA(${EXTEN})})
same => n,GotoIf($[${EXISTS(${EMPRESA})}]?:noasignado,1)
same => n,Set(CDR(dst_company)=${EMPRESA})
same => n,Verbose(El DID está asignado a la empresa ${EMPRESA})
same => n,GoSub(sub_record_call,start,1(${EMPRESA},${CDR(type)},${EXTEN},${CALLERID(num)}))
same => n,GotoIf($["${DIDCUSTOM}" == "1"]?sub_custom_${EMPRESA}_${EXTEN},start,1)
same => n,Set(IDTRATAMIENTO=${ODBC_DIDCONFIGURED(${DIDID})})
same => n,GotoIf($[${EXISTS(${IDTRATAMIENTO})}]?:notratamiento,1)
same => n,Agi(peke_processing.php,${IDTRATAMIENTO})
same => n,GotoIf($[${EXISTS(${PROMPT})}]?:destino)
same => n,Playback(${SOUNDPATH}/${EMPRESA}/${PROMPT})
same => n(destino),GoSub(sub_destination,start,1(${EMPRESA},${DESTINATION}))
exten => noasignado,1,Verbose(DID no encontrado o no asignado a empresa)
same => n,Hangup()
exten => notratamiento,1,Verbose(DID no está configurado)
same => n,Hangup()
25. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
RELEASES
‣ Tenemos la ventaja de controlar todo el
ecosistema. Podemos hacer releases y upgrades
de forma muy sencilla: Hagamos muchas y
pequeñas.
‣ Las nuevas funcionalidades han de venir
determinadas por la necesidad de la solución y no
por la necesidad de una empresa o la de un
comercial. Hay que saber decir NO
26. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
RELEASES
‣ Asume que vas a reescribir todo el dialplan al
menos dos veces. No esperes a tenerlo todo
perfecto para sacar la versión 1.0
‣ Prepara un roadmap y prepárate para no poder
cumplirlo porque el mercado te dictará las
necesidades. Sacarlo a producción es el mejor
roadmap.
27. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
FUTURAS RELEASES
‣ Cuando las funciones PBX ya estén estables y maduras…
Salgamos de la PBX y hagamos funciones diferenciadoras:
‣ Módulos:
‣ Salas de MultiVideoconferencia
‣ Chat, compartición de pantalla… centro de comunicaciones de
la empresa: Fidelización.
‣ Integración con sistema de soporte
‣ Integración con CRMs
‣ Etc...
29. DISEÑANDO UNA SOLUCIÓN MULTI-TENANT CON ASTERISK
ESCALABILIDAD
‣ Limitados por: CAPS, Registros, Keepalives
‣ Sacamos los registros a un proxy
‣ Balanceamos los usuarios por nodo de PBX
‣ Sacamos la DB a exterior y compartimos entre todos
los nodos
‣ Sacamos la web al exterior
‣ => Proxy lb/registrar + MySQL + Web Server + N
nodos asterisk para escalar