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

Wie man eine einfache IVR mit Java und dem Spark Framework erstellt

Zuletzt aktualisiert am April 26, 2021

Lesedauer: 16 Minuten

Ein IVR ist der technische Name für einen automatisierten Telefonanruf, bei dem Sie Ziffern auf Ihrer Telefontastatur eingeben und der Anrufer entsprechend reagiert - indem er Ihnen Informationen vorliest oder Sie mit einer Nummer verbindet oder was auch immer. Das Tolle daran ist, dass Sie sie mit Nexmo Voice erstellen können!

In diesem Tutorial werden Sie einen kleinen Microservice erstellen, um eine einfache IVR zu hosten. Ich führe Sie durch alles, was Sie wissen müssen, um einen Spark-Dienst einzurichten, der eingehende Anrufe empfangen und Benutzereingaben über die Tastatur erfassen kann.

Die Idee ist, eine wirklich kleine IVR zu bauen, die es dem Benutzer erlaubt, einen DTMF-Code einzugeben. Unter diesem Fall wird Ihnen der Anruf einfach die eingegebene Nummer vorgelesen.

Ich finde es sehr hilfreich, entweder ein Skript oder ein Flussdiagramm zur Hand zu haben, wenn man ein IVR erstellt. Hier ist das Skript für Ihren Dienst:

[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]

Den Code für dieses Tutorial finden Sie auf GitHub.

Anforderungen

Bevor ich anfange, sollten Sie folgende Einstellungen vornehmen:

  • Die Nexmo CLI. (Sie können auch ohne diese Funktion auskommen, indem Sie das Nexmo Dashboard verwenden, aber es macht das Leben viel einfacher!)

  • A JDK installiert (ich habe es mit JDK 8 gebaut).

  • Maven um Ihren Java-Code zu erstellen.

  • Ngrok damit Nexmo den Dienst erreichen kann, der auf Ihrem Entwicklungsrechner läuft

Vonage API-Konto

Um dieses Tutorial durchzuführen, benötigen Sie ein Vonage API-Konto. Wenn Sie noch keines haben, können Sie sich noch heute anmelden und mit einem kostenlosen Guthaben beginnen. Sobald Sie ein Konto haben, finden Sie Ihren API-Schlüssel und Ihr API-Geheimnis oben auf dem Vonage-API-Dashboard.

In diesem Lernprogramm wird auch eine virtuelle Telefonnummer verwendet. Um eine zu erwerben, gehen Sie zu Rufnummern > Rufnummern kaufen und suchen Sie nach einer Nummer, die Ihren Anforderungen entspricht.

Erste Schritte

Zunächst sollte ein Maven-Projekt mit dem folgenden Befehl erstellt werden:

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

Wenn Sie diesen Befehl ausführen, wird eine Maven-Projektdatei und eine Quelldatei an der richtigen Stelle erstellt - es sieht in etwa so aus:

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

Öffnen Sie pom.xml in Ihrem bevorzugten Code-Editor (ich verwende VSCode) und ändern Sie zunächst die Zielversion von Java von 1.7 auf 1.8:

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

Fügen Sie dann die Abhängigkeiten von Nexmo und Spark in den <dependencies> Abschnitt hinzu:

<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>

Jetzt empfehle ich Ihnen, das Projekt zu kompilieren, um die Abhängigkeiten herunterzuladen und sicherzustellen, dass alles in Ihrem Projekt in Ordnung ist:

mvn compile

Sie sollten eine Menge Ausgabe sehen, während Maven alles herunterlädt, was es braucht, und dann die Meldung BUILD SUCCESS. Wenn dies nicht der Fall ist, überprüfen Sie Ihre XML-Datei, um sicherzustellen, dass Sie die obige Konfiguration korrekt und an der richtigen Stelle eingegeben haben.

Lassen Sie uns Anrufe entgegennehmen

Ich werde erklären, wie man den Code Schritt für Schritt aufbaut, aber es kann hilfreich sein, einen Blick auf das Endergebnis zu werfen, das Sie auf GitHub. Es ist alles in einer Klasse, und ich habe viele Kommentare hinzugefügt, so dass es hoffentlich nicht zu schwierig ist, zu folgen.

Fast alles wird in unserer main Methode, die ausgeführt wird, wenn wir die App Klasse ausführen. Spark funktioniert vielleicht etwas anders, als Sie es gewohnt sind. Sie registrieren die Art und Weise, wie Spark sich verhalten soll, indem Sie statische Methoden aufrufen, und dann wird Spark Ihre Webanwendung hosten, bis Sie ihm sagen, dass es aufhören soll!

Fügen Sie die folgende Zeile in Ihre main Methode ein:

port(4567);

In der Zeile oben wird Spark mitgeteilt, an welchem TCP-Port Sie Ihren Dienst hosten möchten. Ich habe 4567 gewählt. Sie können eine andere Nummer wählen, aber notieren Sie sich die Nummer, die Sie wählen - Sie werden sie später brauchen! (Wählen Sie eine Zahl über 1024 - das erspart Ihnen vielleicht einige Probleme.)

Als Nächstes sollten Sie einen HTTP-Endpunkt registrieren, den Nexmo aufrufen soll. Dieser wird gehostet unter /inbound gehostet und wird von Nexmo aufgerufen, wenn jemand Ihre virtuelle Nexmo-Nummer anruft. Fügen Sie den folgenden Code ein innerhalb von Ihrer main Methode, nach dem port Aufruf:

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

Wenn Nexmo diese Nummer anruft, sollte Ihre Anwendung eine JSON-Antwort zurückgeben, die wie folgt aussieht:

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

Dadurch wird Nexmo angewiesen, den Anruf entgegenzunehmen und dem Anrufer eine freundliche Nachricht vorzulesen. Sie können dies jetzt testen, indem Sie das Folgende kompilieren und von Ihrer Eingabeaufforderung aus ausführen:

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

Spark gibt einige Protokollmeldungen aus, und wenn es fertig ist, können Sie es mit curl auf der Kommandozeile testen, etwa so:

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

Der obige Befehl curl stellt eine HTTP-POST-Anfrage an Ihren Server und gibt die Antwort aus. Wenn Sie sich mit der Befehlszeile nicht so gut auskennen oder einfach eine visuelle Anwendung bevorzugen, können Sie Postman verwenden, um das Gleiche zu tun.

Sie können den Dienst jederzeit beenden, indem Sie Ctrl-C. Sie müssen dies tun und jedes Mal neu kompilieren und ausführen, wenn Sie Ihren Quellcode ändern und Ihren Dienst testen wollen.

Jetzt haben Sie hoffentlich eine Anwendung, die eingehende Nexmo Voice Anrufe verarbeiten kann. Jetzt ist es an der Zeit, eine Nexmo-Telefonnummer mit Ihrer Anwendung zu verbinden.

Verbinden Sie Nexmo mit Ihrem Dienst

Erinnern Sie sich an die Anforderungen im obigen Abschnitt, wo ich sagte, dass Sie Ngrok installiert haben müssen? Glücklicherweise hat mein Kollege Aaron eine großartige Anleitung zur Verwendung von Ngrok & Nexmo geschrieben. Sie sollten ihn lesen! Sie können Ngrok zum Laufen bringen, indem Sie eine Konsolen-Registerkarte öffnen (Sie müssen es zur gleichen Zeit wie Ihren Java-Dienst ausführen) und den folgenden Befehl ausführen:

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

Sie werden in der Ausgabe feststellen, dass es zwei Zeilen mit der Bezeichnung "Forwarding" gibt; eine hat eine HTTP-URL, die andere eine HTTPS-URL. Notieren Sie sich die HTTPS-URL - Sie werden sie in einer Minute brauchen. Ein weiterer wichtiger Punkt ist die Zeile "Webinterface". Ich empfehle Ihnen, diese URL jetzt in Ihrem Browser zu öffnen - denn Sie werden gleich überprüfen, ob Ngrok mit Ihrem Java IVR-Dienst verbunden ist.

Verwenden Sie curl (oder Postman) führen Sie eine ähnliche Anfrage wie oben aus, verwenden aber diesmal die Ngrok-URL, die Sie gerade erhalten haben, mit /inbound am Ende angehängt. Meine sieht so aus:

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

Sie sollten die gleiche Ausgabe wie zuvor sehen. Das bedeutet, dass Nexmo in der Lage ist, Ihren Dienst zu erreichen (während sowohl Ngrok und Ihr Dienst noch läuft).

Hoffentlich haben Sie einen Nexmo Account und das Nexmo CLI Tool eingerichtet. Wenn nicht, ist es jetzt an der Zeit! Wenn Sie bereit sind ...

Eine Nexmo-Nummer kaufen

Sie können die Anmietung einer Nexmo-Nummer starten, indem Sie den folgenden nexmo Befehl in Ihrer Kommandozeile ausführen:

nexmo number:buy --country_code US

Wenn Ihnen die gewählte Nummer gefällt, geben Sie "Bestätigen" ein und drücken die Eingabetaste. Wenn Sie es vorziehen, eine Nummer aus einer Liste auszuwählen, empfehle ich die Verwendung des Nexmo Dashboard. Notieren Sie sich die Nummer.

Erstellen einer Nexmo Voice Applikation

Nun müssen Sie eine Nexmo Voice Anwendung erstellen, die eine oder mehrere Nexmo Numbers mit einer Webhook-Konfiguration zusammenfasst. Denken Sie daran, den Ngrok-Hostnamen in den oben angegebenen Namen zu ändern!

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

Der obige Befehl richtet eine Nexmo-Anwendung ein, die weiß, wie sie Ihren Dienst anrufen kann, wenn ein eingehender Anruf empfangen wird. Sie haben auch den privaten Schlüssel in einer lokalen Datei gespeichert private.key. Sie werden ihn in diesem Tutorial nicht verwenden, aber er kann später nützlich sein, wenn Sie Ihrem Dienst weitere Funktionen hinzufügen.

Notieren Sie sich Ihre Anmelde-ID. Sie brauchen sie als nächstes.

Verknüpfen Sie Ihre Nexmo-Nummer

Führen Sie mit der Telefonnummer und der Anwendungs-ID, die Sie oben erhalten haben, den folgenden Befehl aus:

nexmo link:app NEXMO_NUMBER APPLICATION_ID

Testen Ihres Dienstes

Wenn Sie nun die Nexmo-Nummer von Ihrem Mobiltelefon aus anrufen, sollte Nexmo abheben und Sie sollten die Nachricht "Willkommen bei meinem Nexmo IVR" hören.

Wenn dies nicht funktioniert, überprüfen Sie die Ngrok-Konsole in Ihrem Browser unter http://localhost:4040/ und stellen Sie sicher, dass der Aufruf von Ngrok empfangen und erfolgreich an den Java-Dienst auf Ihrem Entwicklungsrechner weitergeleitet wurde.

Machen Sie daraus eine IVR

Ihre IVR ist noch nicht sehr nützlich! Ich zeige Ihnen, wie Sie es dem Benutzer ermöglichen, Eingaben über die Tastatur zu tätigen (dies wird DTMF genannt, was für Dual Tone Modulated Frequency steht, aber das ist nicht wirklich wichtig).

Bitte um Input

Gehen Sie zunächst zurück zu dem get Aufruf, den Sie geschrieben haben, und fügen Sie einen zweiten Parameter für den Ncco Konstruktoraufruf einen zweiten Parameter hinzu, so dass er wie folgt aussieht:

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();

Diese InputAction weist Nexmo an, 5 Sekunden lang zu warten, bis der Benutzer eine Ziffer auf der Tastatur eingibt. Wenn die Ziffer eingegeben wurde, ruft Nexmo Ihren Server unter /input mit den Details des DTMF-Codes, der vom Benutzer eingegeben wurde. Sie schreiben den Handler für /input in einem Moment schreiben.

Ich habe auch den TalkAction-Aufruf geändert, so dass wir den Wert bargeIn auf true setzen. Das bedeutet, dass ein Hörer, der es eilig hat, nicht warten muss, bis die Nachricht abgeschlossen ist, bevor er den DTMF-Code eingibt.

Ein weiterer wichtiger Punkt ist die pathToUrl Methode, die verwendet wird, um eine absolute URL zu Ihrem Dienst zu erzeugen. Dies ist eine 10-zeilige Utility-Methode, die ich geschrieben habe. Fügen Sie sie in Ihre App Klasse aus dem Code auf GitHub. Ich werde hier nicht erklären, wie sie funktioniert, denn darum geht es in diesem Tutorial eigentlich nicht!

Verarbeitung der Eingabe

Nun, da Sie Nexmo angewiesen haben, anzurufen /input anzurufen, wenn der Benutzer einen DTMF-Code eingibt, müssen Sie diesen Anruf behandeln. Geben Sie den folgenden Code in das Ende Ihrer main Methode ein:

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();
});

Der obige Code ähnelt sehr Ihrem bestehenden /inbound Handler, aber in diesem Fall parst er das empfangene JSON in ein InputEvent in der Anfrage und extrahiert den DTMF-Code daraus. Anschließend wird dem Benutzer eine Nachricht vorgelesen, die ihm den eingegebenen Code mitteilt.

Testen Sie Ihre Anwendung, indem Sie Ihre Nexmo-Nummer anrufen und nach Aufforderung einen Code auf der Tastatur eingeben!

Schlussfolgerung

Dies ist ein sehr einfaches Beispiel für die Reaktion auf einen DTMF-Code, aber Sie können es für Ihre Anwendung erweitern. Vielleicht könnten Sie einen Datensatz in einer Datenbank mit einer vom Benutzer eingegebenen ID nachschlagen, oder Sie könnten eine Telefonzentrale bauen, die an jemanden in Ihrer Organisation weiterleitet. Es gibt viele Möglichkeiten!

Weitere Informationen finden Sie in unserer preisgekrönten Dokumentation unter Nexmo Entwickler.

Wenn Sie einen größeren Spark-Dienst aufbauen, würde ich nicht empfehlen, Ihren gesamten Code in eine einzige main Methode zu packen! Glücklicherweise hat das Spark-Team einen Blog-Beitrag geschrieben, in dem Best Practices für größere Applications beschrieben werden.

Wenn Sie ein Feedback haben oder Hilfe zu diesem Tutorial wünschen, bin ich @judy2k auf Twitter - schicken Sie mir eine DM. Alternativ können Sie auch eine E-Mail an unser Developer Relations Team schicken unter devrel@nexmo.comoder treten Sie der Nexmo-Gemeinschaft Slack.

Teilen Sie:

https://a.storyblok.com/f/270183/150x150/a3d03a85fd/placeholder.svg
Mark SmithVonage Ehemalige

Mark war nominell für die Client-Bibliotheken von Nexmo verantwortlich (obwohl er nur die Python- und Java-Bibliotheken schreibt). Er war ursprünglich Java-Entwickler, ist seit 18 Jahren Python-Entwickler und beschäftigt sich zunehmend mit Go und Rust. Er liebt es, Programmiersprachen bis an ihre Grenzen zu treiben und diese Techniken dann anderen Programmierern beizubringen. Er trägt einen Wikingerhut, ist aber kein Wikinger, und aus Gründen, die er nicht näher erläutern möchte, ist er Judy2k auf Twitter.