Está en la página 1de 29

Universidad de El Salvador Facultad Multidisciplinaria de Occidente Departamento de Ingeniera y Arquitectura

Telefona Integrada: Sistema Automatizado de Respuesta


Ctedra: Protocolos de Comunicacin Catedrtico: Ing. Juan Carlos Pea Morn Presentado por: Gmez Arvalo, Jacqueline Stephanie Morn Monzn, Luis Antonio Urquilla Campos, Edwin Alberto

Jueves 20 de junio de 2013.

[Escriba aqu una descripcin breve del documento. Normalmente, una descripcin breve es un resumen corto del contenido del documento. Escriba aqu una descripcin breve del documento.

CONTENIDO
PLANTEAMIENTO DEL PROBLEMA............................................................................... 2 OBJETIVOS ...................................................................................................................... 3 DEFINICIONES BSICAS ................................................................................................ 4 CONFIGURACIONES ..................................................................................................... 7 OTRAS LECTURAS DE INTERS .................................................................................... 28

PLANTEAMIENTO DEL PROBLEMA


VENTAS A TRAVS DE TELEFONA
Una empresa ha desarrollado una aplicacin de ventas en lnea, pero desea extender su servicio a las ventas por telfono. Por tanto se le solicita que implemente un sistema de telefona basado en IP que permita hacer consultas de inventarios y precios para productos. Los precios y productos debern estar almacenados en una base de datos relacional (Oracle, MSSQLServer, Postgresql, etc.) y la informacin de los clientes y usuarios en LDAP. Dependiendo del tipo de usuario (cliente, vendedor, etc.), as ser el men que se reproducir.

PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

OBJETIVOS

OBJETIVOS GENERALES
Desarrollar un sistema de telefona basado en IP, el cual permita realizar ventas, compras, soporte y consultas a travs de telefona IP, el cual se conecte a una base de datos y permita obtener y devolver los valores respectivos de compras y ventas para la actualizacin de datos en tiempo real, conforme las transacciones telefnicas se realicen.

OBJETIVOS ESPECFICOS
Realizar un sistema de telefona IP utilizando Asterisk para la implementacin del mismo. Conectar el sistema de telefona IP con una base de datos relacional, utilizando el Gestor de Bases de Datos PostgreSQL. Autenticar a los usuarios a travs de LDAP. Determinar las condiciones ideales para lograr la solucin al problema planteado, as como los inconvenientes con los que se vio la solucin planteada y la resolucin que se dio a los mismos.

PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

DEFINICIONES BSICAS
VOIP VoIP proviene del ingles Voice Over Internet Protocol, que significa "voz sobre un protocolo de internet". Bsicamente VoIP es un mtodo por el cual tomando seales de audio analgicas, del tipo de las que se escuchan cuando se habla por telfono; se las transforma en datos digitales que pueden ser transmitidos a travs de internet hacia una direccin IP determinada. Las dos ventajas ms significativas de utilizar VoIP son: Bajo Costo: En general, el servicio telefnico a travs de VOIP tiene un costo mucho menor que el equivalente al servicio de fuentes tradicionales. Incremento de la Funcionalidad: VOIP hace ms fciles algunas cosas que son difciles o imposibles de lograr con las redes telefnicas tradicionales.

SIP
Es un protocolo de sealizacin, muy utilizado para establecer, conectar y desconectar sesiones de comunicacin, tpicamente voz o video a travs de redes de datos. SIP es un protocolo estandarizado basado en TCP o UDP. El protocolo puede se usado para establecer, modificar o terminar sesiones entre pares (unicast) o sesiones multipares (multicast) que consistan de uno o ms flujos de medios. Las modificaciones pueden incluir cambiar de direcciones IP y/o puertos, invitar a ms participantes, y agregar o eliminar flujos de medios. La premisa de SIP es que cada nodo de una conexin es un par, y el protocolo negocia capacidades entre ellos. Lo que hace que SIP sea atractivo, es que es un protocolo relativamente sencillo, con sintaxis similar a HTTP y SMTP. El RFC 2543, publicado en marzo de 1999 define el protocolo.

ASTERISK
Asterisk es un entorno de trabajo de cdigo abierto, creado para disear aplicaciones de comunicacin. Asterisk convierte un ordenador cualquiera, en un
PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

completo servidor de comunicaciones. Adems potencia los sistemas PBX IP, las pasarelas VoIP, servidores de conferencias, y mucho mas. Es utilizado por pequeos y grandes negocios, call centers, proveedores de telefona, y sedes gubernamentales en todo el mundo. Asterisk es gratuito, libre y de cdigo abierto. Asterisk es patrocinado por Digium.

LDAP
LDAP(Lightweight Directory Access Protocol) es un conjunto de protocolos diseado para acceder y mantener directorios de informacin. Un directorio es una base de datos especializada para buscar y navegar, como adiciones a las funciones de actualizacin. Los directorios tienden a contener informacin descriptiva basada en atributos que soportan sofisticadas capacidades de filtrado. En contraparte, los directorios generalmente no soportan esquemas complicados de transacciones que se encuentran en los sistemas de manejo de base de datos diseados para manejar complejas actualizaciones masivas. Las actualizaciones en los directorios suelen ser cambios simples de todo o nada, si es que son permitidos. Los directorios son optimizados para dar respuesta rpida a bsquedas de grandes volmenes. Adems suelen tener la habilidad para replicar ampliamente la informacin para incrementar la disponibilidad y la confianza de la misma, mientras se reduce el tiempo de respuesta.

IVR
IVR es el acrnimo de Interactive Voice Response, una tecnologa que automatiza la rutina del servicio de llamadas interactivas, permitiendo que los usuarios que realizan las llamadas puedan interactuar utilizando los tonos de los dgitos o incluso su propia voz; est orientado a entregar y/o capturar informacin a travs del telfono.

TTS
Text to Speech, es la generacin de redes inalmbricas por medios automticos de una voz artificial que genera el sonido producido por una persona al leer un

PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

texto cualquiera en voz alta o una voz artificial. Es decir, son sistemas que permiten la conversin de textos en voz sinttica.

ODBC
Open DataBase Connectivity es un estndar de acceso a las base de datos desarrollado por SQL Access Group, su objetivo es hacer posible el acceso a cualquier dato desde cualquier aplicacin, sin importar el Sistema de Gestin de Bases de Datos que almacene los datos.

POSTGRESQL
PostGreSQL es un sistema de gestin de bases de datos objeto-relacional. PostGreSQL es un sistema objeto-relacional, ya que incluye caractersticas de la orientacin a objetos, como puede ser la herencia, tipos de datos, funciones, restricciones, disparadores, reglas e integridad transaccional. A pesar de esto, PostGreSQL no es un sistema de gestin de bases de datos puramente orientado a objetos.

ASTERISK GATEWAY INTERFACE (AGI)


Asterisk Gateway Interface es una interface que aade funcionalidad a Asterisk con muchos diferentes lenguajes de programacin, entre ellos Pers, PHP, C, Pascal, Bash, etc.; depender de la preferencia del desarrollador.

PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

CONFIGURACIONES
BASE DE DATOS
Base de Datos relacional que mantiene el control del inventario que ser administrado a travs de las compras y ventas telefnicas. En la figura 1 se muestra el diagrama de la base de datos utilizada para la gestin del inventario. La base de datos est hecha en PostgreSQL 9.1

Figura 1. Diagrama de Base de Datos

CONFIGURACIONES SIP
Se utilizar Asterisk 1.8; para las versiones de Debian Wheezy, con los repositorios actualizados, se puede instalar a travs de:

# apt-get install asterisk


Para el caso de versiones ms antiguas, se deber descargar desde el proveedor y compilar el programa para su instalacin.

PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

Para conectar Asterisk con la Base de Datos, ser necesario modificar con un editor de texto el archivo res_odbc.conf ubicado en /etc/asterisk/:

#nano /etc/asterisk/res_odbc.conf
Agregar las lneas siguientes y comentar las lneas ya habilitadas:

[postgres] enabled => yes dsn => testing pre-connect => yes

El archivo fun_odbc.conf se encarga de definir las consultas SQL que se harn a la base de datos cuando se llame a una funcin en particular. ste se encuentra en /etc/asterisk/; y se definirn las funciones siguientes:

#nano /etc/asterisk/fun_odbc.conf [GET_PROMPT] dsn=postgres readsql=SELECT content FROM prompt WHERE key='${ARG1}' [GET_PRODUCT_NAME] dsn=postgres readsql=SELECT nombre FROM producto WHERE codigo='${ARG1}' [GET_PRODUCT_PRICE] dsn=postgres readsql=SELECT COALESCE(precio, 0) FROM producto WHERE codigo='${ARG1}' [GET_PRODUCT_STOCK] dsn=postgres readsql=select COALESCE(COALESCE(sum(comp.cantidad), 0) COALESCE(sum(vent.cantidad), 0), 0) from producto p
PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

readsql+= join ( readsql+= oc select c.id_producto,c.cantidad from orden_compra

readsql+= join compra c on oc.id_orden_compra = c.id_orden_compra readsql+= readsql+= readsql+= f readsql+= readsql+= readsql+= where oc.activo ) comp on comp.id_producto = p.id_producto select v.id_producto,v.cantidad from factura join venta v on f.id_factura = v.id_factura

readsql+= left join (

where f.activo ) vent on vent.id_producto = p.id_producto

readsql+= where p.codigo=${ARG1} [GET_PRODUCT_LIST] dsn=postgres readsql=SELECT codigo,nombre FROM producto mode=multirow [GET_CATEGORY_PRODUCTS] dsn=postgres readsql=SELECT codigo,nombre FROM producto WHERE readsql+= id_categoria=(SELECT id_categoria FROM categoria WHERE codigo = ${ARG1} LIMIT 1 ) mode=multirow [GET_CATEGORIES] dsn=postgres readsql=SELECT codigo,nombre FROM categoria WHERE id_categoria_padre is null mode=multirow

PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

[GET_SUB_CATEGORIES] dsn=postgres readsql=SELECT codigo,nombre FROM categoria WHERE id_categoria_padre=${ARG1} mode=multirow

En el archivo sip.conf se har referencia a las extensiones que se utilizarn, las cuales estn definidas en extensions.conf archivo que ser configurado posteriormente-, la configuracin, incluye el nmero de la extensin a la cual se hace referencia, el host que contiene esa extensin, el tipo, una constrasea, un identificador del que realiza la llamada y el nombre completo; a stos campos, se le pueden agregar otros campos de acuerdo a la necesidad de la solucin:

# nano /etc/asterisk/sip.conf [general] context=servidor-default canreinvite=no disallow=all allow=ulaw allow=alaw allow=gsm nat=yes qualify=yes permit=0.0.0.0/0.0.0.0 permit=:: language=es udpbindaddr=:: allowguest=yes ;Extension Juan Perez [6001] host=dynamic type=friend
PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

10

secret=1323 callerid=<6001> Juan Perez fullname=Juan Perez Perez <6001>

En el archivo extensions.conf se define el comportamiento de cada uno de los contextos, los cuales sern llamados por el sip.conf, configurado previamente:

#nano /etc/asterisk/extensions.conf [general] static=yes writeprotect=yes autofallthrough=yes [servidor-default] include=>inventario_ivr include=>prueba include=>locales include=>dongle-outgoing [prueba] exten=>6000,1,Verbose(Received proof call from number ${CALLERID(num)}) exten=>6000,n,BackGround(tt-monkeysintro) exten=>6000,n,BackGround(tt-monkeys) exten=>n,Dial(SIP/6001,30,Ttr) exten=>6000,n,Hangup [locales] exten=>_6XXX,1,NoOp(llamada local) exten=>_6XXX,n,Dial(SIP/${EXTEN},30,Ttr) exten=>_6XXX,n,Goto(${EXTEN}-${DIALSTATUS},1) exten=>_6XXX-BUSY,n,Playtones(busy) exten=>_6XXX-BUSY,n,Busy(10)
PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

11

exten=>_6XXX-BUSY,n,Hangup exten=>_6XXX-NOANSWER,n,Playback(number-not-answering) exten=>_6XXX-NOANSWER,n,Busy(10) exten=>_6XXX-NOANSWER,n,Hangup exten=>_6XXX-.,1,Goto(${EXTEN}-NOANSWER) [dongle-outgoing] exten=>_99XXXXXXXX,1,NoOp(llamada celular) exten=>_99XXXXXXXX,n,Dial(Dongle/dongle0/holdother:${EXTEN:2\},30) exten=>_99XXXXXXXX,n,Goto(${EXTEN}-${DIALSTATUS},1) exten=>_99XXXXXXXX-BUSY,n,Playtones(busy) exten=>_99XXXXXXXX-BUSY,n,Busy(10) exten=>_99XXXXXXXX-BUSY,n,Hangup exten=>_99XXXXXXXX-NOANSWER,n,Playback(number-not-answering) exten=>_99XXXXXXXX-NOANSWER,n,Busy(10) exten=>_99XXXXXXXX-NOANSWER,n,Hangup exten=>_99XXXXXXXX-.,1,Goto(${EXTEN}-NOANSWER) exten=>99725,1,Dial(Dongle/dongle0/holdother:*725#,30)

Dentro del directorio /etc/asterisk/ se va a crear una carpeta en la cual se van a ubicar los archivos necesarios para la ejecucin de Interactive Voice Response (IVR) que sern ejecutados durante la llamada, la carpeta se llamar inventario_ivr; la cual a su vez, contendr dos directorios ms, utils, que contendr los archivos input.conf y output.conf; los cuales definen las extensiones de entradas y salidas que se generarn durante la llamada y el directorio scripts, el cual contiene las configuraciones de los prompts que se generarn y devolvern durante la llamada; por lo cual se crearn los siguientes directorios:

#mkdir /etc/asterisk/inventario_ivr #mkdir /etc/asterisk/inventario_ivr/utils #mkdir /etc/asterisk/inventario_ivr/scripts #mkdir /etc/asterisk/inventario_ivr/scripts/conf

PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

12

Dentro de la carpeta principal inventario_ivr, se va a crear el archivo main.conf, el cual contiene las definiciones principales del men que se despliega al hacer la llamada:

#nano /etc/asterisk/inventario_ivr/main.conf #include inventario_ivr/utils/output.conf #include inventario_ivr/utils/input.conf #include inventario_ivr/product.conf [inventario_ivr] exten => _XX,1,GoSub(subIVR,start,1()) exten => _XXX,1,GoTo(pruebaSpeech,start,1) [pruebaSpeech] exten => start,1,NoOp(speech start) same=> n(start),agi(tts,"Cual es su consulta?") same => n(record),agi(spe) same => n,GotoIf($[$["${status}" = "0"] & $["${confidence}" > "0.74"]]?success:retry) same => n(success),agi(tts,"An no conozco como resolver la consulta ${utterance}") same => n,goto(start) same => n(retry),agi(tts,"No he entendido su pregunta, repitalo de nuevo") same => n,goto(record) exten => 1237,n(end),Hangup() [pruebaWolfram] exten => start,1,NoOp(speech start) same=> n(start),agi(tts,"How may I help you today?","en-US") same => n(record),agi(spe,"en-US") same => n,GotoIf($[$["${status}" = "0"] & $["${confidence}" > "0.74"]]?success:retry) same => n(success),agi(wolfram,"${utterance}")

PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

13

same => n,agi(tts,"${wolfram_answer}","en-US") same => n,goto(start) same => n(retry),agi(tts,"No he entendido su pregunta, repitalo de nuevo") same => n,goto(record) exten => 1237,n(end),Hangup() [subIVR] exten => start,1,agi(tts,${bienvenido_desconocido}) same => n,Set(menu_options=1, ${op_acceder_cliente_proveedor}. 2, ${op_info_producto}) same => n,Set(menu_options="${menu_options} . 3, ${op_ofertas}. 4, ${contactar_representante}") same => n,GoSub(subReadOption,start,1(${menu_options})) same => n,NoOp(Out of main read option) same => n,GoToIf($["${GOSUB_RETVAL}"= "1"]?o1) same => n,GoToIf($["${GOSUB_RETVAL}"= "2"]?o2) same => n,GoToIf($["${GOSUB_RETVAL}"= "3"]?o3) same => n,GoToIf($["${GOSUB_RETVAL}"= "4"]?o4) same => n,GoToIf($["${GOSUB_RETVAL}"= ""]?restart) same => n,GoTo(start,failed) same => n(o1),GoSub(subAuth,start,1()) same => n,Goto(start,1) same => n(o2),GoSub(subProdInfo,start,1()) same => n,Goto(start,1) same => n(o3),GoSub(subOfertas,start,1()) same => n,Goto(start,1) same => n(o4),GoSub(subContact,start,1()) same => n,Goto(start,1) same => n(failed),agi(tts,${opcion_invalida}) same => n(restart),Goto(start,1) [ivr_cliente] exten => start,1,NoOp(Entrando a ivr_cliente)
PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

14

same => n,GoSub(subFillPrompt,start,1(${bienvenido_conocido},${user_name}) ) same => n,agi(tts,${GOSUB_RETVAL}) same => n,Set(menu_options=1, ${op_comprar}. 2, ${op_info_producto}) same => n,Set(menu_options="${menu_options} . 3, ${op_ofertas}. 4, ${contactar_representante}") same => n,GoSub(subReadOption,start,1(${menu_options})) same => n,NoOp(Out of main read option) same => n,GoToIf($["${GOSUB_RETVAL}"= "1"]?o1) same => n,GoToIf($["${GOSUB_RETVAL}"= "2"]?o2) same => n,GoToIf($["${GOSUB_RETVAL}"= "3"]?o3) same => n,GoToIf($["${GOSUB_RETVAL}"= "4"]?o4) same => n,GoToIf($["${GOSUB_RETVAL}"= ""]?restart) same => n,GoTo(start,failed) same => n(o1),GoSub(subAuth,start,1()) same => n,Goto(start,1) same => n(o2),GoSub(subProdInfo,start,1()) same => n,Goto(start,1) same => n(o3),GoSub(subOfertas,start,1()) same => n,Goto(start,1) same => n(o4),GoSub(subContact,start,1()) same => n,Goto(start,1) same => n(failed),agi(tts,${opcion_invalida}) same => n(restart),Goto(start,1) [ivr_proveedor] exten => start,1,NoOp(Entrando a ivr_cliente) same => n,GoSub(subFillPrompt,start,1(${bienvenido_conocido},${user_name}) ) same => n,agi(tts,${GOSUB_RETVAL}) same => n,Set(menu_options=1, ${confirmar_despacho}. 2, ${op_info_producto})
PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

15

same => n,Set(menu_options="${menu_options} . 3, ${op_ofertas}. 4, ${contactar_representante}") same => n,GoSub(subReadOption,start,1(${menu_options})) same => n,NoOp(Out of main read option) same => n,GoToIf($["${GOSUB_RETVAL}"= "1"]?o1) same => n,GoToIf($["${GOSUB_RETVAL}"= "2"]?o2) same => n,GoToIf($["${GOSUB_RETVAL}"= "3"]?o3) same => n,GoToIf($["${GOSUB_RETVAL}"= "4"]?o4) same => n,GoToIf($["${GOSUB_RETVAL}"= ""]?restart) same => n,GoTo(start,failed) same => n(o1),GoSub(subAuth,start,1()) same => n,Goto(start,1) same => n(o2),GoSub(subProdInfo,start,1()) same => n,Goto(start,1) same => n(o3),GoSub(subOfertas,start,1()) same => n,Goto(start,1) same => n(o4),GoSub(subContact,start,1()) same => n,Goto(start,1) same => n(failed),agi(tts,${opcion_invalida}) same => n(restart),Goto(start,1) [subProdInfo] exten => start,1,NoOp(subProdInfo started) same => n,Set(menu_options=1, ${op_ingresar_id_producto}. 2, ${op_navegar_categorias}.) same => n,GoSub(subReadOption,start,1("${menu_options}")) same => n,GoToIf($["${GOSUB_RETVAL}"= "1"]?o1) same => n,GoToIf($["${GOSUB_RETVAL}"= "2"]?o2) same => n(o1),GoSub(subReadProductId,start,1()) same => n,NoOp(Retornar a menu principal? nuevo menu? menu de la redencion) same => n(o2),GoSub(subReadCategoryId,start,1()) same => n,GoSub(subReadProductId,start,1()) same => n,GoSub(subPromptProductInfo,start,1(${GOSUB_RETVAL}))
PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

16

same => n(failed),agi(tts,${opcion_invalida}) same => n,Goto(start,1) same => n,Return() [subContact] exten => start,1,NoOp(subContact started) same => n,NoOp(enviando llamada con exten ${EXTEN}) same => n,Dial(Dongle/dongle0/holdother:77303366,30) ; TODO: esto va para SIP no al dongle same => n,NoOp(Definir que hacemos si no contesta y definir cola de llamadas) same => n,Hangup() [subOfertas] exten => start,1,NoOp(subOfertas started) same => n,agi(tts,${ofertas_disponibles}) same => n,Return() [subAuth] exten => start,1,GoSub(subReadAuth,start,1()) same => n,GoToIf($["${GOSUB_RETVAL}"= "1"]?client) same => n,GoToIf($["${GOSUB_RETVAL}"= "2"]?prov) same => n,GoToIf($["${GOSUB_RETVAL}"= "0"]?failed) same => n(client),Goto(ivr_cliente,start,1) same => n(prov),Goto(ivr_proveedor,start,1) same => n(failed),agi(tts,"Credenciales invlidas, intentelo de nuevo"); TODO: pasar a bd same => n,Goto(subAuth,start,1);GoSub(subReadOption,start,1()); TODO: cancelar

El archivo globals.conf solamente har referencia a los prompts:

# nano

/etc/asterisk/inventario_ivr/globals.conf

#include inventario_ivr/scripts/conf/prompts.conf
PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

17

El archivo product.conf, contiene las definiciones de los productos y los contextos que se ejecutan cuando se elige una opcin de producto:

#nano /etc/asterisk/inventario_ivr/product.conf [subReadProductId] exten => start,1,NoOp(subReadProductId started) same => n,GoSub(subReadOption,start,1(${ingrese_id_producto})) [subReadCategoryId] exten => start,1,NoOp(subReadCategoryId started) same => n,GoSub(subReadCategories,start,1()) same => n(say_categories),GoSub(subReadOption,start,1("${GOSUB_RETVAL}")) same => n,Set(selected_category=${GOSUB_RETVAL}) same => n,GoSub(subReadSubCategories,start,1(${selected_category})) same => n,GotoIf($["foo${GOSUB_RETVAL}"="foo"]?no_rows:sub_cat) same => n(no_rows),GoSub(subReadProductList,start,1(${selected_category})) same => n,GoSub(subReadProductId,start,1(${GOSUB_RETVAL})) same => n,GoSub(subPromptProductInfo,start,1(${GOSUB_RETVAL})) same => n,Return() same => n(sub_cat),NoOp(subcat no op) same => n,GoSub(subReadSubCategories,start,1(${selected_category})) same => n,GotoIf($["foo${GOSUB_RETVAL}"="foo"]?no_rows:say_categories) same => n,Return() same => n,NoOp(subReadProductId? before cats?) same => n,NoOp(return product id?) [subReadCategories] exten => start,1,NoOp(subReadcategories started with ${ARG1}) same => n,Set(category_list=)
PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

18

same => n,Set(ODBC_ID=${ODBC_GET_CATEGORIES()}) same => n,GotoIf($[${ODBCROWS} < 1]?no_rows) same => n,Set(COUNTER=1) same => n,While($[${COUNTER} <= ${ODBCROWS}]) same => n,Set(ARRAY(category_code_${COUNTER},category_name_${COUNTER})=$ {ODBC_FETCH(${ODBC_ID})}) same => n,Set(category_list=${category_list} ${category_code_${COUNTER}}, $ {category_name_${COUNTER}}.) same => n,Set(COUNTER=$[${COUNTER} + 1]) same => n,EndWhile() same => n,ODBCFinish() same => n(no_rows),Return(${category_list}) [subReadSubCategories] exten => start,1,NoOp(subReadSubCategory started with ${ARG1}) same => n,Set(category_list=) same => n,Set(ODBC_ID=${ODBC_GET_SUB_CATEGORIES(${ARG1})}) same => n,GotoIf($[${ODBCROWS} < 1]?no_rows) same => n,Set(COUNTER=1) same => n,While($[${COUNTER} <= ${ODBCROWS}]) same => n,Set(ARRAY(category_code_${COUNTER},category_name_${COUNTER})=$ {ODBC_FETCH(${ODBC_ID})}) same => n,Set(category_list=${category_list} ${category_code_${COUNTER}}, $ {category_name_${COUNTER}}.) same => n,Set(COUNTER=$[${COUNTER} + 1]) same => n,EndWhile() same => n,ODBCFinish() same => n(no_rows),Return(${category_list})

[subPromptProductInfo] exten => start,1,NoOp(subPromptProductInfo started with ${ARG1}) same => n,Set(prod_name=${ODBC_GET_PRODUCT_NAME(${ARG1})})
PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

19

same => n,Set(prod_price=${ODBC_GET_PRODUCT_PRICE(${ARG1})}) same => n,Set(prod_stock=${ODBC_GET_PRODUCT_STOCK(${ARG1})}) same => n,GoSub(subFillPrompt,start,1(${nombre_producto},${prod_name})) same => n,agi(tts,${GOSUB_RETVAL}) same => n,GoSub(subFillPrompt,start,1(${precio_producto},${prod_price})) same => n,agi(tts,${GOSUB_RETVAL}) same => n,GoSub(subFillPrompt,start,1(${existencias_producto},${prod_stock })) same => n,agi(tts,${GOSUB_RETVAL}) same => n,Return() [subReadProductList] exten => start,1,NoOp(subReadProductList started with ${ARG1}) same => n,Set(product_list=) same => n,Set(ODBC_ID=${ODBC_GET_PRODUCT_LIST()}) same => n,GotoIf($[${ODBCROWS} < 1]?no_rows,1) same => n,Set(COUNTER=1) same => n,While($[${COUNTER} <= ${ODBCROWS}]) same => n,Set(ARRAY(product_code_${COUNTER},product_name_${COUNTER})=$ {ODBC_FETCH(${ODBC_ID})}) same => n,Set(product_list=${product_list} ${product_code_${COUNTER}}, $ {product_name_${COUNTER}}.) same => n,Set(COUNTER=$[${COUNTER} + 1]) same => n,EndWhile() same => n,ODBCFinish() same => n,agi(tts, ${productos_en_categoria}) same => n,GoSub(subReadOption,start,1("${product_list}")) same => n,GoSub(subPromptProductInfo,start,1(${GOSUB_RETVAL})) same => n,Return(${product_list})

PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

20

En el directorio utils, se encuentran los archivos input.conf, el cual contiene las definiciones de las entradas que se generan a travs del teclado durante la llamada:

#nano /etc/asterisk/inventario_ivr/utils/input.conf [subRead] exten => start,1,NoOp(subRead started) same => n,WaitExten(3);Agregar verificaciones exten => _X,1,GoSub(subRead,start,1(${ARG1}${EXTEN})) same => n,Return(${GOSUB_RETVAL}) exten => t,1,Return(${ARG1}) exten => e,1,Return(${ARG1}) [subReadOption] exten => start,1,NoOp(SubReadOption started with ${ARG1}) same => n,agi(tts,${ARG1},es,any) same => n,WaitExten(3) exten => t,1,GoSub(subRead,start,1()) exten => _X,1,GoSub(subRead,start,1(${EXTEN})) same => n,Return(${GOSUB_RETVAL}) exten => e,1,agi(tts,"Opcion invalida") same => n,Goto(subReadOption,start,1) [subReadAuth] exten => start,1,NoOp(subReadID started) same => n,GoSub(subReadOption,start,1(${ingrese_id})) same => n,Set(user_id=${GOSUB_RETVAL}) same => n,GoSub(subReadOption,start,1(${ingrese_pin})) same => n,Set(user_pin=${GOSUB_RETVAL}) same => n,NoOp(Realizando autenticacion... ) same => n,Set(auth_result=${user_pin}) same => n,Return(${auth_result})

PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

21

El archivo output.conf, contiene las opciones de salidas durante la llamada:

# nano /etc/asterisk/inventario_ivr/utils/output.conf [subFillPrompt] exten => start,1,NoOp(Iniciado subFillPrompt);Set(prompt=${CUT(ARG1,~,1}) same => n,Set(result=${ARG1}) same => n,Set(i=1) same => n,Verbose(${result}) same => n,While($[REGEX("~","${result}") > 0]) ;empieza bucle same => n,Verbose(Iterando ${i} con ${result}) same => n,Set(i=$[${i}+1]) ; aumentamos i same => n,Set(result=${CUT(result,~,1)}${ARG${i}}${CUT(result,~,2)}) same => n,EndWhile same => n,Set(result=${result}${ARG$[${i}+1]}) same => n,Return(${result}) [subT] exten => _X,1,NoOp(Iniciado subPrompt) same => n,agi(googletts.agi,$ARG1,$ARG2) same => n,Return()

Dentro del directorio /etc/asterisk/inventario_ivr/scripts/conf se encuentra el archivo prompts.conf, el cual define los promtps que pueden ser generados durante la llamada:

#nano /etc/asterisk/inventario_ivr/scripts/conf/prompts.conf

bienvenido_desconocido => ${ODBC_GET_PROMPT(bienvenido_desconocido)} seleccione_opcion => ${ODBC_GET_PROMPT(seleccione_opcion)} op_acceder_cliente_proveedor => ${ODBC_GET_PROMPT(op_acceder_cliente_proveedor)}


PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

22

ingrese_id => ${ODBC_GET_PROMPT(ingrese_id)} id_invalido => ${ODBC_GET_PROMPT(id_invalido)} ingrese_pin => ${ODBC_GET_PROMPT(ingrese_pin)} pin_invalido => ${ODBC_GET_PROMPT(pin_invalido)} reintentar_opcion => ${ODBC_GET_PROMPT(reintentar_opcion)} op_info_producto => ${ODBC_GET_PROMPT(op_info_producto)} op_ingresar_id_producto => ${ODBC_GET_PROMPT(op_ingresar_id_producto)} op_navegar_categorias => ${ODBC_GET_PROMPT(op_navegar_categorias)} op_notificar_existencias_llamada => ${ODBC_GET_PROMPT(op_notificar_existencias_llamada)} op_notificar_existencias_sms => ${ODBC_GET_PROMPT(op_notificar_existencias_sms)} confirmar_accion => ${ODBC_GET_PROMPT(confirmar_accion)} ingrese_numero_notificacion => ${ODBC_GET_PROMPT(ingrese_numero_notificacion)} seleccione_opcion_notificacion => ${ODBC_GET_PROMPT(seleccione_opcion_notificacion)} op_ofertas => ${ODBC_GET_PROMPT(op_ofertas)} opcion_invalida => ${ODBC_GET_PROMPT(opcion_invalida)} tiempo_agotado => ${ODBC_GET_PROMPT(tiempo_agotado)} op_comprar => ${ODBC_GET_PROMPT(op_comprar)} ingresar_cantidad => ${ODBC_GET_PROMPT(ingresar_cantidad)} cantidad_invalida => ${ODBC_GET_PROMPT(cantidad_invalida)} confirmar_orden => ${ODBC_GET_PROMPT(confirmar_orden)} orden_confirmada => ${ODBC_GET_PROMPT(orden_confirmada)} confirmar_despacho => ${ODBC_GET_PROMPT(confirmar_despacho)} ingrese_codigo_despacho => ${ODBC_GET_PROMPT(ingrese_codigo_despacho)} bienvenido_conocido => ${ODBC_GET_PROMPT(bienvenido_conocido)} nombre_producto => ${ODBC_GET_PROMPT(nombre_producto)} descripcion_orden => ${ODBC_GET_PROMPT(descripcion_orden)} despacho_confirmado => ${ODBC_GET_PROMPT(despacho_confirmado)} contactar_representante => ${ODBC_GET_PROMPT(contactar_representante)}
PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

23

ofertas_disponibles => ${ODBC_GET_PROMPT(ofertas_disponibles)} existencias_producto => ${ODBC_GET_PROMPT(existencias_producto)} precio_producto => ${ODBC_GET_PROMPT(precio_producto)} ingrese_id_producto => ${ODBC_GET_PROMPT(ingrese_id_producto)} productos_en_categoria => ${ODBC_GET_PROMPT(productos_en_categoria)}

ASTERISK GATEWAY INTERFACE


Para la autenticacin, se hace uso de Asterisk Gateway Interface, en el cual se autentica al usuario con LDAP, el script se guarda en la ubicacin /var/lib/asterisk/agi-bin; a travs de un script escrito en bash, que se define tal y como sigue:

#!/bin/bash CLIENT_RESULT=`ldapsearch -D "uid=${1},ou=clientes,ou=ivr,dc=uc09001,dc=uesocc,dc=edu,dc=sv" \ -b "ou=clientes,ou=ivr,dc=uc09001,dc=uesocc,dc=edu,dc=sv" -LLL w "${2}" "uid=${1}" | grep -i sn` #`echo ${1}` #`echo ${2}` PROVIDER_RESULT=`ldapsearch -D "uid=${1},ou=proveedores,ou=ivr,dc=uesocc,dc=edu,dc=sv" \ -b "ou=proveedores,ou=ivr,dc=uesocc,dc=edu,dc=sv" -LLL -w "${2}" "uid=${1}" | grep -i sn`

#`echo ${PROVIDER_RESULT} > /tmp/authenticate.log` #`echo ${CLIENT_RESULT} > /tmp/authenticate.log` IS_CLIENT_VALID=`echo $CLIENT_RESULT | grep -c ^sn:`
PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

24

IS_PROVIDER_VALID=`echo $PROVIDER_RESULT | grep -c ^sn:` if [ $IS_CLIENT_VALID = 1 ]; then echo "SET VARIABLE user_type \"1\" " CLIENT_RESULT=`echo ${CLIENT_RESULT:4}` echo "SET VARIABLE user_name \"${CLIENT_RESULT}\" " elif [ $IS_PROVIDER_VALID = 1 ]; then echo "SET VARIABLE user_type \"2\" " PROVIDER_RESULT=`echo ${PROVIDER_RESULT:4}` echo "SET VARIABLE user_name \"${PROVIDER_RESULT}\" " else echo "SET VARIABLE user_type \"0\" " fi

LDAP
El almacenamiento de usuarios para la autenticacin se har a travs de LDAP con OpenLDAP

#apt-get install slapd #apt-get install ldap-utils


El rbol LDAP se ilustra en la figura 2, y est compuesto en sus ramas menos generales por Proveedores y Clientes; en los cuales se almacenarn los datos de los proveedores y de los clientes para que se autentiquen en el rbol, a travs del AGI.

PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

25

Figura 2. rbol LDAP

Para poder agregar los usuarios ser necesario, escribir algunos archivos ldif, los cuales agregaremos al rbol; stos se definen a continuacin:

ivr.ldif DN: ou=ivr,dc=uesocc,dc=edu,dc=sv objectClass: organizationalUnit objectClass: top ou: ivr

clientes.ldif DN: ou=clientes,ou=ivr,dc=uc09001,dc=uesocc,dc=edu,dc=sv objectClass: organizationalUnit objectClass: top ou: clientes

PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

26

cliente123.ldif DN: uid=123,ou=clientes,ou=ivr,dc=uc09001,dc=uesocc,dc=edu,dc=sv objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person objectClass: top cn: jose sn: Alfonso Zayas uid: 123 userPassword:: e1NIQX1RTDBBRldNSVg4TlJaVEtlb2Y5Y1hzdmJ2dTg9 proveedores.ldif DN: ou=proveedores,ou=ivr,dc=uc09001,dc=uesocc,dc=edu,dc=sv objectClass: organizationalUnit objectClass: top ou: proveedores proveedor321.ldif DN: uid=321,ou=proveedores,ou=ivr,dc=uc09001,dc=uesocc,dc=edu,dc=sv objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person objectClass: top cn: alberto sn: Alberto Rojas uid: 321 userPassword:: e1NIQX1RTDBBRldNSVg4TlJaVEtlb2Y5Y1hzdmJ2dTg9

Para agregar los ldif se ejecuta un ldapadd con la siguiente forma:

# ldapadd D cn=admin,dc=uesocc,dc=edu,dc=sv W h nombredelhost x f rama.ldif


PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

27

OTRAS LECTURAS DE INTERS


Telefona Voz IP http://www.telefoniavozip.com Voip-info.org http://www.voip-info.org/ The Internet Engineering Task Force (IETF) http://www.ietf.org/ Wiki Asterisk http://wikiasterisk.com Asterisk http://www.asterisk.org

PROTOCOLO S DE COMU NICACI N VENTAS A TRAVS D E TELEFONA

28

También podría gustarte