Codieren von Twilio-WebHooks in Java mit Spring Boot

May 07, 2019
Autor:in:

Codieren von Twilio-WebHooks in Java mit Spring Boot


Hallo und Danke fürs Lesen! Dieser Blogpost ist eine Übersetzung von Coding Twilio Webhooks in Java with Spring Boot. Während wir unsere Übersetzungsprozesse verbessern, würden wir uns über Dein Feedback an help@twilio.com freuen, solltest Du etwas bemerken, was falsch übersetzt wurde. Wir bedanken uns für hilfreiche Beiträge mit Twilio Swag :)

Mit den APIs von Twilio lässt sich auf vielfältige Weise kommunizieren: über TelefonWhatsAppFacebookSMS und mehr.  Bei Ereignissen wie eingehenden Nachrichten oder Anrufen stellt Twilio normalerweise eine HTTP-Anfrage an einen vom Benutzer bereitgestellten Server, um herauszufinden, welche Aktion erwartet wird. Das sind die sogenannten WebHooks. HTTP-Server können zwar mit jeder Technologie geschrieben werden, um auf diese WebHooks zu antworten, aber das bevorzugte Framework für Java-Entwickler ist Spring Boot.

In diesem Blog erstellen wir eine Spring Boot-App, die auf eingehende Telefonanrufe mit einer kurzen Nachricht gefolgt von dem wunderbaren Lied „It Might As Well Be Spring“ von Rogers und Hammerstein antwortet.

Piano

Voraussetzungen

Erstellen einer Spring Boot-App

Spring hat den Spring Initializr entwickelt, mit dem schnell neue Projekte erstellt werden können. Wir rufen https://start.spring.io auf und richten folgendermaßen ein neues Projekt ein:

Spring Initializr

Wir verwenden entweder Maven oder Gradle, wählen geeignete Group- und Artifact-Namen aus und fügen im Feld Search dependencies to add die Web-Abhängigkeit hinzu. Wir klicken auf die Schaltfläche Generate Project und das Projekt wird als ZIP-Datei heruntergeladen. Diese kann entpackt und in eine IDE importiert werden.

Unter src/main/java befinden sich Ordner, die dem Artifact-Namen entsprechen, und eine einzelne Java-Klasse, in unserem Fall mit dem Namen PhoneCallWebhookApplication.java. Das ist die Hauptklasse für dieses Projekt. Sie ist mit @SpringBootApplication annotiert und verfügt über eine main-Methode. Die @SpringBootApplication-Annotation richtet viele nützlich Standardeinstellungen für Spring ein, darunter den eingebetteten HTTP-Server und das Komponenten-Scanning.

Wir erzeugen eine Klasse mit dem Namen WebhookController in demselben Paket wie die Anwendungsklasse. Dazu erstellen wir eine neue Datei mit dem Namen WebhookController.java in demselben Verzeichnis wie die PhoneCallWebhookApplication.java-Datei. Die Controller-Klasse enthält den Code für den WebHook. Eine @Controller-Annotation stellt sicher, dass sie auch vom Komponenten-Scanning von Spring gefunden wird. Spring registriert automatisch HTTP-Endpunkte für Methoden, die mit @GetMapping annotiert sind.

Für die erste Iteration sollte die WebhookController-Klasse so aussehen:

    // The package name may be different depending on
    // what the Group and Artifact of the project are
package lol.gilliard.phonecallwebhook;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class WebhookController {

    @GetMapping("/call")
    @ResponseBody
    public String respondToPhoneCall(){
         return "Welcome to Spring Boot";
    }
}

Dieser Code reicht aus, um einen funktionierenden Webserver zu erhalten. Bevor wir weitermachen, können wir ihn testen. Das Projekt enthält ein Wrapper-Skript für Maven oder Gradle, also erstellen wir es und führen es mit einem dieser beiden Befehle aus. Wenn wir das Skript zum ersten Mal ausführen, müssen wir möglicherweise einige Abhängigkeiten herunterladen. Eine gute Gelegenheit, unser Wissen darüber etwas aufzufrischen.

./mvnw clean package
java -jar target/phone-call-webhook-0.0.1-SNAPSHOT.jar

oder

./gradlew clean build
java -jar ./build/libs/phone-call-webhook-0.0.1-SNAPSHOT.jar

Sobald es ausgeführt wird, navigieren wir zu http://localhost:8080/call und wir sehen folgende Begrüßungsnachricht:

Screenshot: Welcome to spring boot

Antworten auf einen Twilio-WebHook

Die Antwort auf einen Twilio-WebHook sollte normalerweise eine Art XML sein, die wir TwiML nennen. Es ist zwar möglich, TwiML von Hand zu schreiben, aber für alles, was über die einfachsten Anwendungsfälle hinausgeht, empfehle ich die Java-Hilfebibliothek.  Wir fügen die Hilfebibliothek dem Projekt hinzu, indem wir sie in den <dependencies>-Abschnitt der pom.xml-Datei einfügen:

<dependencies>
    ...
    <dependency>
        <groupId>com.twilio.sdk</groupId>
        <artifactId>twilio</artifactId>
        <version>7.37.4</version>
    </dependency>
    ... 
</dependencies>

Wir ändern die WebhookController-Klasse folgendermaßen ab:

    // The package name may be different depending on
    // what the Group and Artifact of the project are
package lol.gilliard.phonecallwebhook;
    
import com.twilio.twiml.VoiceResponse;
import com.twilio.twiml.voice.Play;
import com.twilio.twiml.voice.Say;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.concurrent.atomic.AtomicInteger;

@Controller
public class WebhookController {

   private AtomicInteger callerNumber = new AtomicInteger();

   @GetMapping(path="/call", produces="application/xml")
   @ResponseBody
   public String respondToPhoneCall() {

       VoiceResponse.Builder voiceBuilder = new VoiceResponse.Builder();

       Say greeting = new Say.Builder("Hello caller number " + callerNumber.incrementAndGet()).build();
       Play music = new Play.Builder("https://static.gilliard.lol/Might_As_Well_Be_Spring.mp3").build();

       return voiceBuilder.say(greeting).play(music).build().toXml();
   }
}

Wir erstellen den Code und führen ihn erneut wie bereits zuvor mit Maven oder Gradle aus. Wenn wir jetzt http://localhost:8080/call aufrufen, sehen wir die TwiML, die die Hilfebibliothek erzeugt:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say>Hello caller number 1</Say>
    <Play>https://static.gilliard.lol/Might_As_Well_Be_Spring.mp3</Play>
</Response>

it&#x27;s working

Verwenden von ngrok zum Entwickeln von WebHooks

Damit Twilio auf den WebHook zugreifen kann, reicht localhost leider nicht aus. Der Dienst muss sich unter einer URL befinden, auf die über das Internet zugegriffen werden kann.  Zum Entwickeln von WebHooks ist ngrok ein hervorragendes Tool. Es stellt eine temporäre URL, auf die über das Internet zugegriffen werden kann, für die Entwicklungsumgebung bereit.Wir installieren das Tool und führen in einem neuen Terminal folgenden Befehl aus:

ngrok http 8080

ngrok erstellt öffentliche http- und https-URLs, die auf Localhost umleiten:

screenshot: ngrok

Ich würde immer HTTPS empfehlen. Deshalb verwenden wir statt „localhost“ die HTTPS-URL in der WebHook-Adresse.  Die Hostnamen von ngrok sind jedes Mal anders. Bevor wir fortfahren, kannst du deinen Hostnamen in einem Browser nachsehen.

Einrichten einer Twilio-Telefonnummer

Nach dem Anmelden am Twilio-Konto gehen wir zur Seite mit den Telefonnummern und kaufen eine neue Nummer in unserem Land. Dabei müssen wir darauf achten, dass wir das Kontrollkästchen „Voice“ aktivieren:

screenshot: twilio console

Nachdem wir eine Nummer ausgewählt haben, werden wir aufgefordert, auf die Seite zur Verwaltung von Telefonnummern zu gehen. Dort konfigurieren wir, wie Twilio auf eingehende Anrufe und Nachrichten reagieren soll.  Hier fügen wir die ngrok-URL als WebHook für eingehende Anrufe ein, und aufgrund der @GetMapping-Annotation wählen wir außerdem HTTP GET aus:

screenshot: webhook config

Wir speichern diese Konfiguration. Jetzt steht alles bereit.  Wenn wir jetzt unsere Twilio-Telefonnummer anrufen, können wir der wunderbaren Melodie lauschen.

Zusammenfassung: Wenn die Nummer angerufen wird, stellt Twilio eine Anfrage an die ngrok-URL, die über einen Tunnel mit der Spring Boot-App verbunden ist. Die App antwortet mit der TwiML, die in der Controller-Klasse erstellt wurde, und Twilio gibt die Begrüßung und das Lied wieder.  Und das alles in nur zehn Zeilen Code!

Success!

Ein permanenter Platz in der Cloud

Das Entwickeln von WebHooks mit ngrok funktioniert wunderbar, allerdings kann auf die URL nicht zugegriffen werden, wenn der Computer ausgeschaltet oder der ngrok-Befehl abgebrochen wird. Für eine zuverlässigere Lösung finden sich in der Spring-Dokumentation mehrere Empfehlungen zu Orten, an denen Anwendungen dauerhaft bereitgestellt werden können. Wir dürfen allerdings nicht vergessen, die URL auf der Seite für die Konfiguration von Telefonnummern zu aktualisieren.

Wie geht es weiter?

Wir haben in diesem Blog nur im Ansatz behandelt, welche Möglichkeiten Spring Boot bietet. Es gibt zahlreiche weitere Spring-Projekte zum Erstellen von komplexeren Apps, zum Verwenden von SQL- oder NoSQL-Datenspeichern, zum Bereitstellen in der Cloud und vieles mehr.  Und Twilio hat natürlich auch mehr zu bieten, als nur Musik über das Telefon abzuspielen.  Weitere Informationen findest du in der umfassenden Twilio-Dokumentation und in den Java-Schnellstarts. Oder für die Gamer unter uns empfehle ich Twilio Quest. Dort kannst du beim Spielen noch etwas lernen.

Ich würde gern erfahren, woran du gerade arbeitest. Kontaktiere mich auf Twitter oder per E-Mail: