Transcription des appels téléphoniques avec Twilio Media Streams, Java, WebSockets et Spring Boot
Temps de lecture: 6 minutes
WebSockets est une technologie Web utilisée pour créer des connexions bidirectionnelles de longue durée entre un client et un serveur Web sur Internet. Avec Twilio Media Streams, vous pouvez diffuser le son en temps réel d'un appel téléphonique vers votre application Web à l'aide de WebSockets.
Ce blog post vous montrera comment créer un serveur WebSocket en Java à l'aide de Spring Boot qui recevra le son en temps réel d'un appel téléphonique et transmettra les données audio à la fonction de synthèse vocale de Google pour fournir une transcription en direct des voix de l'appel.
Configuration requise
Pour suivre cette procédure, vous devez disposer des éléments suivants :
Si vous voulez passer directement à la fin, vous pouvez consulter le projet terminé sur GitHub.
Mise en route
Le moyen le plus rapide de créer un nouveau projet avec Spring Boot est d'utiliser Spring Initializr. Laissez les entrées Project (Projet), Language (Langage) et la version Spring Boot à leurs valeurs par défaut. Pour Group (Groupe) et Artifact (Artefact) dans les métadonnées du projet, vous êtes libre de choisir, tant que vous suivez les conventions de dénomination Maven. Dans l'exemple de code, j'ai utilisé lol.gilliard
comme groupe et websockets-transcription
pour l'artefact.
En bas de la page, ajoutez la dépendance WebSocket, puis cliquez sur le bouton « Generate » (Générer) pour générer et télécharger le projet. Il sera téléchargé sous forme de fichier zip que vous pourrez décompresser et importer dans votre IDE préféré.
Création du serveur Websocket
Spring sera en mesure de gérer la création de la connexion WebSocket, ce qui nous laissera le travail de gestion des données. Les données sont envoyées par WebSockets sous forme de petits blocs appelés « Messages ».
Spring attend de nous que nous écrivions un code capable de traiter ces messages. La manière la plus simple de le faire est d'étendre l'élément AbstractWebSocketHandler
de Spring.
Création du gestionnaire WebSocket
Le projet que vous avez téléchargé à partir de Spring Initializr a une classe unique dans un sous-répertoire sous src/main/Java
appelé <nom_votre_artefact>Application.java
et, dans le même package, vous devez créer une nouvelle classe appelée TwilioMediaStreamsHandler
, avec le code suivant :
Voir le code complet sur GitHub
Lorsqu'un nouveau client WebSocket se connecte, la méthode afterConnectionEstablished
est appelée. Ensuite, la méthode handleTextMessage
est appelée à plusieurs reprises, chaque fois qu'il y a un message. Lorsque la connexion est fermée, la méthode afterConnectionClosed
est appelée.
Notez que l'élément WebSocketSession
est transmis à toutes ces méthodes, ce qui permet à l'application de suivre simultanément plusieurs connexions WebSocket.
La prise en charge WebSocket de Spring peut gérer les messages binaires et les messages texte à l'aide de méthodes distinctes. Twilio Media Streams fournit les données audio encodées en JSON, c'est pourquoi il est seulement nécessaire de remplacer l'élément handleTextMessage
. La première itération de ce code imprime la taille de chaque message dans System.out
pour vérifier que les messages sont reçus, ce qui est fait dans le corps de la méthode handleTextMessage
:
Configuration de Spring pour utiliser notre gestionnaire
Une connexion WebSocket est établie par le client qui envoie une requête HTTP régulière. Le serveur informe le client que ce point de terminaison attend des données WebSocket avec une liaison qui commence par une réponse HTTP 101 Switching Protocols. Le client le confirme et commence à envoyer des messages. En procédant à une légère configuration, Spring peut gérer tout cela pour nous.
Dans le même package contenant vos classes existantes, créez une nouvelle classe appelée WebSocketConfig
. Cette classe configure Spring pour s'assurer que les requêtes vers un chemin particulier (dans notre cas /messages
) seront traitées par notre code WebSocketHandler
ci-dessus.
Cela ne se compile pas tel quel, car pour l'implémentation de WebSocketConfigurer
, nous devons implémenter une méthode appelée registerWebSocketHandlers
:
Voir le code complet sur GitHub
Diffusion d'un appel téléphonique
Cela suffit pour gérer les clients WebSocket ; nous devons maintenant configurer quelque chose pour envoyer des données à notre point de terminaison WebSocket. Entrez dans Twilio Media Streams.
Twilio 101
Vous pouvez acheter un numéro de téléphone Twilio et configurer ce qui se passe quand quelqu'un l'appelle en créant un webhook qui répond avec un langage de configuration que nous aimons appeler TwiML.
L'application Spring Boot servira ce TwiML et prendra en charge les connexions WebSocket. Utilisez la bibliothèque Twilio Java Helper, en ajoutant ce qui suit à la section <dependencies>
de pom.xml
, à côté de la dépendance spring-boot-starter-websocket
:
Ensuite, créez une classe appelée TwiMLController
dans le même package que vos autres classes qui servira l'élément TwiML :
Voir le code complet sur GitHub
L'élément TwiML créé ici comporte 3 parties :
- Say : un message de bienvenue
- Start the Media Stream : en utilisant le même nom d'hôte que la requête TwiML et un chemin d'accès
/messages
- Pause : pause de 30 secondes pour donner à l'appelant le temps de parler. Au bout de 30 secondes, l'appel est terminé, mais l'appelant peut bien sûr raccrocher avant s'il le souhaite.
Configuration de Twilio pour utiliser l'application
Pour que Twilio puisse appeler votre application, elle doit être disponible sur une URL accessible au public. La configuration actuelle de l'application fait qu'elle écoutera uniquement sur localhost
, qui est probablement (espérons-le !) non accessible depuis Internet. Il existe plusieurs options pour l'hébergement public, comme AWS,DigitalOcean ou Azure, mais à nos fins il est plus simple d'utiliser ngrok
. Ngrok est un outil gratuit qui, une fois installé, peut créer un tunnel temporaire à partir d'une URL publique vers votre localhost
.
Démarrez l'exécution de votre application en utilisant cette commande dans un terminal ou via votre IDE :
Ensuite, démarrez ngrok avec
Vous verrez une URL publique dans la sortie de ngrok, différente de celle ci-dessous, mais également composée de lettres et de chiffres aléatoires :
Vous pouvez la tester en chargeant https://<VOTRE_SOUSDOMAINE_NGROK>.ngrok.io/twiml dans votre navigateur. Vous verrez alors une réponse du type :
Configuration d'un numéro de téléphone Twilio
L'achat et la configuration d'un numéro de téléphone avec Twilio ne prennent que quelques minutes. Si vous n'avez pas encore de compte Twilio, un compte d'essai gratuit fonctionnera parfaitement pour cette application.
Achat d'un numéro de téléphone
Sur la page des numéros de téléphone de votre console, vous pouvez acheter des numéros de centaines de pays :
Choisissez une option locale, en vous assurant que vous sélectionnez la fonction Voice :
Après avoir acheté le numéro, vous verrez l'écran de configuration du numéro de téléphone. Utilisez l'URL ngrok comme ci-dessus (n'oubliez pas le /twiml
à la fin), et comme nous avons utilisé l'annotation @GetMapping
dans le code, redéfinissez la méthode sur HTTP GET
:
Enregistrez cette configuration et vous êtes prêt à appeler le numéro.
Appelez votre nouveau numéro de téléphone. Vous entendez la lecture du message <Say> par un robot, puis Media Stream démarre et la console affiche quelque chose de similaire à ceci pendant que vous parlez :
Félicitations, vous avez un serveur WebSocket opérationnel avec Spring Boot, recevant des données audio en direct d'un appel téléphonique vers votre numéro Twilio.
Vous pouvez faire beaucoup de choses avec le flux audio. La partie suivante de cet article présentera un exemple : le transfert des données au service de synthèse vocale de Google pour la transcription en direct.
Diffusion de données vers le service de transcription de Google
Le service de synthèse vocale de Google peut accepter des données en streaming, ce qui en fait un outil idéal pour notre projet. Pour l'utiliser, vous devez configurer un projet et télécharger vos identifiants dans un fichier dont l'emplacement est stocké dans la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS
. C'est gratuit, mais vous avez besoin d'une carte de crédit pour créer le compte. Vous pouvez suivre les instructions de Google pour faire tout cela. Je vais prendre une tasse de thé et attendre votre retour.
Maintenant que vous avez configuré votre projet Google, nous pouvons continuer.
Vous devez ajouter une nouvelle classe pour extraire les données des messages WebSocket de Twilio et les envoyer à Google dans le bon format. Sur la base de l'exemple de code de Google, j'ai créé une classe qui peut être copiée à partir du repo sur GitHub et utilisée directement. N'oubliez pas que le nom de votre package sera probablement différent selon ce que vous avez choisi pour le groupe et l'artefact au début. Votre IDE devrait vous aider ici.
Vous devez ajouter quelques dépendances supplémentaires dans votre pom.xml
(à côté de l'emplacement où vous avez ajouté la dépendance sur la bibliothèque Twilio Helper) :
Enfin, il vous faut changer le code dans TwilioMediaStreamsHandler
pour utiliser GoogleTextToSpeechService
:
À la ligne 13, une Map
de WebSocketSession
à GoogleTextToSpeechService
est créée, de sorte qu'il est possible de prendre en charge plusieurs appels entrants simultanément sans induire Google en confusion en mélangeant tous les flux audio. Ensuite, à la ligne 26, la charge utile de chaque message entrant est envoyée à GoogleTextToSpeechService
, qui est configuré pour imprimer la transcription chaque fois que Google l'envoie.
S'agissant de ngrok, il devrait toujours être en cours d'exécution. Si ce n'est pas le cas, redémarrez-le avec ngrok http 8080
. Redémarrez le serveur avec ./mvnw
spring-boot:run
et appelez à nouveau votre numéro.
Après le message vocal, vous pouvez parler et vous verrez quelque chose comme ceci dans votre console :
N'est-ce pas merveilleux ce que vous pouvez réaliser avec quelques classes et des services cloud puissants ?
La prochaine étape ?
Une myriade de possibilités s'offre à vous : vous pouvez diffuser le texte à un service de traduction, l'enregistrer dans un fichier, vous faire la main sur l'analyse des sentiments ou choisir des mots-clés qui peuvent déclencher un message texte de suivi après l'appel. Je suis impatient de savoir ce que vous allez faire avec Java, WebSockets et Twilio Media Streams. Faites-le moi savoir dans les commentaires ci-dessous ou retrouvez-moi en ligne :
Twitter : @MaximumGilliard
E-mail : mgilliard@twilio.com
Articles associés
Ressources connexes
Twilio Docs
Des API aux SDK en passant par les exemples d'applications
Documentation de référence sur l'API, SDK, bibliothèques d'assistance, démarrages rapides et didacticiels pour votre langage et votre plateforme.
Centre de ressources
Les derniers ebooks, rapports de l'industrie et webinaires
Apprenez des experts en engagement client pour améliorer votre propre communication.
Ahoy
Le hub de la communauté des développeurs de Twilio
Meilleures pratiques, exemples de code et inspiration pour créer des expériences de communication et d'engagement numérique.