Conquistando el Dialplan I. Aplicaciones Asterisk: Voicemail

Como ya sabemos, el Dialplan, plan de marcación, es el esqueleto en esencia de Asterisk. A partir de este se abre el sin fin de posibilidades que nos ofrece este sistema.

Solo el que conoce lo que ofrece el Dialplan al 100%, es aquel que realmente conoce Asterisk de verdad. Por ello, las series de documentación sobre Dialplan serán mensajes mas cortitos pero no por ello menos interesantes  y que ayudaran a organizar mejor la información.

Realmente ya vimos parte del potencial del Dialplan, con la creación de una operadora automática de coste cero, ahora vamos a ver las funciones de Buzón de Voz para nuestras extensiones. Aquí básicamente hay dos actores principales. La Aplicación Voicemail, y el fichero voicemail.conf

El fichero voicemail.conf puede llegar a ser todo lo complejo que deseemos en función de nuestras necesidades, pero voy a comentar un caso práctico en el que podemos ver diversa funcionalidad que podemos llegar alcanzar. Como la mayoría de los ficheros de Asterisk, se divide en contextos, como casi siempre, general, suele ser el genérico que afecta a todos los contextos por igual.

[general]
format=wav
//Formato de las grabaciones para el buzon de voz. Se admiten otros formatos como gsm.
serveremail=direccion@queenvia.com
//Direccion del remitente de los envios
attach=yes
// Para enviar el fichero adjunto en los emails con el audio
delete=yes
// Para permitir la opción de borrado del mensaje de voz local en el servidor una vez enviado por correo eletronico
maxmsg=100
// Maximo numero de mensajes permitidos en la bandeja local por buzon
maxsecs=180
// Maximos segundos por mensaje
minsecs=2
// Minimos segundos por mensaje para desechar los mensajes vacios o casi vacios
skipms=3000
// Opciones del mensaje de audio, para indexarlo cara a desplazamientos X ms adelante o detrás cuando sea reproducido en el pc del destinatario
maxsilence=10

// Silencio máximo permitido, esto es importante cara a poder desconectar la llamada en caso de silencio antes de cumplir el máximo posible caso 180 segundos (en nuestro ejemplo)
silencethreshold=128
// Este es el umbral de audio para el que consideramos que es un silencio, de aquí podemos ir mas abajo o mas arriba en función de nuestra necesidad, no hay un valor “ideal”
maxlogins=3
// Intentos de acceso a voicemail, en caso de sobrepasarlos, Asterisk desconectara al usuario de su cuenta SIP/IAX
emailsubject=Nuevo Mensaje de ${VM_CALLERID}
emailbody=Buenos días ${VM_NAME},\n\nHemos recibido un mensaje en su buzon de voz…
// Esto seria el asunto y el cuerpo del mensaje email. Aquí se pueden aprovechar variables para poder formatear el correo y mostrar datos quizá interesantes para el destinatario. Algunas de estas variables de ejemplo:
${VM_CALLERID}: El numero identificador del llamante (el número de teléfono)
${VM_NAME}: El nombre del dueño del buzon (lo definiremos más adelante)
${VM_DUR}: Duracion del mensaje
${VM_DATE}: Fecha y hora de recogida del mensaje
Mas variables pueden encontrarse aquí: en su correspondiente sección (tampoco son muchas más)
emaildateformat=%A, %B %d, %Y at %r
// Formato de la fecha para el email. Para la variable VM_DATE. Consultar el manual de date para mas información (# man date)

Con esto tenemos más que suficiente para componer mensajes para el buzon de voz y enviarlos por email. Ahora vienen los contextos. Como siempre, si es [default] es el genérico, y luego los contextos específicos. En principio vamos a poner uno genérico y uno especifico.
[default]
1234 => 5678,Buzon de Ejemplo,ejemplo@buzones.com
– En primer lugar, el número del buzón, luego lo utilizaremos en el Dialplan para la aplicación Voicemail así referirnos a este buzón
– En segundo lugar, la contraseña para acceder al buzón. Tendremos que crear una “extensión” en el Dialplan para que el usuario pueda acceder a su buzón de forma interna. Esto solo es útil si no marcamos la opción de borrado de mensajes del buzón al ser enviados por email
– En tercer lugar, nombre del buzón que luego utilizaremos en variables como VM_NAME
– En cuarto lugar, Email del destinatario de los mensajes de este buzón

Este es un ejemplo muy sencillo, pero a esto podríamos aplicarle un poco mas de complejidad al asunto

[extensiones]
1000 => 9878,Mr. Lenny, lenny@debian.net,,attach=yes|delete=1
– En quinto lugar, iria la dirección del Pager… muy poco utilizado a dia de hoy
– En último lugar, irían opciones especiales. En este caso, decimos que adjunto el mensaje, y lo borre a continuación. Si hemos activado las opciones en el contexto general, ira bien esto.

Si queremos hacer “broadcasting” de mensajes de buzon a varios emails, hay varios métodos pero el que a mi mejor me ha funcionado es hacerlo en combinación a aliases del servidor de correo (en nuestro caso al usar Ubuntu, por defecto, Postfix)

1001 => 8765, Dpto. de Botijos, botijos@nuestroservidor,,attach=yes|delete=1

Nos vamos a /etc/aliases y añadimos
botijos: sr.sanchez@botijoland.com,sr.perez@botijoland.com,sr.alvarez@botijoland.com

Y refrescamos aliases comando: # newaliases

Por ultimo no olvidemos recargar nuestro voicemail.conf #asterisk –rx ‘voicemail reload’

Ahora toca editar nuestro Dialplan para poder utilizar estos buzones recién configurados. Vamos al extensions.conf:

Si queremos por ejemplo hacer que los usuarios puedan dejar mensajes a nuestro contestador tenemos que utilizar la aplicación Voicemail
Ejemplo:

exten => 1000,1,NoOp()
exten => 1000,n,Dial(SIP/1000,30)
exten => 1000,n,Voicemail(1000@extensiones,u)
// En este caso, ponemos el número del buzón que pusimos antes @ el contexto al que pertenecía, adicionalmente ponemos una opción, para que antes de dar el pitido de “empezar a grabar” diga el mensaje de “en estos momentos no nos encontramos, deje su mensaje después de oír la señal”. Aquí tenemos varias, opciones, en vez de utilizar los mensajes por defecto que se pueden encontrar en la carpeta de sonidos /var/lib/asterisk/sounds/ todos los que empiezan por vm- tienen algo que ver con el buzón de voz y estas opciones. Las opciones posibles son:
sin opciones: se escuchan las instrucciones para dejar el mensaje
s: no se escucha nada (útil si queremos poner mensajes personalizados para cada usuario)
su: mensaje de no disponible
u: mensaje de no disponible + instrucciones
sb: mensaje de ocupado
b: mensaje de ocupado + instrucciones

Con esto también podemos jugar con las aplicaciones Playback y Record, para con la opción “s” crear un buzón acorde a las necesidades de un usuario en concreto

Por otro lado vendría la aplicación destinada a escuchar los mensajes guardados si no pusimos la opción de borrado automático: VoicemailMain. Tiene poca historia:
exten => 10001,1,VoicemailMain(1000@extensiones)
El tema es que a partir de ahí vendría un menú relativamente complejo, editable, y demás. Yo personalmente no lo utilizo ya que la función de envío a correo aparte de que me descarga el disco duro, hoy en día a la mayoría del personal le resulta formidable. Aun así, para aquellos que deseen profundizar, les dejo un enlace al manual por si acaso quieren probarlo. Cualquier consulta acerca de esto, no duden en comentármela!

En principio, con todo esto, ya se podrían componer sistemas de Buzón de voz bastante interesantes. Como ven no es demasiado complejo y existen muchas alternativas y opciones. Yo personalmente opino que las opciones de envío a correo, todavía están muy poco elaboradas, pese a que se ha profundizado en ellas. Yo personalmente no he encontrado opciones por ejemplo, de envío CC o CCO (BCC) para envíos broadcasting (lo cual me resultaría muy interesante). Supongo que sería una cuestión de apoyar programando, al proyecto Asterisk. Quien sabe, a lo mejor más adelante nos animamos a ello.

Creando una Operadora Automatica de Coste Cero I

Es curioso observar que el 99,99% de sistemas de operadoras automaticas de las PBX de marcas reconocidas como Alcatel-Lucent, Panasonic, Siemens, el coste de poseer un sistema de operadora automatica, o IVR (interactive voice response), sea directamente proporcional al numero de canales entrantes de voz. Y la pregunta es, ¿realmente estas operadores ofrecen algo mas que no podamos obtener a traves de nuestro magnifico sistema Asterisk? La respusta no solo es negativa, sino que ademas podemos discriminar que vamos a ser capaces a traves de nuestro plan de marcacion de realizar operaciones totalmente casi inimaginables para estas centralitas de alto nivel, al menos, sin una dificultad de alto standing.

¿Pero no se supone que las PBX de marcas reconocidas poseen interfaces de configuracion ampliamente escalables y de relativa facil configuracion? Solo si queremos hacer funciones, que no sobrepasen el nivel del mar.

Y eso es lo que vamos a tratar de hacer hoy, pero sin ir demasiado lejos, solo andando un poco por la arena.

Segun veiamos el otro dia con respecto a los Gateways, y la capacidad de recibir llamadas entrantes, vamos a plantear un nuevo contexto dentro del DialPlan en el que manejemos dichas llamadas a nuestra voluntad.

Partiendo de la base:

[desde-rdsi]
exten => 987654321,1,NoOp()
exten => 987654321,n,Answer
exten => 987654321,n,Goto(operadora,s,1)

Tenemos la instruccion Goto, que nos permite desplazarnos a otro contexto (operadora), marcacion de extension (s) y prioridad (1). Ya hemos hablado sobre las prioridades y los contextos. ahora voy a hacer una breve reseña sobre las marcaciones de extension.

Por un lado existen las marcaciones especiales:

s viene de start, suele ser, la marcacion de inicio de todo contexto, una extension comodin para dejar claras las cosas por regla general.
i viene de invalid, en caso que marquemos una extension que no pertenezca a un contexto, entonces iremos a esta marcacion de extension
t viene de timeout simple, seria el caso de que se acabe el tiempo por una aplicacion que tenga expiracion de tiempo, como WaitExten
T viene de timeout absoluta, existe una variable global (ya veremos variables locales y globales en otro momento) llamada TIMEOUT que establece el tiempo total que se permite mantener una llamada en activo, en el momento que expira este tiempo, entonces saltariamos a la T del contexto que nos encontremos

Por otro lado existen las extensiones normales, y los patrones

Una extension normal simplemente es un numero cualquiera
Un patron viene precedido por un guion bajo  “_” y permite que se puedan crear patrones de posibles extensiones numericas. Informacion detallada sobre esto, la explico en un post mas antiguo

Ahora ya que sabemos lo que necesitamos saber sobre extensiones comenzamos con nuestro contexto de IVR

[operadora]
exten => s,1,NoOp
exten => s,n,Answer()
exten => s,n, GotoifTime(8:00-14:00,mon-fri,*,*?abierto,s,1)
exten => s,n,GotoifTime(16:00-18:00,mon-fri,*,*?abierto,s,1)
exten => s,n,GotoifTime(*,mon-fri,1,jan?festivo)
exten => s,n,Playback(fueradehorario)
exten => s,n,Voicemail(100@default)
exten => s,n,Hangup
exten => s,n(festivo),Playback(festivo)
exten => s,n,Voicemail(100@default)
exten => s,n,Hangup

Esto podria ser la estructura de una eficaz “introduccion” a nuestra operadora automatica. Leyendolo rapidamente, lo que tratamos de hacer es que salte al contexto “abierto” en caso que la llamada se encuentre en horario lectivo de la empresa, o que salte a la etiqueta “festivo” en caso que coincida que es dia de fiesta. En otro caso, lanzara un mensaje de “estamos cerrados”, saltara un buzon de voz para dejar mensajes y colgara, en caso que salte a la etiqueta “festivo”, algo parecido, un mensaje diciendo que es dia festivo en la empresa, buzon de voz y cuelgue.

Realmente esto se podria usar incluso como plantilla para miles de centralitas de PYMES y SOHO y ofreceria una configuracion basica, potente y eficaz, sin tener que andar merodeando en miles de interfaces graficas que pueden dar lugar al error facilmente. Esta claro que este blog esta dedicado a gente especializada en el mundo de la informatica y/o las telecomunicaciones por lo que trabajar sobre una pantalla con fondo negro y letras blancas no deberia ser demasiado drama y mas alla aun, deberia ser una gratificacion excepto en contados casos.

Figura 1: “No exige aprender Linux o Scripting” Como si fuera algo malo

Ahora vamos alla con el detalle. En primer lugar vamos a introducir la aplicacion GotoifTime:

Como vimos con Goto, es equivalente, pero introduciendo una condicion temporal. Para los conocedores de Cron, esto es equivalente.

En primera posicion, especificamos hora o rango horario, incluso varios rangos horarios. Por nuestro ejemplo podriamos haberlo resumido con:

exten => s,n, GotoifTime(8:00-14:00,mon-fri,*,*?abierto,s,1)
exten => s,n,GotoifTime(16:00-18:00,mon-fri,*,*?abierto,s,1)

por

exten => s,n,GotoifTime(8:00-14:00|16:00-18:00,mon-fri,*,*?abierto,s,1). Dos pajaros de un tiro como quien dice.
El segundo parametro, es el dia de la semana, en ingles, los tres primeros caracteres, y ocurre lo mismo que con las horas, rangos, multiples rangos, etc.
El tercer parametro, es el dia del mes y el cuarto, el mes en ingles y los tres primeros caracteres igual. El resto es equivalente a a la aplicacion Goto.

Ademas aqui hemos introducido las etiquetas aparte de los contextos. Una etiqueta se ubica en una parte de la prioridad, esto es util cuando como ocurre en mis ejemplos en vez de poner prioridades del tipo, 1 2 3, etc pongo siempre n considerando lo de n+1 y queremos saltar a otra prioridad sin tener que saber la posicion relativa (esto nos permite la maxima genericidad en nuestros planes de marcacion y la capacidad de insercion futura en casos complejos).

Sobre los ultimos dos parametros, dia del mes y mes, hay que considerar que esto permite mucho “poder” para crear genericidad a lo largo de los años, como son el caso de los dias festivos. En nuestro ejemplo decimos: Si es lunes a viernes y ademas cae el 1 de Enero entonces es festivo. Aunque sea lo que sea realmente es festivo este seria un ejemplo especifico de la posibilidad saltar al contexto dia festivo realmente en estos dias, y si fuera un sabado o un domingo, como ya es festivo de por si, que de el otro mensaje (El de cerrado simplemente) . Opciones hay muchas y esto quedaria a nuestra libertad.

Mas alla aun, asterisk 1.8 tengo entendido que incluso existe la posibilidad de crear calendarios con Google Calendar y desde ahi especificar los dias festivos y toda la informacion relativa a tiempos. Hay mas informacion aqui, y esto nos ofreceria un nivel de potencia a bajo coste de complejidad para nuestro IVR que ninguna otra central se acercaria lo mas minimo. Ahora ya podemos decir que estamos sobre el nivel del mar, y eso que no hemos empezado siquiera en este mundillo.

Por otro lado, tenemos la aplicacion Playback. Simplemente reproduce un archivo de musica que tengamos en la carpeta correspondiente en funcion de nuestro lenguaje definido. Los sonidos se encuentran en /var/lib/asterisk/sounds/

Finalmente esta la aplicacion Voicemail, que basicamente llama a otro archivo de musica (“deje su mensaje despues de oir la señal”) y guarda el mensaje de voz en el buzon especificado (100) del contexto por defecto (@default). Todo esto podemos verlo y configurarlo en el archivo de configuracion voicemail.conf que seguramente veremos en otro momento.

Y ahora ¿que ocurre con las llamadas que van al contexto “abierto”?

Vamos a hacer algo sencillito en abierto para terminar por hoy, y mas adelante intentaremos profundizar aun mas en todo esto.

[abierto]
exten => s,1,NoOp
exten => s,n,Background(listadistribucion)
exten => s,n,WaitExten(20)

exten => 1,1,NoOp
exten => 1,n,Goto(comercial,s,1)

exten => 2,1,NoOp
exten => 2,n,Goto(postventa,s,1)

exten => t,1,NoOp
exten => t,n,Goto(telefonista,s,1)
exten => t, n,Goto(s,1)

Voy a leerlo: primero, saltaria un mensaje, que diria “Bienvenido a nuestra empresa, Marque el 1 para hablar con Comercial o Marque el 2 para hablar con Posventa, en otro caso espere y le pondremos con un Agente”. En caso de marcar el 1, le mandaria al contexto comercial, y en caso de marcar el 2, a postventa. En caso de “Timeout simple” le mandaria al telefonista.

Aqui solo tenemos dos aplicaciones que no vimos hasta el momento:

Background es equivalente a Playback pero deja a la espera de marcacion de una extension. Podemos interrumpir el background si marcamos teclas en el telefono y saltaria a la extension del contexto marcada (hay mas opciones complejas, como saltar a extensiones de otros contextos pero no voy a entrar en detalles)

Por otro lado Waitexten, basicamente establece el tiempo que tenemos para marcar una extension antes de ir a la extension especial “t”.

Parece sencillo, y lo es. Asi que invito a hacer mil combinaciones con toda esta información para crear posibles IVR sencillitos que cumplan una funcion que para la mayoria de las PBX del mercado suele ser bastante compleja y obliga a pasar por miles de secciones de la interfaz grafica. Por esto, es suficiente por hoy. Seguiremos informando como suele decirse