domingo, 25 de enero de 2015

IMPLEMENTACIÓN DE UN IVR (INTERACTIVE VOICE RESPONSE) UTILIZANDO MySQL Y PHPAGI

Call Center Video_6

IVR es una plataforma de desarrollo de aplicaciones telefónicas, que permite diseñar, integrar, implementar y administrar sistemas de respuesta interactiva de voz
Es implementado en empresas que reciben grandes cantidades de llamadas, a fin de reducir la necesidad de personal y los costos que el servicio ofrecido representa para la empresa
IVR tiene capacidad para atender miles de llamadas al día, permitiendo a sus clientes recibir información, consultar y modificar bases de datos, vía telefónica y transferirse con una persona, cuando así lo requieran por medio de varios menús con múltiples opciones de marcado para satisfacer las necesidades del cliente


AGI (Asterisk Gateway Interface) 
Es una manera de interactuar con Asterisk desde un script. Este programa puede ser escrito en PHP y es llamado por Asterisk desde el dial plan. El ejemplo será el desarrollo de aplicaciones de consulta telefónica a bases de datos que se explicara a continuación.
El Asterisk Gateway Interface (AGI) permite desarrollar aplicaciones externas que pueden interactuar con Asterisk. Estas aplicaciones pueden estar escritas en distintos lenguajes de programación como por ejemplo librerías en PHP que simplifican su escritura, haciendo modificaciones a bases de datos, consultas a estados de variables, controlar el dIalplan, etc, todo esto haciendo la llamada desde el archivo extensions.conf
¿Cómo Funciona?
La comunicación entre Asterisk y el AGI se apoya a los “files descriptors” del sistema operativo Linux que permiten una comunicación entre el Kernel y la aplicación que quiere acceder a un determinado archivo/programa. En Linux. Los tres estándares que se utilizan son:
•STDIN
•STDOUT
•STDERR
Esto permite escribir el AGI utilizando prácticamente cualquier lenguaje de programación. Para el IVR que se implementara en el call center, se utilizarán la librería PHPAGI y PHP.


INSTALACIÓN PHPAGI
Ya se tiene la librería php.agi, a continuación se descomprime:
tar -xf phpagi-2.20.tgz
se entra en la carpeta creada:
cd phpagi-2.20
y se copian las dos librerías AGI en la carpeta agi-bin de Asterisk:
cp phpagi.php /var/lib/asterisk/agi-bin
cp phpagi-asmanager.php /var/lib/asterisk/agi-bin
se vuelven los archivos ejecutables:
chmod 755 /var/lib/asterisk/agi-bin/phpagi.php
chmod 755 /var/lib/asterisk/agi-bin
/var/lib/asterisk/agi-bin

EJEMPLO:
nano ejemplo.php
#!/usr/bin/php –q
Esta línea le dice al Sistema que va a utilizar un intérprete para ejecutar un script en lenguaje PHP, la opción –q desactiva los mensajes de error que puede enviar HTML, es muy Importante que después del "?" y el ">" del 'fin del PHP' no debe haber ni siquiera un [ENTER]
<?php
require('phpagi.php');
Llamamos a las librerías de phpagi
error_reporting(E_ALL);
Activamos la bandera de enviar todo lo que se realice a consola como modo depuración
$agi = new AGI();
Creamos una instancia de la clase AGI
$agi-> answer();
Generamos el comando Answer de Asterisk, este comando siempre lo ejecutamos al inicio de un AGI
$callerid = $agi->request['agi_callerid'];
Obtenemos el caller id de quién realiza la llamada
$agi->text2wav("Hola extension $callerid");
Enviamos un mensaje de voz por medio de festival, en este caso en ingles
$agi-> hangup();
al finalizar el script del AGI siempre es recomendable ejecutar esta función para no dejar el canal abierto
?>
Se vuelve ejecutable el archivo:
chmod +x /var/lib/asterisk/agi-bin/ejemplo.php
Se modifica el dialplan para añadir el AGI:
exten => 250,1,Agi(ejemplo.php)

Como se vio en el ejemplo anterior, Festival en Elastix viene instalado pero sin ninguna voz en español, además, la calidad no es muy buena, es por esto que es necesario instalar las especificaciones de las voces. Existe un proyecto de la Junta de Andalucía, el cual consiste de dos paquetes (para Debian) que contienen una voz masculina y otra femenina para Festival.
Se verá como convertir los paquetes debian (.deb) a CentOS (.rpm) utilizando el programa Alien y también como cambiar la configuración de Festival para que se puedan utilizar en Asterisk.
cd /usr/src
tar –xf alien_8.78.tar.gz
cd alien
perl Makefile.PL
make
make install

Ahora con los dos paquetes Debian con las voces en español para festival, estos se trasformaran a paquetes en .rpm asi:
alien –rv festvox-palpc16k_1.0-1_all.deb
alien –rv festvox-sflpc16k_1.0-1_all.deb

Llegados a este punto podemos instalar los dos paquetes para CentOS:
rpm –ivh festvox-palpc16k-1.0-2.noarch.rpm
rpm –ivh festvox-sflpc16k-1.0-2.noarch.rpm

En la carpeta /usr/share/festival/voices/spanish encontraremos estas dos carpetas:
JuntaDeAndalucia_es_pa_diphone
JuntaDeAndalucia_es_sf_diphone
Luego es necesario hacer que "Festival" use la nueva voz de forma predeterminada, se edita el archivo /usr/share/festival/siteinit.scm y al final se ponen las siguiente línea, recordar que en el paquete de voces se incluyen 2 voces, una voz masculina y otra femenina, esta será la voz masculina

(set! voice_default 'voice_JuntaDeAndalucia_es_pa_diphone)
Por último se editara en las librerías phpagi, el archivo de configuración de phpagi que trae Elastix (/etc/asterisk/phpagi.conf) en el cual hay que configurarle el path hacia la aplicación "text2wave" que es la que se utilizara como se vio en el ejemplo.
[festival]
text2wave= /usr/bin/text2wave


BASES DE DATOS A UTILIZAR EN EL IVR


create database usuario
create database promo


create table datos(
ci int(8) null,
clave int(4) null,
saldo float null
);

insert into datos (ci,clave,saldo) values (76324167,1234,100)
insert into datos (ci,clave,saldo) values (25269245,4321,200)


create table cosas(
id int not null auto_increment primary key,
descripcion char (100) null,
valor float null,
dias int(3) null
)

insert into cosas (id,descripcion,valor,dias) values (null,'monitores 25 por ciento de descuento', 50,15)
insert into cosas (id,descripcion,valor,dias) values (null,'Discos duros 10 por ciento de descuento', 35,8)
insert into cosas (id,descripcion,valor,dias) values (null,'memorias RAM 15 por ciento de descuento', 8,7)


DISEÑO DEL IVR
archivo extensiosn.conf

exten => 01800123,1,Goto(entrante,s,1)

[entrante]

exten => s,1,Answer()
same => n,Background(/var/lib/asterisk/sounds/custom/grabacion15)
same => n,WaitExten(5)

exten => i,1,Playback(pbx-invalid)
same => n,Goto(entrante,s,1)

exten => t,1,Playback(thank-you-for-calling)
same => n,Dial(SIP/4003)
same => n,Voicemail(4003@agentes)


exten => 1,1,Macro(llamadas,SIP/4001)
exten => 2,1,Macro(colas,${COLA1})
exten => 3,1,Macro(colas,${COLA2})
exten => 4,1,Playback(conference-call)
exten => 4,2,Goto(conferencia,s,1)
exten => 5,1,Goto(ivr,s,1)

#include ivr.conf


archivo ivr.conf

[ivr]

exten => s,1,Answer()
same => n,Background(/var/lib/asterisk/sounds/custom/grabacion11)
same => n,WaitExten(5)

exten => 1,1,AGI(cuenta.php)
same => n,Goto(ivr1,s,1)

exten => 2,1,Set(tabla=datos)
same => n,Background(/var/lib/asterisk/sounds/custom/grabacion05)
same => n,Read(ci,number&astcc-followed-by-the-pound-key)

same => n,Background(/var/lib/asterisk/sounds/custom/grabacion06)
same => n,Read(clave,number&astcc-followed-by-the-pound-key)

same => n,AGI(datos.php,${tabla},${ci},${clave})
same => n,Dial(SIP/4002,5)

exten => i,1,Playback(pbx-invalid)
same => n,Goto(ivr,s,1)

exten => t,1,Playback(thank-you-for-calling)
same => n,Dial(SIP/4002)
same => n,Voicemail(4002@agentes)

archivo cuenta.php

#!/usr/bin/php -q
<?php

require('/var/lib/asterisk/agi-bin/phpagi.php');

error_reporting(E_ALL);

$agi = new AGI();

$agi->answer();

$conexion = mysql_connect('localhost','root','123456') or die(mysql_error());

mysql_select_db('usuario',$conexion);

$aux=0;

do
{
$aux=$aux+1;

$agi->text2wav("por favor, ingrese su numero de cedula");
$_result=$agi->get_data('beep',20000,8);
$keys=$_result['result'];

if($keys!=""){
$query="select clave from datos where ci=\"$keys\"";
$_result=mysql_query($query,$conexion);}

if($_re=mysql_fetch_array($_result)){
$agi->text2wav("ha sido encontrado en nuestra base de datos, su clave actual es:");
$agi->say_digits($_re[clave]);
$aux=5;}

else{
$agi->text2wav("No ha sido encontrado en nuestra base de datos");
mysql_close();
}


archivo datos.php

#!/usr/bin/php -q
<?php

//llamamos a las librerias de phpagi
 require('/var/lib/asterisk/agi-bin/phpagi.php');

//activamos la bandera de enviar todo lo que se realice a consola como modo depu$
 error_reporting(E_ALL);

//creamos una instancia de la clase AGI
$agi = new AGI();

$agi->answer();

$conexion = mysql_connect('localhost','root','123456') or die (mysql_error());
mysql_select_db('usuario',$conexion);

//argumentos recibidos de asterisk
$id = $_SERVER['argv'][1];   //valor 1: tabla
$id2 = $_SERVER['argv'][2];   //valor 2: ci
$id3 = $_SERVER['argv'][3];   //valor 3: clave

$sql = "INSERT INTO $id (ci,clave) VALUES ( '$id2', '$id3')";
$result = mysql_query( $sql, $conexion );
mysql_close();

$agi->text2wav("a continuacion sera transferido a una operadora para completar e$

?>



archivo actualizar.php

#!/usr/bin/php -q
<?php

//llamamos a las librerias de phpagi
 require('/var/lib/asterisk/agi-bin/phpagi.php');

//activamos la bandera de enviar todo lo que se realice a consola como modo depuracion
 error_reporting(E_ALL);

//creamos una instancia de la clase AGI
$agi = new AGI();

$agi->answer();

$conexion = mysql_connect('localhost','root','123456') or die (mysql_error());
mysql_select_db('usuario',$conexion);

//argumentos recibidos de asterisk
$id = $_SERVER['argv'][1];   //valor 1: tabla
$id2 = $_SERVER['argv'][2];   //valor 2: ci
$id3 = $_SERVER['argv'][3];   //valor 3: clave

$agi->text2wav("su nueva clave es:");
$agi->say_digits($id3);

$sql = "update datos set clave = $id3 where ci = $id2";
$result = mysql_query( $sql, $conexion );
?>

archivo actualizar.php

#!/usr/bin/php -q
<?php

//llamamos a las librerias de phpagi
 require('/var/lib/asterisk/agi-bin/phpagi.php');

//activamos la bandera de enviar todo lo que se realice a consola como modo depuracion
 error_reporting(E_ALL);

//creamos una instancia de la clase AGI
$agi = new AGI();

$agi->answer();

$conexion = mysql_connect('localhost','root','123456') or die (mysql_error());
mysql_select_db('usuario',$conexion);

//argumentos recibidos de asterisk
$id = $_SERVER['argv'][1];   //valor 1: tabla
$id2 = $_SERVER['argv'][2];   //valor 2: ci
$id3 = $_SERVER['argv'][3];   //valor 3: clave

$agi->text2wav("su nueva clave es:");
$agi->say_digits($id3);

$sql = "update datos set clave = $id3 where ci = $id2";
$result = mysql_query( $sql, $conexion );
?>

archivo saldo.php

$aux=1;
do
{
if($aux==1)
$agi->text2wav("por favor ingrese su clave");

else $agi->text2wav("clave no encontrada");

$_result=$agi->get_data('beep',10000,4);
$keys=$_result['result'];
$query="select clave from datos where clave=\"$keys\"";
$_result=mysql_query($query,$conexion);
$_re=mysql_fetch_array($_result);

$aux=0;
}while($keys!=$_re[clave]);

$agi->text2wav("usuario registrado");
$query="select saldo from datos where clave=\"$keys\"";
$_result=mysql_query($query,$conexion);

if($_re=mysql_fetch_array($_result)){
$agi->text2wav("su saldo es $_re[saldo] dolares");
}

archivo promocion.php

mysql_select_db('promo',$conexion);

$aux=1;
$query="select descripcion,valor,dias from cosas where id=$aux";
$_result=mysql_query($query,$conexion);
$_re=mysql_fetch_array($_result);

while($_re !=0){

if($aux==1)
$agi->text2wav("las promociones de la empresa son");
$agi->say_digits($aux);
$query="select descripcion,valor,dias from cosas where id=$aux";
$_result=mysql_query($query,$conexion);
$_re=mysql_fetch_array($_result);

$agi->text2wav("$_re[descripcion].... el valor por unidad es $_re[valor] dolares... la promocion dura por los proximos $_re[dias] dias ");
$aux=$aux+1;
$query="select descripcion from cosas where id=$aux";
$_result=mysql_query($query,$conexion);
$_re=mysql_fetch_array($_result);}

if($aux!=1) $agi->text2wav("no hay mas promociones");
if($aux==1) $agi->text2wav("no hay promociones actualmente");



No hay comentarios:

Publicar un comentario