{"id":288,"date":"2009-12-25T10:37:06","date_gmt":"2009-12-25T15:37:06","guid":{"rendered":"http:\/\/alejandroayala.wordpress.com\/?p=288"},"modified":"2012-11-13T10:05:09","modified_gmt":"2012-11-13T15:05:09","slug":"ivr-con-mysql-elastix","status":"publish","type":"post","link":"https:\/\/alejandroayala.solmedia.ec\/?p=288","title":{"rendered":"IVR con MYSQL. Elastix"},"content":{"rendered":"<p style=\"text-align: justify;\">Configurar un <a title=\"IVR\" href=\"http:\/\/es.wikipedia.org\/wiki\/Interactive_Voice_Response\" target=\"_blank\">IVR<\/a> es muy sencillo desde la interfaz web de <a title=\"Elastix\" href=\"http:\/\/www.elastix.org\/\" target=\"_blank\">Elastix<\/a>, simple para direccionar opciones a extensiones agregadas a nuestra PBX. Pero sabemos que muchas de las veces requerimos hacer cosas mas elaboradas, por ejemplo gestionar datos de una BD y hacerlos interactuar con nuestra central telef\u00f3nica.<\/p>\n<p style=\"text-align: justify;\">Para este ejemplo mi aplicaci\u00f3n contiene:<\/p>\n<ul>\n<li>Un saludo de bienvenida.<\/li>\n<li>Un men\u00fa principal<\/li>\n<li>Menus secundarios<\/li>\n<li>Audios de ingresos correctos e incorrectos.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Para grabar estos archivos podemos hacerlo desde nuestro editor favorito, yo utilizo <a title=\"Audacity\" href=\"http:\/\/audacity.sourceforge.net\/?lang=es\" target=\"_blank\">Audacity<\/a> respetando ciertas configuraciones de muestreo y otras cosas. Para facilitar nuestro trabajo podemos realizar las grabaciones desde una extensi\u00f3n de nuestra PBX y con la ayuda de un softphone grabar nuestra voz. En la p\u00e1gina de elastix hay mucha <a href=\"http:\/\/www.elastix.org\/content\/view\/137\/60\/lang,es\/\" target=\"_blank\">informaci\u00f3n<\/a> de c\u00f3mo realizar esta labor. Recomiendo los manuales de \u00abComunicaciones Unificadas con Elastix\u00bb <a href=\"http:\/\/sourceforge.net\/projects\/elastix\/files\/Tutorials_Docs_Manuals\/Comunicaciones%20Unificadas%20con%20Elastix\/Comunicaciones_Unificadas_con_Elastix_Volumen_1_29Mar2009.pdf\/download\" target=\"_blank\">volumen 1<\/a> y <a href=\"http:\/\/sourceforge.net\/projects\/elastix\/files\/Tutorials_Docs_Manuals\/Comunicaciones%20Unificadas%20con%20Elastix\/Comunicaciones_Unificadas_con_Elastix_Volumen_2_29Mar2009.pdf\/download\" target=\"_blank\">volumen 2<\/a>.<\/p>\n<p style=\"text-align: justify;\"><!--more--><\/p>\n<p style=\"text-align: justify;\">La aplicaci\u00f3n es sencilla y se la puede complicar tanto como queramos.<\/p>\n<p style=\"text-align: justify;\">Empezamos con editar el archivo de configuraci\u00f3n <strong>extensions_custom.conf<\/strong>, desde nuestra interfaz web llegamos a este archivo de la siguiente manera:<\/p>\n<ol>\n<li>Clic en PBX<\/li>\n<li>Clic en Tools<\/li>\n<li>Clic en File Editor<\/li>\n<\/ol>\n<p style=\"text-align: center;\"><a href=\"http:\/\/solmedia.ec\/blog\/wp-content\/uploads\/2009\/12\/01.png\"><img loading=\"lazy\" class=\"size-medium wp-image-289 aligncenter\" title=\"Fig 1\" src=\"http:\/\/solmedia.ec\/blog\/wp-content\/uploads\/2009\/12\/01.png?w=300\" alt=\"Acceso archivo extension_custom.conf\" width=\"300\" height=\"125\" srcset=\"http:\/\/solmedia.ec\/blog\/wp-content\/uploads\/2009\/12\/01.png 939w, http:\/\/solmedia.ec\/blog\/wp-content\/uploads\/2009\/12\/01-300x125.png 300w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Para encontrar rapidamente el archivo podemos filtarlo por su nombre:<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/solmedia.ec\/blog\/wp-content\/uploads\/2009\/12\/02.png\"><img loading=\"lazy\" class=\"size-medium wp-image-290 aligncenter\" title=\"Fig 2.\" src=\"http:\/\/solmedia.ec\/blog\/wp-content\/uploads\/2009\/12\/02.png?w=300\" alt=\"Filtranto el archivo extensions_custom.conf\" width=\"300\" height=\"151\" srcset=\"http:\/\/solmedia.ec\/blog\/wp-content\/uploads\/2009\/12\/02.png 723w, http:\/\/solmedia.ec\/blog\/wp-content\/uploads\/2009\/12\/02-300x151.png 300w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Agregamos lo siguiente a nuestro archivo:<\/p>\n<p style=\"text-align: justify;\"><!--more--><\/p>\n<p>[sourcecode language=\u00bbtext\u00bb]<br \/>\ninclude =&amp;gt; inicio<br \/>\ninclude =&amp;gt; IVR<br \/>\ninclude =&amp;gt; IVR1<br \/>\ninclude =&amp;gt; IVR2<\/p>\n<p>[globals]<\/p>\n<p>;&#8212;&#8212;&#8211; VARIABLES<\/p>\n<p>telefono=<br \/>\ntotal=<br \/>\nestadof=<br \/>\nnumero=<br \/>\nflaq=<br \/>\nestado=<\/p>\n<p>[inicio]<\/p>\n<p>exten =&amp;gt; 1800,1,Answer<br \/>\nexten =&amp;gt; 1800,2,Ringing<br \/>\nexten =&amp;gt; 1800,3,Wait,2<br \/>\nexten =&amp;gt; 1800,4,goto(IVR,s,1)<\/p>\n<p>[IVR]<br \/>\nexten =&amp;gt; s,1,Wait(1) ;espera un segundo<br \/>\nexten =&amp;gt; s,2,Set(TIMEOUT(response)=10) ; 10 seg espera para que el llamante presione una tecla<br \/>\nexten =&amp;gt; s,3,Playback(custom\/welcome) ; menu y escucha si el llamante presiona alguna tecla<br \/>\nexten =&amp;gt; s,4,BackGround(custom\/menu)<br \/>\nexten =&amp;gt; s,5,WaitExten() ; espera que el llamante presione alguna tecla<br \/>\nexten =&amp;gt; 1,1,goto(IVR1,s,1) ; si presiona 1 va al contexto IVR1, extension s, prioridad 1<br \/>\nexten =&amp;gt; 2,1,goto(IVR2,s,1) ; si presiona 2 va al contexto IVR2, extension s, prioridad 1<br \/>\nexten =&amp;gt; 0,1,Hungup<br \/>\nexten =&amp;gt; t,1,Goto(#,1)<br \/>\nexten =&amp;gt; i,1,BackGround(custom\/noOp)<br \/>\nexten =&amp;gt; i,2,Goto(s,4)<\/p>\n<p>[IVR1]<br \/>\nexten =&amp;gt; s,1,Playback(custom\/inFono)<br \/>\nexten =&amp;gt; s,2,Read(telefono,,8) ; variable telefono recupera lo q el usuario ingreso 8 caracteres<br \/>\nexten =&amp;gt; s,3,MYSQL(Connect conn localhost root eLaStIx.2oo7 informacion) ; usuario: root, pass:eLaStIx.2oo7, informacion es el nombre de la BD<br \/>\nexten =&amp;gt; s,4,MYSQL(Query resultid ${conn} SELECT total from CNT where idfono=${telefono}) ; consulta tabla CNT, campo idfono<br \/>\nexten =&amp;gt; s,5,MYSQL(Fetch fetchid ${resultid} suu) ; recupera el valor<br \/>\nexten =&amp;gt; s,6,Set(total=${suu}) ; guarda en la variable total<br \/>\nexten =&amp;gt; s,7,MYSQL(Clear ${resultid}) ;limpia<br \/>\nexten =&amp;gt; s,8,MYSQL(Disconnect ${conn}) ;desconecta<br \/>\nexten =&amp;gt; s,9,GotoIf($[${LEN(${total})} = 0]?11:20) ; si la consulta retorna valores vacios<br \/>\nexten =&amp;gt; s,10,Goto(11)<br \/>\nexten =&amp;gt; s,11,BackGround(custom\/losiento) ; se le dice al usuario que no hubo datos de su consulta<br \/>\nexten =&amp;gt; s,12,Goto(23)<br \/>\nexten =&amp;gt; s,20,BackGround(custom\/totales)<br \/>\nexten =&amp;gt; s,21,SayNumber(${total}) ; si la consulta retorna un valor, una voz femenina lee el valor(en ingles)<br \/>\nexten =&amp;gt; s,22,Playback(custom\/dolares)<br \/>\nexten =&amp;gt; s,23,BackGround(custom\/pregunta) ; si desea hacer otra consulta<br \/>\nexten =&amp;gt; s,24,WaitExten(3)<br \/>\nexten =&amp;gt; 1,1,Goto(IVR1,s,1)<br \/>\nexten =&amp;gt; 2,1,Goto(IVR,s,4)<br \/>\nexten =&amp;gt; 3,1,Hangup<\/p>\n<p>[IVR2]<br \/>\nexten =&amp;gt; s,1,Playback(custom\/inFono)<br \/>\nexten =&amp;gt; s,2,Read(telefono,,8)<br \/>\nexten =&amp;gt; s,3,MYSQL(Connect con localhost root eLaStIx.2oo7 informacion)<br \/>\nexten =&amp;gt; s,4,MYSQL(Query resul ${con} SELECT estado from CNT where idfono=${telefono})<br \/>\nexten =&amp;gt; s,5,MYSQL(Fetch fetchid ${resul} su)<br \/>\nexten =&amp;gt; s,6,Set(estadof=${su})<br \/>\nexten =&amp;gt; s,7,MYSQL(Clear ${con})<br \/>\nexten =&amp;gt; s,8,MYSQL(Disconnect ${con})<br \/>\nexten =&amp;gt; s,9,GotoIf($[${LEN(${estadof})} = 0]?11:20)<br \/>\nexten =&amp;gt; s,10,Goto(11)<br \/>\nexten =&amp;gt; s,11,BackGround(custom\/losiento)<br \/>\nexten =&amp;gt; s,12,Goto(22)<br \/>\nexten =&amp;gt; s,20,BackGround(custom\/estadoes)<br \/>\nexten =&amp;gt; s,21,Playback(custom\/${estadof}) ; el resultado de la consulta es la misma que el\u00a0 nombre de un archivo de audio<br \/>\nexten =&amp;gt; s,22,BackGround(custom\/pregunta2)<br \/>\nexten =&amp;gt; s,23,WaitExten(3)<br \/>\nexten =&amp;gt; 1,1,Goto(IVR2,s,1)<br \/>\nexten =&amp;gt; 2,1,Goto(IVR,s,4)<br \/>\nexten =&amp;gt; 3,1,Hangup&lt;\/td&gt;<br \/>\n[\/sourcecode]<\/p>\n<p style=\"text-align: justify;\">Parte del c\u00f3digo esta comentado para su entendimiento, es muy f\u00e1cil seguir su secuencia y probar sus opciones mentalmente. Todo empieza con el contexto <strong>[inicio]<\/strong>, la extensi\u00f3n de nuestra IVR es 1800, esta a su vez puede ser configurada como ruta entrante de las llamadas o puede ser configurada para que primero sea contestada en un Call Center, etc., son muchas nuestras posibilidades, todo esto se explica en detalle en la <a href=\"http:\/\/www.elastix.org\/content\/view\/137\/60\/lang,es\/\" target=\"_blank\">documentaci\u00f3n oficial<\/a>.<\/p>\n<p style=\"text-align: justify;\">Luego va al contexto [IVR] donde reproducimos el saludo (PlayBack) y luego el men\u00fa (Background), la diferencia entre las dos es que la primera har\u00e1 caso omiso al usuario hasta terminar de reproducir todo el archivo y background reproducir\u00e1 el archivo hasta que el usuario presione alguna opci\u00f3n del teclado y el IVR interprete esta opci\u00f3n.<\/p>\n<p style=\"text-align: justify;\">La secuencia depende del n\u00famero de su secuencia y con <strong>\u00abGoto\u00bb<\/strong> podemos pr\u00e1cticamente pasearnos por nuestras opciones.<\/p>\n<p style=\"text-align: justify;\">La consulta de conexi\u00f3n a la BD viene con los datos de usuario y password que se menciona en la explicaci\u00f3n del c\u00f3digo, estos valores vienen por default en Elastix<\/p>\n<p style=\"text-align: justify;\">La aplicaci\u00f3n le da al usuario dos opciones:<\/p>\n<ul>\n<li>Presione 1 para revisar su saldo. <em>Contexto [IVR1]<\/em><\/li>\n<li>Presione 2 para revisar el estado actual de su l\u00ednea. <em>Contexto [IVR2]<\/em><\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><strong>[IVR1]<\/strong><\/p>\n<ul>\n<li>El usuario ingresa su numero de telefono 8 caracteres<\/li>\n<li>Se realiza la consulta<\/li>\n<li>El IVR lee el resultado de la consulta<\/li>\n<li>Menu para consultar otro numero o regresar al men\u00fa principal o salir<\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><strong>[IVR2]<\/strong><\/p>\n<ul>\n<li>El usuario ingresa su numero de telefono 8 caracteres<\/li>\n<li>Se realiza la consulta<\/li>\n<li>Los resultados siempre tienen 4 estados de la linea posibles:\n<ul>\n<li>En reparacion<\/li>\n<li>En mora<\/li>\n<li>Suspendido<\/li>\n<li>En linea<\/li>\n<\/ul>\n<\/li>\n<li style=\"text-align: justify;\">El resultado de la consulta cualquiera que estos fueran tienen un audio con el nombre de archivo igual al\u00a0 de la consulta. Ejemplo: si la consulta devuelve suspendido en el sistema se encuentra un audio llamado suspendido.wav<\/li>\n<li>Menu para consultar otro numero o regresar al men\u00fa principal o salir<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Por el momento es todo y hay mucho que se puede hacer, espero le sea de utilidad a alguien. Hasta pronto.<\/p>\n\n<div class=\"twitter-share\"><a href=\"https:\/\/twitter.com\/intent\/tweet?via=a1ejo_ayala\" class=\"twitter-share-button\" data-size=\"large\">Twittear<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Configurar un IVR es muy sencillo desde la interfaz web de Elastix, simple para direccionar opciones a extensiones agregadas a nuestra PBX. Pero sabemos que muchas de las veces requerimos hacer cosas mas elaboradas, por ejemplo gestionar datos de una BD y hacerlos interactuar con nuestra central telef\u00f3nica. Para este ejemplo mi aplicaci\u00f3n contiene: Un\u2026 <span class=\"read-more\"><a href=\"https:\/\/alejandroayala.solmedia.ec\/?p=288\">Leer m\u00e1s &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":723,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[8],"tags":[224,24,29,35,60,64,507],"_links":{"self":[{"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/posts\/288"}],"collection":[{"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=288"}],"version-history":[{"count":5,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/posts\/288\/revisions"}],"predecessor-version":[{"id":453,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/posts\/288\/revisions\/453"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/media\/723"}],"wp:attachment":[{"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=288"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=288"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=288"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}