La entrada/salida de una aplicación asterisk

Asterisk 1 Comment

A la hora de pensar en una aplicación telefónica real en Asterisk, lo primero que como programador se me viene a la cabeza, es la forma en que se va a comunicar con el usuario. Esto es, la forma en que va a introducir los datos y va a obtener la información deseada.

asteriskEn una aplicación informática estándar, tenemos a disposición del usuario la pantalla del ordenador para mostrar información y un teclado y ratón con el que introducir los datos, sin embargo tenemos que tener en cuenta, que por muy potente que sea el programa que hemos desarrollado en asterisk, el usuario solo va a disponer de un pequeño auricular y un teclado numérico de 10 teclas (y en el peor de los casos, con los antiguos teléfonos analógicos, ni siquiera eso).

Actualmente, con el uso de los teléfonos móviles (y algunos fijos) tenemos la posibilidad de interactuar mediante mensajes SMS, lo cual ofrece una vía adicional de comunicación entre nuestra aplicación y el usuario, pero en este artículo nos centraremos mas en la comunicación basada en la telefonía tradicional.

La salida

El canal de salida estándar en nuestro caso el auricular del teléfono, mediante el cual podremos reproducir sonidos, grabaciones o incluso generar voces sintéticas mediante TTS (text to speech).

juegos de guerra

Una opción económica a la hora de elegir un motor TTS es Festival Speech Synthesis System (Festival para los amigos) una alternativa libre para generar voz sintética. Actualmente se encuentra en su versión 2.0 beta y soporta muchos idiomas y cuando digo muchos me refiero a bastantes. En cuanto a la calidad de la voz, no os voy a engañar, suena a máquina, os parecerá estar hablando con el ordenador de Juegos de Guerra (Que también tiene su encanto, oye!) pero las alternativas son aplicaciones comerciales de pago no asequibles a cualquier bolsillo. Entre las mas conocidas, Verbio y el famoso Loquendo.

La entrada

En cuanto al canal de entrada, la introducción de datos, la fórmula mas sencilla es la utilización del propio teclado del teléfono para introducir dígitos, esto nos limita a usar solo números y los caracteres especiales # y *. Por lo que nos vemos siempre obligados a utilizar códigos de usuario numéricos, contraseñas numéricas y menús organizados por números.

También existen actualmente sistemas de reconocimiento de voz aunque la mayoría aun no están muy depurados. Probablemente ya lo habréis sufrido alguna vez llamando al servicio técnico de alguna compañía (“Por favor, diga claramente el motivo de su llamada…”). El principal problema de estos sistemas es que no son fiables, requieren que el usuario hable claramente, vocalizando y sin ningún ruido de fondo, algo complicado si tenemos en cuenta la gran riqueza dialéctica de nuestro país.

gañan

“No le he entendido, por favor, repita el motivo de su llamada”

Mas adelante ya veremos como montar una aplicación básica en Asterisk usando Festival y el teclado numérico como entrada de datos. Así como la instalación y configuración del servicio Festival.

Integración de Asterisk con la agenda de eGroupWare

Asterisk, Desarrollo 6 Comments

Recientemente hemos descubierto las ventajas de la programación AGI en el dialplan de Asterisk, y nos preguntabamos si sería posible integrar una libreta de direcciones con asterisk de forma que se pudiera mostrar en el caller id el nombre del usuario que estaba llamando. De esta forma podremos ver en la ventana emergente de nuestro softphone (o en el display del teléfono IP) el nombre del contacto, en lugar del número desde el que está llamando.

En nuestro caso trabajamos con la libreta de direcciones de eGroupWare, y una vez localizada la base de datos y la tabla en la que se almacenan los contactos, el resto no supone mucho trabajo.

Empezaremos por editar el dialplan de nuestro Asterisk, e indicarle que todas las llamadas entrantes deben ser pasadas a nuestro script para comprobar si están en la libreta de contactos.

[entrantes]
exten => s,1,AGI(callerid.agi)  ;Reconocimiento del callerID
exten => s,2,Goto(horarios,s,1)  ;Comprobación del horario de oficina

A continuación crearemos nuestro script de reconocimiento de callerid. Para ello vamos a utilizar Python, pero igualmente lo podríamos haber hecho en Perl, Ruby o Php. La ventaja de la programación AGI es que es independiente del lenguaje que utilicemos, ya que la comunicación entre el dialplan y el AGI se realiza mediante la salida/entrada estándar.

Previamente hemos instalado en nuestro servidor la librería MySQLdb para Python que nos permitirá hacer consultas SQL a la base de datos de eGroupWare.

#!/usr/bin/python
#FILE: callerid.agi
 
import sys
import MySQLdb
 
# datos de la conexion SQL
host = 'avefenix'
user = 'USER'
password = 'PASS'
database = 'egroupware'

Recogemos todos los datos introducidos por la entrada estándar, aunque el unico que nos interesa es el campo ‘agi_callerid’ que es el que contiene el número teléfono entrante.

callerid = "Oculto" # por defecto
while 1:
        line = sys.stdin.readline().strip()
        if line =='':
                break
        key,data = line.split (':')
        if key  == 'agi_callerid':     #Extraemos la variable de entorno "agi_callerid"
                callerid=data.strip()	# Lo guardamos en la variable callerid
                break

Una vez obtenido el callerId conectamos con la base de datos, y le dejamos todo el peso de la operación de búsqueda a la consulta SQL. En nuestro caso vamos a buscar el teléfono en los campos de teléfono de trabajo, de casa, móvil y fax.

#Conectamos con la base de datos de Avefenix
db=MySQLdb.connect(host,user,password,database)
 
#Creamos un cursor para ejecutar la consulta
cursor = db.cursor()
 
#Hacemos la consulta SQL
cursor.execute('select n_fn,org_name from egw_addressbook where tel_work=' + callerid + ' or tel_cell=' + callerid + ' or tel_home=' + callerid + ' or tel_fax=' + callerid)

Una vez tenemos el resultado de la consulta, construimos un callerid con el nombre del contacto y la empresa a la que pertenece y se lo pasamos al dialplan mediante SET CALLERID, en caso de no encontrar ninguna coincidencia simplemente salimos y dejamos que el dialplan muestre el número de teléfono entrante.

# Cogemos el primer resultado
registro = cursor.fetchone()
 
# Si hemos encontrado al menos un resultado
if (registro != None):
        #Ponemos el nuevo callerId con el formato nombre(empresa)
        callerid = ''
        if (registro[0] != None): #Nombre del contacto
        		callerid = callerid + registro[0]
        if (registro[1] != None): #Empresa del contacto
        		callerid = callerid + '(' + registro[1] + ')'
 
        callerid = callerid.replace (' ','\ ') #Sustituimos los espacios por ‘\ ‘
 
        sys.stdout.write ("SET CALLERID " + callerid + "\n")
        sys.stdout.write ("VERBOSE El\ nuevo\ callerid\ de\ entrada\ es\ " + callerid + "\n")
        sys.stdout.flush ()
else:
        # si no hemos encotnrado el contacto en la BD
        sys.stdout.write ("VERBOSE No\ se\ ha\ encontrado\ el\ contacto\n")
        sys.stdout.flush ()

A continuación salvamos el script, en nuestro caso lo guardaremos en /var/lib/asterisk/agi-bin/callerid.agi, que será donde lo buscará nuestro dialplan. Reiniciamos Asterisk y vemos que funciona correctamente.

Aún nos quedan algunos problemas por resolver como puede ser la duplicidad de números en la agenda, o la visualización incorrecta de caracteres especiales como acentos y eñes, pero como una primera aproximación es una solución muy válida.

¡Hola mundo!

General 1 Comment

A modo de diario de a bordo, en parte para compartir libremente nuestro conocimiento y en parte para utilizarlo como una base de conocimiento propia, los integrantes de la empresa sevillana eNe Soluciones hemos dado el paso y nos hemos lanzado a la creación de este blog.

En eNe Soluciones estamos solidamente comprometidos con la filosofía del software libre, y a través de este blog queremos poner nuestro pequeño granito de arena en el mundo del conocimiento libre y devolver así en lo posible toda la ayuda prestada por parte de la comunidad.

Sean bienvenidos!

Next Entries »