https://d226lax1qjow5r.cloudfront.net/blog/blogposts/ivr-java-spark-framework-dr/ivr-java-feature-image.png

Cómo crear un IVR sencillo con Java y Spark Framework

Publicado el April 26, 2021

Tiempo de lectura: 17 minutos

Un IVR es el nombre técnico dado a una llamada telefónica automatizada en la que se introducen dígitos en el teclado del teléfono y la llamada responde adecuadamente - mediante la lectura de la información, o la conexión a un número, o lo que sea. Lo mejor es que puedes crearlos con Nexmo Voice.

En este tutorial, construirás un pequeño microservicio para alojar un IVR básico. Te guiaré a través de todo lo que necesitas saber para configurar un servicio Spark que pueda recibir llamadas entrantes y capturar la entrada del usuario introducida a través del teclado.

La idea es construir un IVR realmente pequeño que permita al usuario introducir un código DTMF. En este caso, la llamada se limitará a leerle el número que haya introducido.

Creo que es muy útil tener a mano un guión o un diagrama de flujo cuando se construye un IVR. Aquí tienes el guión para tu servicio:

[Caller dials Nexmo number]

IVR: Welcome to my Nexmo IVR! Please enter a digit.

[Caller enters '5']

IVR: You entered 5. Thank you for calling!

[IVR hangs up]

El código de este tutorial se encuentra en GitHub.

Requisitos

Antes de empezar, debes tener configurado lo siguiente:

  • El sitio Nexmo CLI. (Usted puede conseguir sin esto mediante el uso de la Nexmo Dashboard, pero hace la vida mucho más fácil).

  • A JDK instalado (yo construí esto con JDK 8).

  • Maven para compilar su código Java.

  • Ngrok para que Nexmo pueda llegar al servicio que se ejecuta en su máquina de desarrollo

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.

Primeros pasos

En primer lugar, crear debe arrancar un proyecto de Maven utilizando el siguiente comando:

mvn archetype:generate -DgroupId=com.nexmo.xwithy -DartifactId=ivr-demo -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4

Ejecutando este comando se creará un archivo de proyecto Maven, y un archivo fuente en el lugar correcto - se parece un poco a esto:

ivr-demo
├───pom.xml
└───src
    └───main
        └───java
            └───com
                └───nexmo
                    └───xwithy
                        └───App.java

Abra pom.xml en tu editor de código favorito (yo uso VSCode) y primero cambia la versión de Java de 1.7 a 1.8:

<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>

A continuación, añada las dependencias de Nexmo y Spark a la sección <dependencies> sección:

<dependency>
    <groupId>com.nexmo</groupId>
    <artifactId>client</artifactId>
    <version>4.4.0</version>
</dependency>

<dependency>
    <groupId>com.sparkjava</groupId>
    <artifactId>spark-core</artifactId>
    <version>2.7.2</version>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.21</version>
</dependency>

Ahora te recomiendo compilar el proyecto, sólo para descargar las dependencias y asegurarte de que todo en tu proyecto está bien:

mvn compile

Usted debe ver un montón de salida como Maven descarga todo lo que necesita, y luego el mensaje BUILD SUCCESS. Si no es así, comprueba tu archivo XML para asegurarte de que has introducido la configuración anterior correctamente y en el lugar adecuado.

Llamadas telefónicas

Voy a explicar cómo construir el código paso a paso, pero puede ser útil echar un vistazo al resultado final, que se puede encontrar en GitHub. Está todo en una clase, y he añadido un montón de comentarios, así que espero que no sea demasiado difícil de seguir.

Casi todo va dentro de nuestro método main que se ejecuta cuando ejecutamos la clase App clase. Spark puede funcionar un poco diferente a lo que estás acostumbrado. Usted registra la forma en que le gustaría que Spark se comportara llamando a métodos estáticos, y luego Spark alojará su aplicación web ¡hasta que usted le diga que se detenga!

Ponga la siguiente línea en su método main método:

port(4567);

La línea de arriba le dice a Spark en qué puerto TCP quieres alojar tu servicio. Yo he elegido 4567. Puedes elegir un número diferente, pero asegúrate de tomar nota del número que elijas - ¡lo necesitarás más tarde! (Elija un número superior a 1024 - esto puede ahorrarle algún problema.)

Lo siguiente que debe hacer es registrar un punto final HTTP para que Nexmo lo llame. Este se alojará en /inbound y será llamado por Nexmo cuando alguien llame a tu Número Virtual Nexmo. Ponga el siguiente código dentro de su método main después de la llamada port llamada:

post("/inbound", (req, res) -> {
    res.type("application/json");
    return new Ncco(
        TalkAction.builder("Welcome to my Nexmo IVR!").build()
    ).toJson();
});

Cuando Nexmo llame a este número, su aplicación debería devolver una respuesta JSON con el siguiente aspecto:

[
  {
    "text": "Welcome to my Nexmo IVR!",
    "action": "talk"
  }
]

Esto le dirá a Nexmo que conteste la llamada y les lea un mensaje amistoso. Puede probar esto ahora, compilando y ejecutando lo siguiente desde su símbolo del sistema:

mvn compile mvn exec:java -Dexec.mainClass="com.nexmo.xwithy.App"

Spark imprimirá algunos mensajes de registro, y cuando haya terminado, puedes probarlo usando curl en la línea de comandos:

curl -X POST http://localhost:4567/inbound [{"text":"Welcome to my Nexmo IVR!","action":"talk"}]

El comando curl anterior realiza una petición HTTP POST a su servidor e imprime la respuesta. Si no se siente tan cómodo en la línea de comandos, o simplemente prefiere una aplicación visual, puede utilizar Postman para hacer lo mismo.

Puede detener el servicio en cualquier momento introduciendo Ctrl-C. Tendrás que hacer esto, y recompilar y volver a ejecutar cada vez que cambies tu código fuente y quieras probar tu servicio.

Ahora usted tiene una aplicación que puede manejar las llamadas entrantes de Nexmo Voice. Es hora de conectar un número de teléfono Nexmo a su aplicación.

Conecte Nexmo a su servicio

¿Recuerda los Requisitos donde dije que necesitarías tener instalado Ngrok? Afortunadamente, mi colega Aaron ha escrito una gran guía para usar Ngrok y Nexmo. ¡Deberías leerla! Puede hacer que Ngrok se ejecute abriendo una pestaña de la consola (necesita ejecutarlo al mismo tiempo que su servicio Java) y ejecutando el siguiente comando:

ngrok http 4567 ... Web Interface http://127.0.0.1:4040 Forwarding http://r6nd0m.ngrok.io -> http://localhost:4567 Forwarding https://r6nd0m.ngrok.io -> http://localhost:4567

Verás que en la salida hay dos líneas llamadas "Reenvío"; una tiene una URL HTTP y la otra es HTTPS. Toma nota de la URL HTTPS - la necesitarás en un minuto. La otra cosa a tener en cuenta es la línea 'Interfaz Web'. Te recomiendo que abras esa URL en tu navegador ahora mismo - porque estás a punto de comprobar que Ngrok está conectado a tu servicio Java IVR.

Utilizando curl (o Postman), ejecute una solicitud similar a la que hizo anteriormente, pero esta vez utilice la URL Ngrok que le acaban de dar, con /inbound al final. La mía tiene este aspecto:

curl -X POST https://r6nd0m.ngrok.io/inbound [{"text":"Welcome to my Nexmo IVR!","action":"talk"}]

Deberías ver el mismo resultado que antes. Esto significa que Nexmo será capaz de llegar a su servicio (mientras que tanto Ngrok y su servicio todavía se están ejecutando).

Esperemos que usted tiene una cuenta de Nexmo, y la herramienta Nexmo CLI configurado. Si no es así, ¡ahora es el momento! Cuando esté listo ...

Comprar un número Nexmo

Puede empezar a alquilar un número Nexmo ejecutando el siguiente nexmo en la línea de comandos:

nexmo number:buy --country_code US

Si te gusta el número que te ha seleccionado, escribe "confirmar" y pulsa Intro. Si prefieres elegir un número de una lista, te recomiendo que utilices el Panel Nexmo. Toma nota del número.

Crear una aplicación Nexmo Voice

Ahora necesitas crear una aplicación Nexmo Voice, que agrupe uno o más Numbers Nexmo con alguna configuración webhook. ¡Recuerde cambiar el nombre de host Ngrok al que se le dio anteriormente!

nexmo app:create --keyfile private.key "My IVR Demo" --answer_method POST --event_method POST https://r6nd0m.ngrok.io/inbound https://r6nd0m.ngrok.io/event

El comando anterior configura una aplicación Nexmo que sabe cómo llamar a su servicio cuando se recibe una llamada entrante. También ha guardado la clave privada en un archivo local private.key. No la usarás en este tutorial, pero puede ser útil más adelante cuando añadas más funcionalidad a tu servicio.

Anote el ID de su solicitud. Lo necesitará a continuación.

Vincule su número Nexmo

Utilizando el número de teléfono y el ID de la aplicación que se le proporcionó anteriormente, ejecute el siguiente comando:

nexmo link:app NEXMO_NUMBER APPLICATION_ID

Pruebe su servicio

Ahora, si llama al número de Nexmo desde su teléfono móvil, Nexmo debería descolgar, y usted debería escuchar el mensaje "¡Bienvenido a mi Nexmo IVR!" y luego la llamada colgará.

Si esto no funciona, comprueba la consola de Ngrok en tu navegador en http://localhost:4040/ y asegúrate de que la llamada fue recibida por Ngrok y pasada con éxito al servicio Java que se ejecuta en tu máquina de desarrollo.

Conviértalo en un IVR

Tu IVR todavía no es muy útil. Te mostraré cómo permitir que el usuario introduzca datos desde su teclado (esto se llama DTMF, que significa Frecuencia Modulada de Doble Tono, pero eso no es realmente importante).

Pedir información

En primer lugar, vuelva a la llamada get que has escrito, y añade un segundo parámetro a la llamada al constructor Ncco constructor, para que se vea así:

return new Ncco(
    TalkAction.builder("Welcome to my Nexmo IVR! Please enter a digit.")
            .build(),
    InputAction.builder()
            .maxDigits(1)
            .timeOut(5)
            .eventUrl(pathToUrl(req, "/input"))
            .build()
).toJson();

Esta InputAction indica a Nexmo que espere 5 segundos a que el usuario introduzca 1 dígito en su teclado. Cuando se introduzca el dígito, Nexmo realizará una llamada a su servidor en /input con los detalles del código DTMF introducido por el usuario. Escribirás el manejador para /input en un momento.

También he modificado la llamada TalkAction, de modo que hemos establecido bargeIn a true. Esto significa que un oyente con prisa no necesita esperar a que el mensaje se complete antes de introducir el código DTMF.

La otra cosa a tener en cuenta es el método pathToUrl que se utiliza para generar una URL absoluta a su servicio. Este es un método de utilidad de 10 líneas que he escrito. Pégalo en tu clase App de la clase código en GitHub. No voy a explicar cómo funciona aquí, ¡porque no es realmente de lo que trata este tutorial!

Manejar la entrada

Ahora que ha ordenado a Nexmo que llame a /input cuando el usuario introduzca un código DTMF, necesitas manejar esa llamada. Introduzca el siguiente código al final de su método main método:

post("/input", (req, res) -> {
    InputEvent input = InputEvent.fromJson(req.body());

    res.type("application/json");
    String message = "You entered " + input.getDtmf();
    return new Ncco(TalkAction.builder(message).build()).toJson();
});

El código anterior es muy similar a su actual /inbound pero en este caso analiza el JSON recibido en un InputEvent en la solicitud, extrae el código DTMF de eso. A continuación, responde al usuario mediante la lectura de un mensaje diciéndole el código que ha introducido.

Pruebe su aplicación llamando a su número Nexmo e introduciendo un código en el teclado cuando se le solicite.

Conclusión

Este es un ejemplo muy sencillo de respuesta a un código DTMF, pero puedes ampliarlo para adaptarlo a tu aplicación. Tal vez podrías buscar un registro en una base de datos con un ID introducido por el usuario, o podrías construir una centralita para reenviar a alguien de tu organización. Hay muchas posibilidades.

Para más información, consulte nuestra galardonada documentación en Desarrollador Nexmo.

Si estás construyendo un servicio Spark más grande, no te recomendaría poner todo tu código en un único método main ¡método! Afortunadamente, el equipo de Spark ha escrito un entrada de blog describiendo las mejores prácticas para aplicaciones más grandes.

Si tienes algún comentario, o quieres ayuda con este tutorial, soy @judy2k en Twitter. Envíame un mensaje de texto. También puedes enviar un correo electrónico a nuestro equipo de relaciones con los desarrolladores a devrel@nexmo.como unirte a la Slack de la comunidad Nexmo.

Compartir:

https://a.storyblok.com/f/270183/150x150/a3d03a85fd/placeholder.svg
Mark SmithAntiguos alumnos de Vonage

Mark era nominalmente responsable de las bibliotecas cliente de Nexmo (aunque sólo escribe las bibliotecas Python y Java). Originalmente era un desarrollador Java, ha sido un desarrollador Python durante 18 años, y está incursionando cada vez más en Go y Rust. Le gusta llevar al límite los lenguajes de programación y luego enseñar estas técnicas a otros programadores. Tiene un sombrero vikingo, pero no es un vikingo, y es Judy2k en Twitter por razones que no discutirá.