jueves, 3 de noviembre de 2011

Directorio de llamado en asterisk

En este documento detallaremos los pasos necesarios para implementar un Directorio de llamado. Esto se utiliza por ejemplo cuando queremos llamar a alguien y no sabemos su interno. Supongamos que tenemos un IVR que nos recibe de la siguiente

“Gracias por comunicarse con   Mi Empresa SRL ….……para comunicarse con  Ventas marque 1… para  comunicarse con Soporte  marque 2 …. Para comunicarse con Administración  marque 3… para enviar un fax presione 4… para acceder al directorio presione 9  sino aguarde y será atendido por una operadora.”

Si seleccionamos la opción 9 nos aparecerá un mensaje que dirá:

“Bienvenido al directorio asterisk, por favor introduzca las 3 primeras letras del apellido de la persona que busca, por ejemplo 3 para la D o 5 para la L.”

Para configurar el directorio debemos realizar  los siguientes pasos:

Para agregar la opción 9, en el contexto  menu-dia en el archivo extensions.conf debemos agregar la línea exten => 9,1,Directory(default,phones,e)
[phones]
include => internal
[internal]
exten => _2XXX,1,Dial(SIP/${EXTEN},10) ; llamados de ext 2xxx
exten => _2XXX,n,VoiceMail(${EXTEN}@default,u)
exten => _2XXX,n,Playback(vm_goodbye) ; 
exten => _2XXX,n,Hangup() ; cuelga la comunicación
;llamando al interno 2000 entra al IVR segun el horario ejecuta el mensaje
exten => 2000,1,GotoIfTime(9:00-18:00|mon-fri|*|*?menu-dia,s,1)
exten => 2000,2,GotoIfTime(18:01-8:59|mon-fri|*|*?menu-noche,s,1) 
[menu-dia]
exten => s,1,Answer
exten => s,n,Wait(0.5)
exten => s,n,Background(menudia2) ; reproduce el mensaje grabado
exten => s,n,WaitExtend(5)
exten => 1,1,Goto(internal,2001,1);opcion 1 redirecciona a la ext 2001
exten => 2,1,Goto(internal,2002,1);opcion 2 redirecciona a la ext 2002
exten => 2,1,Goto(internal,2003,1);opcion 3 redirecciona a la ext 2003
exten => 9,1,Directory(default,phones,e) ;la opcion 9 redirige al directorio
exten => *,1,Goto(s,1) ; vuelve a reproducir el menu principal con la tecla asterisco
exten => t,1,Playback(goodbye) ; si esta mucho tiempo sin hacer nada despide y cuelga
exten => t,n,Hangup()
exten => i,1,Playback(pbx-invalid) ; si el numero digitado no es valido comunica el error
exten => i,n,goto(s,1) ;vuleve al menu principal del IVR

Se agrega la siguiente línea al contexto features.

[features]
exten => 2000,1,Goto(menu-dia,s,1) ; llamando a la ext 2000 ingresa al menu del IVR


Se agrega la siguiente línea al contexto default ubicado en /etc/asterisk/voicemail.conf



[default]

1234 => 4242,Example Mailbox,root@localhost
2001 => 1234,Ventas,pepe@midominio.com.ar
2002 => 1234,Compras,asterisk@midominio.com.ar
2003 => 1234,Soporte

TIPS= Siempre debemos definir los contactos en el voicemail para que puedan ser ubicados con la función Directory(), de lo contrario no ubicara a la persona.

 se realiza la prueba llamando al interno 2000 donde tendría que escucharse el IVR, 
elegimos la opción 9 y nos pedirá que ingresemos las 3 primeras letras del nombre de 
la persona/sector que deseamos ubicar, la operadora nos deletreara el nombre completo
con la extensión a la que pertenece y si es esa la extensión nos pide que pulsemos la tecla “1”.


Cómo funciona el IVR con directorio.

En este ejemplo veremos cómo utilizar el directorio si se desea llamar al sector Compras.

Una vez que ingresamos la opción 9, la operadora nos dice el siguiente mensaje:

“Bienvenido al directorio asterisk, por favor introduzca las 3 primeras letras del apellido de la persona que busca, por ejemplo 3 para la D o 5 para la L.”

1-      Ingresamos las 3 primeras letras del apellido o sector, en este caso “C”,”O”,”M”.

2-      La operadora nos deletrea el sector junto con el interno que tiene asociado. Deletreara los siguiente “C””O””M””P””R””A””S”… INTERNO ”2””0””0””2”.

3-      Si el nombre es el correcto presione la tecla “1” y se realizara la llamada a ese interno.

4-      En caso de que este mal el sector que nos informa presionaremos * para volver a realizar el paso 1.

La sintaxis para la función Directory es la siguiente:

exten => 9,1,Directory(default,phones,f) ;

default= contexto en el archivo voicemail.conf donde se declaran los contactos a ubicar

phones=contexto  de las llamadas internas en el archivo extensions.conf

f/e= la opción f realiza la búsqueda por apellido, y con la opción “e” por nombre

Rellamada en asterisk

En este documento detallaremos los pasos necesarios para configurar la función rellamada si el interno esta ocupado.  En este caso si llamamos a un interno que esta ocupado presionamos la tecla 6 para dejar la rellamada y cuando el mismo se desocupe le dará la opción  de aceptar la rellamada, si la misma es aceptada  llama al llamante indicando que el interno se ha desocupado.

En el archivo/etc/asterisk/extensions.conf agregamos las siguientes líneas
[local-sip]
include => training
exten => _4XXX,1,Macro(internos)
exten => _40XX,2,Playback(hello-world)
exten => _40XX,3,Hangup()
[macro-internos]
exten => s,1,Answer()
exten => s,n,Wait(1)
exten => s,n,Set(ID=${CALLERID(num)})
exten => s,n,Dial(SIP/${MACRO_EXTEN},30,tTwmkKxX)
exten => s,n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail)
exten => s,n(unavail),Voicemail(${MACRO_EXTEN}@default,u)
exten => s,n,Hangup()
exten => s,n(busy),Playback(rellamada)
exten => s,n,Read(callbusy,,1,,1,5)
exten => s,n,GotoIf($["${callbusy}" = "6"]?callfile)
exten => s,n,VoiceMail(${MACRO_EXTEN}@default,b)
exten => s,n,Hangup()
exten => s,n(callfile),System(echo Channel:SIP/${MACRO_EXTEN} >> /tmp/callback${MACRO_EXTEN})
exten => s,n,System(echo Callerid:CallBack "<VozToVoice>" >> /tmp/callback${MACRO_EXTEN})
exten => s,n,System(echo WaitTime:30 >> /tmp/callback${MACRO_EXTEN})
exten => s,n,System(echo Maxretries:10 >> /tmp/callback${MACRO_EXTEN})
exten => s,n,System(echo RetryTime:30 >> /tmp/callback${MACRO_EXTEN})
exten => s,n,System(echo Account: ${ID}>> /tmp/callback${MACRO_EXTEN})
exten => s,n,System(echo Application:Dial >> /tmp/callback${MACRO_EXTEN})
exten => s,n,System(echo Data: SIP/${ID} >> /tmp/callback${MACRO_EXTEN})
exten => s,n,Wait(1)
exten => s,n,System(mv /tmp/callback${MACRO_EXTEN} /var/spool/asterisk/outgoing)
exten => s,n,Hangup()
exten => h,1,Hangup

NOTA: Debemos grabar el archive wav rellamada.wav y colocarlos en el directorio /var/lib/asterisk/sounds/es.

Definimos nuestro dialplan en [local-sip], cuando llamamos a un interno la línea exten => _4XXX,1,Macro(internos) salta a [macro-internos], esta macro si el interno esta ocupado nos da la opción de activar la rellamada si marcamos el numero 6.

Explicación de la  macro [macro-internos]

exten => s,1,Answer() ; asterisk contesta el canal

exten => s,n,Wait(1) ; espera un segundo

exten => s,n,Set(ID=${CALLERID(num)}); asigna a la variable ID el número de la extensión del llamante

exten => s,n,Dial(SIP/${MACRO_EXTEN},30,tTwmkKxX) ; llama la extensión

exten => s,n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail) ; si la extensión está ocupada va a la prioridad con etiqueta busy, si no está disponible a la prioridad con la etiqueta unavail

exten => s,n(unavail),Voicemail(${MACRO_EXTEN}@default,u) ; envía la llamada al contestador automático anunciando que la extensión no se encuentra disponible

exten => s,n,Hangup() ; cuelga la llamada

exten => s,n(busy),Playback(rellamada) ; en el caso que la extensión llamada esté ocupada anunciaremos que presionando la tecla 6 del teléfono podremos ser rellamados cuando la extensión se encuentre libre. Podemos hacer esto con Cepstral, Festival o creando un archivo audio que luego copiamos en la carpeta /var/lib/asterisk/sounds/es. En este ejemplo se está usando el archivo grabado

exten => s,n,Read(callbusy,,1,,1,5) ; la variable Read espera que el llamante presione una tecla

exten => s,n,GotoIf($["${callbusy}" = "6"]?callfile) ; si la tecla presionada es el 6 se seguirá procesando la llamada en la prioridad con etiqueta callfile. De lo contrario se seguirá enviando la llamada al contestador automático anunciando que la extensión se encuentra ocupada.

exten => s,n,VoiceMail(${MACRO_EXTEN}@default,b)

exten => s,n,Hangup()

exten => s,n(callfile),System(echo Channel:SIP/${MACRO_EXTEN} >> /tmp/callback${MACRO_EXTEN}) ; Aquí empieza la creación del call file. Asterisk llamará la extension ocupada

exten => s,n,System(echo Callerid:CallBack "<VozToVoice>" >> /tmp/callback${MACRO_EXTEN}) ; definimos el identificativo de la llamada

exten => s,n,System(echo WaitTime:30 >> /tmp/callback${MACRO_EXTEN}) ; Espera 30 segundos para que conteste

exten => s,n,System(echo Maxretries:10 >> /tmp/callback${MACRO_EXTEN}) ; número máximo de intentos (10)

exten => s,n,System(echo RetryTime:30 >> /tmp/callback${MACRO_EXTEN}) ; tiempo (en segundos) entre un intento y otro

exten => s,n,System(echo Account: ${ID}>> /tmp/callback${MACRO_EXTEN}) ; número de cuenta para el registro de las llamadas

exten => s,n,System(echo Application:Dial >> /tmp/callback${MACRO_EXTEN}) ; aplicación que se usará (dial)

exten => s,n,System(echo Data: SIP/${ID} >> /tmp/callback${MACRO_EXTEN}) ; número del llamante que asterisk conectará con la extensión ocupada una vez que esté libre.

exten => s,n,Wait(1) ; espera un segundo

exten => s,n,System(mv /tmp/callback${MACRO_EXTEN} /var/spool/asterisk/outgoing) ; mueve el archivo creado en la carpeta usada por asterisk para procesar los Call Files

exten => s,n,Hangup() ; cuelga la llamada

exten => h,1,Hangup ; cuelga la llamada si el llamante cuelga estando en cualquier línea de la macro

Diagrama de funcionamiento de rellamada



Cómo funciona el desvío de llamada.

1-      En este ejemplo vemos una llamada ya establecida entre el interno 2001 y el  interno 2002, cuando el interno 2003 intenta llamar al 2002 le da ocupado y un mensaje anuncia que se puede dejar la rellamada presionando la tecla 6. Una vez que finaliza la comunicación entre el interno 2001 y 2002, si se activo la rellamada suena el interno 2002 indicando que hay una rellamada del 2003,  si es acepada entonces suena el 2003 y se establece la  comunicación.