Adolfo Garcia Yague VoiceXML, CCXML y SALT Convergencia Voz y Aplicaciones IV Jornadas sobre Técnologías de la Información en el CSIC Centro de Investigaciones Científicas Isla de la Cartuja Sevilla, 12-14 de Mayo 2004 Adolfo García Yagüe [email protected] Versión 1.2 Agenda • Antecedentes de la convergencia Voz, Datos y Aplicaciones • Necesidades y Retos actuales • Tecnologías – VoiceXML – CCXML – SALT • Aplicaciones 2 Antecedentes: El Legado CTI Ï Amplio número de aplicaciones (casi todo está inventado... ?...) Ï Efectividad demostrada Ï Cultura asentada en las organizaciones Ï Madurez de las tecnologías subyacentes (Call Control, Media Services) Ð Soluciones poco abiertas Ð APIs Limitadas y complejas: TAPI, TSAPI Ð Integración compleja -y propietaria- con las tecnologías Internet: IP, SIP, HTTP, XML, etc Ð Soluciones caras y rígidas, no facilitando así la rápida implantación y los cambios 3 Necesidades y Retos Actuales • Relación con los Clientes: – Extender la interacción con ellos a través de Internet – Facilitar la accesibilidad a un mayor número de clientes, a través del teléfono, a nuestros productos y servicios • Dentro de las Organizaciones: – Integrar Voz y Datos sobre una única Red – Movilidad de las personas y equipos de trabajo – Simplificar la puesta en servicio de nuevas actividades, departamentos y campañas – Integración de la voz en el escritorio y aplicaciones corporativas – Tecnología basada en estándares, que aseguren la interoperabilidad y supervivencia de una solución • Internet e Intranet: – Nuevos modelos de programación e interfaces para 4 acceder a la información Agenda • Antecedentes de la convergencia Voz, Datos y Aplicaciones • Necesidades y Retos actuales • Tecnologías – VoiceXML – CCXML – SALT • Aplicaciones 5 Voice Extensible Markup Language (VoiceXML) • Creación y Gestión de Diálogos basados en XML • Construido a partir de las iniciativas VoXML (Motorola) y SpeechML (IBM) • Estandarizado bajo los auspicios del W3C: – V.1.0 Marzo 2000 – V.2.0 Febrero 2004 • VoiceXML Forum es la organización que está promoviendo el desarrollo y la adopción del estándar 6 Capacidades de VoiceXML • VoiceXML permite desarrollar aplicaciones capaces de: – – – – Reconocer tonos (DTMF) Reconocimiento de voz Reproducción de ficheros de audio y streams Síntesis de voz (Text-to-speech) • VoiceXML no ha sido pensado para: – Establecer multiconferencias – Generar llamadas – Encaminar llamadas • VoiceXML se complementa con SIP y CCXML 7 Escenario VoiceXML Web Server Este equipo lleva incluido el cliente VoiceXML o browser ASR (Automatic Speech Recongnition) TTS (Text-to-Speech) P MRC P HTT Red IP Red PSTN H.323-SIP VoiceXML Gateway SMTP Server Teléfono IP • • • SMTP-POP3 SIP Proxy Server Gatekeeper H.323 El Gateway VoiceXML hace las funciones de navegador, aportando un nivel de presentación basado en la reproducción y reconocimiento de la voz (Voice Browser). Puede residir en un Router o RAS Si los equipos anteriores no cuentan con capacidades de Voice Browser, o estas son limitadas, vía MRCP puede usar los servicios de sistemas ASR y TTS 8 El VoiceXML GW puede interoperar con buzones de correo, servicios SIP, H.323, etc. Acceso Global a la Información y Portabilidad de las Aplicaciones Usuario presente en Internet BB.DD 1 HTTP Server Dígame o introduzca su número de usuario, por favor 3 Dígame o introduzca su clave de acceso, por favor 5 Buenas Días Sr. García, le informamos que desde su última visita su cartera de valores se ha revalorizado en un 2,5%. ¿Qué operación desea realizar?. Pulse 1 si desea conocer la opciones Usuario con acceso a un teléfono 2 4 6 1234567890 asdfgh valores Red PSTN VoiceXML Gateway 9 Aspecto de una aplicación VoiceXML • Una session VoiceXML se inicia cuando el teléfono del cliente alcanza al Gateway. En este instante se inicia la aplicación • Una aplicación está constituida por un conjunto de dialog states. El usuario siempre se encuentra dentro de un dialog. Desde un dialog se puede saltar a través de un URL a otro dialog • Hay dos tipos de dialog: forms y menus • Un form presenta y recoge información (voz o DTMF) • Un menu presenta al usuario diferentes opciones y permite la transición a otros dialog • Speech Synthesis Markup Language (SSML) define los aspectos relativos a reproducción de audio y síntesis de voz: pronunciación, género, edad, volumen, tono y énfasis. Recomendación v.1.0 estimada en 1Q 2004 10 Speech Recognition Grammar • Para el reconocimiento de voz, cada dialog emplea una Grammar • En una Grammar se establecen las palabras y declaraciones que serán válidas como respuesta • Tras el reconocimiento, la Grammar retorna variables a la aplicación VoiceXML en curso • Una Grammar puede residir como un elemento más dentro de la aplicación (inline) o bien, puede ser referenciada: fichero.grxml • Speech Recognition Grammar Specification (SRGR) establece el uso de XML como sintaxis 11 para la programación de Grammars Ejemplo de navegación por tonos Para deportes pulse 1, para el tiempo pulse 2, para astrología pulse 3 <?xml <?xml version="1.0" version="1.0" encoding="UTF-8"?> encoding="UTF-8"?> <vxml version="2.0" xmlns="http://www.w3.org/2001/vxml" <vxml version="2.0" xmlns="http://www.w3.org/2001/vxml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/vxml xsi:schemaLocation="http://www.w3.org/2001/vxml http://www.w3.org/TR/voicexml20/vxml.xsd"> http://www.w3.org/TR/voicexml20/vxml.xsd"> <menu> <menu> <property <property name="inputmodes" name="inputmodes" value="dtmf"/> value="dtmf"/> <prompt> <prompt> For For sports sports press press 1, 1, For For weather weather press press 2, 2, For For astrology astrology press press 3. 3. </prompt> </prompt> <choice <choice dtmf="1" dtmf="1" next="http://www.sports.example.com/vxml/start.vxml"/> next="http://www.sports.example.com/vxml/start.vxml"/> <choice dtmf="2" <choice dtmf="2" next="http://www.weather.example.com/intro.vxml"/> next="http://www.weather.example.com/intro.vxml"/> <choice <choice dtmf="3" dtmf="3" next="http://www.astrology.example.com/astronews.vxml"/> next="http://www.astrology.example.com/astronews.vxml"/> </menu> </menu> </vxml> </vxml> 12 Ejemplo de una aplicación VoiceXML y su Grammar con las respuestas posibles <?xml <?xml version="1.0"? version="1.0"? encoding="ISO-8859-1"?> encoding="ISO-8859-1"?> <vxml <vxml version="2.0" version="2.0" application="example05.vxml"> application="example05.vxml"> <!-<!-- root root document document example example -- start start to to interpret interpret this this file file --> --> <form <form id="start"> id="start"> <field <field name="answer"> name="answer"> <prompt> <prompt> Are Are you you sleepy? sleepy? </prompt> </prompt> <grammar <grammar src="yesno.grxml"/> src="yesno.grxml"/> <filled> <filled> <if <if cond="answer=='yes'"> cond="answer=='yes'"> So So you you are are sleepy. sleepy. Me Me too. too. <else/> <else/> So So you you are are not not sleepy. sleepy. But But II am. am. </if> </if> </filled> </filled> </field> </field> <block> <block> <goto <goto next="example06.vxml"/> next="example06.vxml"/> </block> </block> </form> </form> </vxml> </vxml> <?xml <?xml version="1.0" version="1.0" encoding="ISO-8859-1"?> encoding="ISO-8859-1"?> <grammar <grammar root="main" root="main" version="1.0"> version="1.0"> <rule id="main" <rule id="main" scope="public"> scope="public"> <one-of> <one-of> <item><ruleref <item><ruleref uri="#yes" uri="#yes" tag="yes"/></item> tag="yes"/></item> <item><ruleref <item><ruleref uri="#no" uri="#no" tag="no"/></item> tag="no"/></item> </one-of> </one-of> </rule> </rule> <rule <rule id="yes"> id="yes"> <one-of> <one-of> <item>yes</item> <item>yes</item> <item>yeah</item> <item>yeah</item> <item>yep</item> <item>yep</item> <item>sure</item> <item>sure</item> </one-of> </one-of> </rule> </rule> <rule <rule id="no"> id="no"> <one-of> <one-of> <item>no</item> <item>no</item> <item>not</item> <item>not</item> <item>nope</item> <item>nope</item> </one-of> </one-of> </rule> </rule> </grammar> </grammar> 13 Ejemplo grabación de un mensaje <?xml <?xml version="1.0" version="1.0" encoding="UTF-8"?> encoding="UTF-8"?> <vxml version="2.0" <vxml version="2.0" xmlns="http://www.w3.org/2001/vxml" xmlns="http://www.w3.org/2001/vxml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/vxml xsi:schemaLocation="http://www.w3.org/2001/vxml http://www.w3.org/TR/voicexml20/vxml.xsd"> http://www.w3.org/TR/voicexml20/vxml.xsd"> <form> <form> <property <property name="bargein" name="bargein" value="true"/> value="true"/> <block> <block> <prompt> <prompt> Riley Riley is is not not available available to to take take your your call. call. </prompt> </prompt> </block> </block> <record <record name="msg" name="msg" beep="true" beep="true" maxtime="10s" maxtime="10s" finalsilence="4000ms" finalsilence="4000ms" dtmfterm="true" dtmfterm="true" type="audio/x-wav"> type="audio/x-wav"> <prompt <prompt timeout="5s"> timeout="5s"> Record Record aa message message after after the the beep. beep. </prompt> </prompt> <noinput> <noinput> II didn't didn't hear hear anything, anything, please please try try again. again. </noinput> </noinput> </record> </record> <field <field name="confirm"> name="confirm"> <grammar <grammar type="application/srgs+xml" type="application/srgs+xml" src="/grammars/boolean.grxml"/> src="/grammars/boolean.grxml"/> <prompt> <prompt> Your Your message message is is <audio <audio expr="msg"/>. expr="msg"/>. </prompt> </prompt> <prompt> <prompt> To To keep keep it, it, say say yes. yes. To To discard discard it, it, say say no. no. </prompt> </prompt> <filled> <filled> <if <if cond="confirm"> cond="confirm"> <submit <submit next="save_message.pl" next="save_message.pl" enctype="multipart/form-data" enctype="multipart/form-data" method="post" method="post" namelist="msg"/> namelist="msg"/> </if> </if> <clear/> <clear/> </filled> </filled> </field> </field> </form> </form> </vxml> </vxml> Riley no está disponible para atender su llamada Grabe su mensaje después del beep No he escuchado nada. Por favor, vuelva a intentarlo Hola soy Carol, llámame cuando puedas Su mensaje es: hola soy Carol, llámame cuando puedas Para mantenerlo diga “si”. Para descartarlo diga “no” 14 Algunos elementos de VoiceXML • • • • • • • Entrada de datos: <field>, <form> Seleccionar gramáticas: <grammar> Asignación de variables: <assign> y <var> Reproducción de un clip de audio: <audio> Grabación de la voz: <record> Definición de menús: <menu> y <choice> Condicionales y saltos: <if>, <else>, <elseif>, <goto> y <return> • Anidar diálogos: <subdialog> • Control de la sesión: <disconnect>, <transfer>, <exit> • Incluir scripts ECMA/CTSA: <script> 15 Call Control Extensible Language (CCXML) • CCXML ha sido diseñado para desarrollar aplicaciones de Call Control (gestión de llamadas, proceso de eventos y conferencias) • CCXML está impulsado por el W3C y emplea XML como sintaxis • CCXML y VoiceXML no son dependientes: – VoiceXML puede soportar otros métodos para la gestión de llamadas – Una implementación CCXML puede no incluir diálogos VoiceXML • CCXML puede emplear diferentes definiciones para el control de llamadas: JAIN Call Control, ECMA CSTA y ECTF S.100/C.001 • Especificación V. 1 Junio 2003 Working Draft 16 Tratamiento de eventos en CCXML • Una aplicación CCXML se comporta como una máquina de estados gobernada por eventos. <evenhandler> • La definición de eventos y objetos deriva de JAIN/JCC: – Call (estado de las llamadas) – Connection (nº conexiones, estado, nº llamante...) – Provider (estado de PSTN, PBX y redes externas) – Standard (estado de aplicación CCXML y VoiceXML) • Dentro de la aplicación, la manipulación de un evento incluye estados de transición <transition> que desencadenan acciones: – Aceptar/rechazar llamada – Encaminar llamada – Iniciar/finalizar conferencia 17 – Iniciar un diálogo VoiceXML... Aspecto de una aplicación CCXML CCXML Browser Aplicación CCXML Manipulador Evento 1 <eventhandler> --</eventhandler> Manipulador Evento 2 <eventhandler> --</eventhandler> Manipulador Evento 3 <eventhandler> --</eventhandler> ... <eventhandler> --</eventhandler> Posibles Acciones Trigger 1 Trigger 1 <transition> --</ transition> Incoming Call <accept> <reject> <hold> Trigger 2 < transition> --</ transition> Outbound Call Manipulador Evento 2 ... Manipulador Evento n Manipulador Evento 1 Manipulador Evento n <createcall> Disconnect Call <disconnect> Start/Terminate VoiceXML dialog <dialogstart> <dialogterminate> Redirect Call <redirect> Create/Destroy Conference call <createconference> <destroyconference> Bridge/Unbridge Call <join> y <unjoin> 18 Algunas capacidades de CCXML • Routing: Encamina una llamada a la siguiente extensión disponible. Incluye capacidades de búscame, sígueme y supervisión de trasferencias • Selective Call Answering: Decide quién puede responder a una llamada en función de la información del llamante • Whisper transfer: envió de un mensaje al destinatario antes de establecer la conexión con el llamante • Outbound Calling: Inicia una llamada y arranca un diálogo VoiceXML cuando la conexión es establecida • Conferencing: Permite a múltiples participantes unirse a una conferencia telefónica • Dialog Execution: Inicio y finalización de diálogos 19 VoiceXML Ejemplo CCXML para bloquear la entrada de ciertas llamadas <?xml <?xml version="1.0" version="1.0" encoding="UTF-8"?> encoding="UTF-8"?> <ccxml <ccxml version="1.0"> version="1.0"> <eventhandler> <eventhandler> <transition <transition event= event= "connection.CONNECTION_ALERTING“ "connection.CONNECTION_ALERTING“ name="evt"> name="evt"> <if <if cond="evt.callerid cond="evt.callerid == == ‘917776714'"> ‘917776714'"> <reject/> <reject/> <exit/> <exit/> <elseif cond="evt.callerid <elseif cond="evt.callerid == == ‘917856436'"/> ‘917856436'"/> <reject/> <reject/> <exit/> <exit/> <else/> <else/> <accept <accept callid="evt.callid"/> callid="evt.callid"/> </if> </if> </transition> </transition> <transition <transition event= event= "connection.CONNECTION_CONNECTED"> "connection.CONNECTION_CONNECTED"> <dialogstart src=“welcome.vxml'"/> <dialogstart src=“welcome.vxml'"/> </transition> </transition> <transition <transition event="dialog.exit"> event="dialog.exit"> <log <log expr="'Thats expr="'Thats all all for for now now folks.'"/> folks.'"/> <exit/> <exit/> </transition> </transition> </eventhandler> </eventhandler> </ccxml> </ccxml> • connection.CONNECTION_ALER TING indica a llegada de una llamada • Configuramos un estado de transición en el que establecemos una serie de condicionales en función del número telefónico del llamante evt.callerid: – Si el número telefónico es 917776714 o 917856436 rechazamos las llamadas – Si el número telefónico es diferente a los anteriores se establece la llamada y se inicia un dialogo VoiceXML Bienvenido a MoneyBank.com. Dígame o introduzca su clave 20 de acceso, por favor Ejemplo CCXML para iniciar llamadas <?xml <?xml version="1.0" version="1.0" encoding="UTF-8"?> encoding="UTF-8"?> <ccxml <ccxml version="1.0"> version="1.0"> <var <var name="state0" name="state0" expr="'init'"/> expr="'init'"/> <eventhandler <eventhandler statevariable="state0"> statevariable="state0"> <transition <transition state="'init'" state="'init'" event="ccxml.loaded"> event="ccxml.loaded"> <assign <assign name="state0" name="state0" expr="'dialing'"/> expr="'dialing'"/> <createcall <createcall dest="‘917856436'"/> dest="‘917856436'"/> </transition> </transition> <transition <transition state="'dialing'" state="'dialing'" event="connection.CONNECTION_CONNECTED"> event="connection.CONNECTION_CONNECTED"> <assign <assign name="state0" name="state0" expr="'connected'"/> expr="'connected'"/> <dialogstart <dialogstart src="'hello.vxml'"/> src="'hello.vxml'"/> </transition> </transition> <transition <transition state="'dialing'" state="'dialing'" event="connection.CONNECTION_FAILED"> event="connection.CONNECTION_FAILED"> <log <log expr="'Failed expr="'Failed making making outbound outbound call'"/> call'"/> <exit/> <exit/> </transition> </transition> <transition <transition state="'connected'" state="'connected'" event="dialog.exit"> event="dialog.exit"> <log <log expr="'Thats expr="'Thats all all for for now now folks.'"/> folks.'"/> <exit/> <exit/> </transition> </transition> <transition <transition event="call.CALL_INVALID" event="call.CALL_INVALID" name="evt"> name="evt"> <exit/> <exit/> </transition> </transition> <transition <transition event="error.*" event="error.*" name="evt"> name="evt"> <log <log expr="'an expr="'an error error has has occurred occurred ('(' ++ evt.error evt.error ++ ')'"/> ')'"/> <exit/> <exit/> </transition> </transition> </eventhandler> </eventhandler> </ccxml> </ccxml> • Definimos un manipulador de evento para iniciar una llamada desde nuestra aplicación • Intentamos establecer una llamada <createcall> contra el abonado 917856436 – Si el abonado anterior descuelga el teléfono iniciamos un diálogo VoiceXML – Si la comunicación con el abonado no es posible se inician los eventos connection.CONNECTION_FA ILED y call.CALL_INVALID. • En el log de actividades anotamos la imposibilidad de establecer la comunicación y las causas 21 Ejemplo CCXML para el establecimiento de conferencias <transition <transition state="'init'" state="'init'" event="connection.CONNECTION_ALERTING" event="connection.CONNECTION_ALERTING" name="evt"> name="evt"> <log <log expr="'---expr="'---- assigning assigning incoming incoming callid callid to to [line_0] [line_0] ----'"/> ----'"/> <var <var name="line_0" name="line_0" expr="evt.callid"/> expr="evt.callid"/> <log <log expr="'---expr="'---- creating creating conference conference ----'"/> ----'"/> <createconference id="smallConf" <createconference id="smallConf" /> /> </transition> </transition> <transition <transition state="'init'" state="'init'" event="ccxml.conference.created"> event="ccxml.conference.created"> <assign name="state0" expr="'docalls'"/> <assign name="state0" expr="'docalls'"/> <log <log expr="'---expr="'---- conference conference created created and and its its ID ID is is ['[' ++ smallConf smallConf ++ ']'] ----'"/> ----'"/> <log <log expr="'---expr="'---- accepting accepting incoming incoming call call [line_0] [line_0] ----'"/> ----'"/> <accept <accept callid="line_0"/> callid="line_0"/> <log expr="'---<log expr="'---- making making outbound outbound calls calls ----'"/> ----'"/> <createcall dest="‘917856436'" name="line_1" <createcall dest="‘917856436'" name="line_1" /> /> <createcall <createcall dest="‘sip:[email protected]'" dest="‘sip:[email protected]'" name="line_2" name="line_2" /> /> <createcall <createcall dest="‘sip:[email protected]'" dest="‘sip:[email protected]'" name="line_3" name="line_3" /> /> </transition> </transition> • Aceptamos una llamada, la ubicamos en la línea 0 y creamos una conferencia a la que denominamos smallConf <createconference id="smallConf"/> • A continuación añadimos a la conferencia al abonado 917856436 y a los abonados SIP [email protected] y [email protected] 22 Speech Application Language Tags (SALT) • Es una propuesta –abierta- de Microsoft para la creación de aplicaciones accesibles desde cualquier dispositivo (Multi-modal): – Teléfono – iPAQ, PDA, PocketPC – Microbrowsers (teléfonos GPRS, UMTS) • A diferencia de VoiceXML, la característica Multimodal hace posible por ejemplo, visualizar datos a través de un display de un PDA o teléfono e interactuar con la voz (o viceversa) • SALT Forum es la organización que está promoviendo esta iniciativa (Microsoft, Philips, Cisco, Intel y SpeechWorks entre otros) • Recientemente, el W3C ha puesto en marcha el 23 Multimodal Working Group (MMWG) SALT y Acceso Multi-modal 1 Dígame o introduzca su número de usuario, por favor 1 3 Dígame o introduzca su clave de acceso, por favor Internet HTTP Server Multi-modal Browser 2 4 BB.DD 1234567890 asdfgh Red PSTN SALT Voice Browser 24 Características de SALT • SALT emplea las gramáticas y modelos de síntesis del W3C (SRGS y SSML) • Desde PCs hasta dispositivos móviles pueden ser speech-enable. En los PCs, las capacidades de reconocimiento y síntesis pueden residir localmente, mientras que en equipos de menor capacidad estas son desarrolladas en un servidor remoto • Se definen tres tipos de elementos principales: – <listen> Reconocimiento de voz, ejecuta y manipula eventos asociados a la entrada de voz – <prompt> Síntesis de voz y reproducción de sonidos – <dtmf> Configuración y control de tonos 25 Ejemplo de formulario de entrada de datos y reconocimiento de voz <!—<!—- HTML HTML --> --> <html <html xmlns:salt="urn:saltforum.org/schemas/020124"> xmlns:salt="urn:saltforum.org/schemas/020124"> <body <body onload="RunAsk()"> onload="RunAsk()"> <form <form id="travelForm"> id="travelForm"> <input <input name="txtBoxOriginCity" name="txtBoxOriginCity" type="text" type="text" /> /> <input <input name="txtBoxDestCity" name="txtBoxDestCity" type="text" type="text" /> /> </form> </form> <!—<!—- Speech Speech Application Application Language Language Tags Tags --> --> <salt:prompt <salt:prompt id="askOriginCity"> id="askOriginCity"> Where Where would would you you like like to to leave leave from? from? </salt:prompt> </salt:prompt> <salt:prompt <salt:prompt id="askDestCity"> id="askDestCity"> Where Where would would you you like like to to go go to? to? </salt:prompt> </salt:prompt> <salt:prompt <salt:prompt id="sayDidntUnderstand" id="sayDidntUnderstand" onComplete="runAsk()"> onComplete="runAsk()"> Sorry, Sorry, II didn't didn't understand.</salt:prompt> understand.</salt:prompt> <salt:listen <salt:listen id="recoOriginCity" id="recoOriginCity" onReco="procOriginCity()" onReco="procOriginCity()" onNoReco="sayDidntUnderstand.Start()"> onNoReco="sayDidntUnderstand.Start()"> <salt:grammar <salt:grammar src="city.grxml" src="city.grxml" /> /> </salt:listen> </salt:listen> <salt:listen <salt:listen id="recoDestCity" id="recoDestCity" onReco="procDestCity()" onReco="procDestCity()" onNoReco="sayDidntUnderstand.Start()"> onNoReco="sayDidntUnderstand.Start()"> <salt:grammar <salt:grammar src=“city.grxml" src=“city.grxml" /> /> </salt:listen> </salt:listen> <!—<!—- script script --> --> <script> <script> function function RunAsk() RunAsk() {{ ifif (travelForm.txtBoxOriginCity.value=="") (travelForm.txtBoxOriginCity.value=="") {{ askOriginCity.Start(); askOriginCity.Start(); recoOriginCity.Start(); recoOriginCity.Start(); }} else else ifif (travelForm.txtBoxDestCity.value=="") (travelForm.txtBoxDestCity.value=="") {{ askDestCity.Start(); askDestCity.Start(); recoDestCity.Start(); recoDestCity.Start(); }} }} function function procOriginCity() procOriginCity() {{ travelForm.txtBoxOriginCity.value travelForm.txtBoxOriginCity.value == recoOriginCity.text; recoOriginCity.text; RunAsk(); RunAsk(); }} function function procDestCity() procDestCity() {{ travelForm.txtBoxDestCity.value travelForm.txtBoxDestCity.value == recoDestCity.text; recoDestCity.text; travelForm.submit(); travelForm.submit(); }} </script> </script> </body> </body> </html> </html> • De manera reiterativa el script RunAsk() pregunta e intenta conocer la ciudad origen y ciudad destino • Para ello comprueba si los datos han sido introducidos a través de alguna de las siguientes vías: – Formularios textuales txtBoxOriginCity y txtBoxDestCity – Formularios de voz recoOriginCity y recoDestCity 26 Conclusiones • VoiceXML simplifica notablemente el desarrollo de servicios de atención telefónica. “Es tan fácil y rápido como la actualización de una página Web”. • VoiceXML facilita la integración con otras aplicaciones corporativas: correo, BBDD, etc. • VoiceXML es Internet: es estándar y portable • CCXML pone al alcance de las organizaciones el diseño, personalización e integración de avanzados servicios de telefonía • SALT abre la puerta de la navegación e interacción Multimodal sobre Internet a millones de nuevos usuarios y dispositivos • A través de ECMA y ECTF; VoiceXML, CCXML y SALT pueden integrarse con plataformas y arquitecturas CTI 27 Gracias por su Atención 28