https://d226lax1qjow5r.cloudfront.net/blog/blogposts/boosting-voice-calls-with-vonage-api-human-machine-detection-and-flask/human-machine-detection.png

Verstärkung von Voice-Anrufen mit Vonage-API, Mensch/Maschine-Erkennung und Flask

Zuletzt aktualisiert am December 7, 2023

Lesedauer: 12 Minuten

Einführung

In bestimmten Geschäftsszenarien besteht die Notwendigkeit, eine sprachbasierte Kommunikation mit Kunden aufzubauen, wobei der Zeitdruck zu einem kritischen Faktor bei der effizienten Übermittlung von Sprachnachrichten wird, vor allem, wenn nur begrenzte Arbeitskräfte zur Verfügung stehen. Wenn ein Agent einen Anruf durch das Wählen einer Telefonnummer initiiert, muss er sich in Geduld üben, bis der Anruf von der Gegenstelle entgegengenommen wird, bei der es sich um einen Menschen oder ein Voicemail-System handeln kann. Diese Interaktionen verbrauchen wertvolle Zeit und Ressourcen.

Durch die Nutzung der Vonage Voice API und ihrer erweiterten Funktionen, die die Erkennung von Menschen, Voicemails und Pieptönen umfassen, ist die Automatisierung des gesamten Kommunikationsprozesses mit minimaler Code-Implementierung möglich. Darüber hinaus garantiert die ausgefeilte Maschinenerkennung die vollständige Zustellung der beabsichtigten Nachricht. Das folgende Tutorial führt Sie in die Automatisierung von Sprachanrufen ein, einschließlich der Erkennung von Menschen und Voicemail. Den Quellcode für diese Anwendung finden Sie auf Github.

1. Voraussetzungen

Für die Nutzung der Vonage Voice API sind bestimmte Voraussetzungen zu erfüllen. Dazu gehören das Erstellen eines Vonage Developer Accounts, das Beziehen einer virtuellen Nummer, das Einrichten einer Python-Umgebung zusammen mit der Flask-Anwendung und der ngrok Ingress-Anwendung. In den folgenden Abschnitten werden diese Voraussetzungen im Detail beschrieben.

Erstellen eines Vonage Developer Accounts

Vonage ist ein führender Kommunikationsanbieter, der Entwicklern Zugang zu APIs für den Versand von Voice, Video und Nachrichten bietet. Unter Anmeldung für einen kostenlosen Accounthaben Sie Zugang zu kostenlosem Guthaben und unkomplizierter Dokumentation zur Nutzung der Vonage-APIs. Sobald Sie den API-Schlüssel und das Geheimnis erhalten haben, folgen Sie der Dokumentation, um eine Sprachanwendung mit Dashboard zu erstellen zu erstellen und eine JWT zu erstellen, das in den nächsten Schritten benötigt wird. Weitere Informationen zur JWT-Generierung finden Sie hier.

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.

Erhalten Sie eine virtuelle Rufnummer

Sobald die Anmeldung abgeschlossen ist, erhalten Sie eine virtuelle Rufnummer von der Vonage-Website. In einigen Ländern sind Telefonnummern erforderlich, um einen Anruf zu tätigen, und die Anrufer-ID "Unbekannt" ist nicht zulässig, um einen Anruf zu tätigen. Daher ist es sehr empfehlenswert, sich eine virtuelle Telefonnummer zu einem geringen Preis zu besorgen.

Flask Server und ngrok Ingress Anwendung einrichten

Ein Webserver, der mit einem veröffentlichten Endpunkt kommunizieren kann, ist erforderlich, um Ereignisse aus dem Anrufverlauf zu empfangen und anschließend Aktionspunkte auszugeben. Flask ist ein Webanwendungs-Framework mit geringem Platzbedarf, das Python zur Erstellung webbasierter Anwendungen verwendet. Richten Sie den Flask-Server in Ihrer Umgebung ein, indem Sie die offiziellen Dokumentation.

Um auf eine lokal ausgeführte Flask-Anwendung zuzugreifen, benötigen Sie eine öffentliche URL, die über das Internet zugänglich ist. Hier ist die minimale Anleitung, um zu überprüfen, ob Python auf Ihrem Rechner installiert ist und Flask einzurichten:

python --version pip install Flask flask --version

Sie können ngrok verwenden verwenden, um den Webserver auf Ihrem lokalen Rechner zu hosten und Anfragen aus dem Web zu senden/empfangen. Es wird empfohlen, dass die neueste Version von ngrok installiert ist. Hier finden Sie eine minimale Anleitung, um ngrok auf Ihrem Mac einzurichten und seine Version zu überprüfen:

brew install ngrok/ngrok/ngrok ngrok version

Um den Anfang zu machen, hier der minimale Python-Code, um den Flask-Server zu starten und einen "Hello World"-Gruß zu senden:

from flask import Flask, request

app = Flask(__name__)

@app.route("/", methods=["GET", "POST"])
def callback_listener():
    print(f"event received --> {request.data}")
    return ("Hello world!", 200)

Speichern Sie den obigen Code in callback.py und führen Sie ihn mit dem folgenden Befehl aus:

flask --app callback run --host=0.0.0.0 --debug

Sie können nun Ihren Browser auf die öffentliche IP-Adresse oder die ngrok-Ingress-URL richten, um zu sehen, ob die Anwendung über das Internet erreichbar und bereit für den nächsten Schritt ist.

2. Voice-Anrufe tätigen und Ereignisse verfolgen

Nun, da Sie die Voraussetzungen erfüllt haben, ist es an der Zeit, den ersten Voice-Anruf zu tätigen und den Verlauf dieses Anrufs zu verfolgen. Es gibt mehrere Möglichkeiten, einen Anruf zu tätigen, z. B. mit dem SDK in Node.js, Python oder .NET. Der einfachste Weg ist die Verwendung des Befehls curl, den wir hier demonstrieren werden.

Das Beispiel ist entnommen aus hier entnommen und für 'action: talk' angepasst. Um einen Anruf zu tätigen, können Sie entweder den Befehl curl verwenden oder Postman mit der Option import einsetzen:

curl --location 'https://api-us.vonage.com/v1/calls' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "to": [ { "type": "phone", "number": "" } ], "from": { "type": "phone", "number": "" }, "event_url": [""], "ncco": [ { "action": "talk", "text": "This is a test call." } ] }'

Ersetzen Sie das Folgende durch:

  • YOUR_JWT = JWT, das im vorherigen Schritt erzeugt wurde

  • YOUR_MOBILE_NUMBER = Mobilfunknummer, die den Voice-Anruf entgegennimmt

  • YOUR_VIRTUAL_NUMBER = Virtuelle Nummer, die im vorherigen Schritt ermittelt wurde

  • YOUR_CALLBACK_URL = ngrok ingress URL oder öffentliche IP-Adresse der Flask-Server-Anwendung

Wenn Sie sich die Protokolle der Flask-Anwendung ansehen, können Sie die Details des Anrufverlaufs vom Beginn bis zum Klingeln sehen.

event received --> b'{"headers":{},"from":"YOUR_VIRTUAL_NUMBER","to":"YOUR_MOBILE_NUMBER","uuid":"2dd98ea6-2518-4e54-8f3a-a8c532f131d6","conversation_uuid":"CON-51982b08-5337-480f-be09-81c3cda3f885","status":"started","direction":"outbound","timestamp":"2023-10-20T13:57:42.895Z"}'
event received --> b'{"headers":{},"from":"YOUR_VIRTUAL_NUMBER","to":"YOUR_MOBILE_NUMBER","uuid":"2dd98ea6-2518-4e54-8f3a-a8c532f131d6","conversation_uuid":"CON-51982b08-5337-480f-be09-81c3cda3f885","status":"ringing","direction":"outbound","timestamp":"2023-10-20T13:57:42.895Z"}'
event received --> b'{"start_time":null,"headers":{},"rate":null,"from":"YOUR_VIRTUAL_NUMBER","to":"YOUR_MOBILE_NUMBER","uuid":"2dd98ea6-2518-4e54-8f3a-a8c532f131d6","conversation_uuid":"CON-51982b08-5337-480f-be09-81c3cda3f885","status":"answered","direction":"outbound","network":null,"timestamp":"2023-10-20T13:57:47.191Z"}'
event received --> b'{"headers":{},"end_time":"2023-10-20T13:57:50.000Z","uuid":"2dd98ea6-2518-4e54-8f3a-a8c532f131d6","network":"23410","duration":"3","start_time":"2023-10-20T13:57:47.000Z","rate":"0.10000000","price":"0.00500000","from":"YOUR_VIRTUAL_NUMBER","to":"YOUR_MOBILE_NUMBER","conversation_uuid":"CON-51982b08-5337-480f-be09-81c3cda3f885","status":"completed","direction":"outbound","timestamp":"2023-10-20T13:57:49.611Z"}'

Herzlichen Glückwunsch zu Ihrem ersten automatischen Voice-Anruf. Wenn Sie keinen Anruf tätigen können, kann es viele Gründe dafür geben, dass ein Anruf auf Ihrem Mobiltelefon nicht ankommt. Es könnte daran liegen, dass der Benutzer nicht authentifiziert wurde, dass die JWT nicht richtig geprägt wurde oder dass das Feld "von" nicht korrekt gesetzt wurde. Sie können Probleme mit Anrufen immer anhand der Daten aus der Antwort des Befehls und des Voice Inspektor Werkzeug.

3. Hinzufügen der Erkennung von Menschen/Mikrofonen zum Anruf

Nun, da Sie einen Anruf tätigen können, ist es an der Zeit, erweiterte Funktionen hinzuzufügen, um zu erkennen, wer am anderen Ende des Anrufs ist. Es gibt mehrere mögliche Szenarien für die Entgegennahme des Anrufs:

  1. Ein Mensch

  2. Ansage auf der Mailbox

  3. Eine Voicemail-Ansage gefolgt von einem Piepton

Mit der Funktion zur Erkennung von Menschen und Sprachnachrichten kann jeder Fall spezifisch behandelt werden, um die Nachricht bei Sprachanrufen richtig zuzustellen.

Um die Menschen-/Stimmerkennung hinzuzufügen, aktualisieren Sie den curl-Befehl mit der Option "advanced_machine_detection" (Einzelheiten zu diesem Parameter finden Sie hier):

curl --location 'https://api-us.vonage.com/v1/calls' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "to": [ { "type": "phone", "number": "" } ], "from": { "type": "phone", "number": "" }, "advanced_machine_detection": { "behavior": "continue", "beep_timeout": "45" }, "event_url": ["YOUR_CALLBACK_UR"], "ncco": [ { "action": "talk", "text": "This is a test call." } ] }'

Wenn Sie den Anruf entgegennehmen und "Hallo" sagen, wird die Stimme als menschliche Stimme interpretiert, und ein Ereignis "Status: Mensch" wird erzeugt und im Callback des Anrufverlaufs gesendet, das Sie in den Protokollen der Flask-Server-Anwendung sehen können:

event received --> b'{"call_uuid":"47f22bfd-ddb3-4a02-88be-9cb9673e0ae9","from":"<YOUR_VIRTUAL_NUMBER>","to":"<YOUR_MOBILE_NUMBER>","status":"human","conversation_uuid":"CON-d8ae51d1-6b93-426d-bbd0-2b1c059036ca","timestamp":"2023-10-20T14:34:43.014Z"}'

Voicemail-Ansagen werden als "Status: Anrufbeantworter" interpretiert, und wenn nach der Voicemail ein Piepton erkannt wird, wird im Rückruf ein zusätzlicher Parameter "sub_state: beep_start" gesendet. Alle diese Ereignisse lassen sich wie folgt zusammenfassen:

  1. Wenn der Anruf von einer Person entgegengenommen wird -> "status": "human"

  2. Wenn der Anruf an eine Voicemail geht, die keinen Piepton hat, dann -> "status": "machine" und dann "sub_state": "beep_timeout", wenn die Zeitüberschreitung des Signaltons auftritt

  3. Wenn der Anruf mit einem Signalton an die Voicemail geht -> zuerst "status": "machine" und dann "sub_state": "beep_start" wenn der Signalton erkannt wird

Die Signaltonerkennung ist eine hilfreiche Funktion, da sie Sie genau darüber informiert, wann die Aufzeichnung der Voicemail beginnt. Bei der Signaltonerkennung wird die in der Aufzeichnung verbleibende Nachricht abgeschnitten und ist beim Abspielen durch die zuhörende Person möglicherweise unklar, da der Teil der Nachricht vor dem Signalton fehlt.

4. Änderung des Anrufverlaufs auf der Grundlage der Erkennung von Mensch und Voicemail

Nutzen Sie die Möglichkeiten der Voicemail-Erkennung, um den Verlauf des Anrufs zu ändern. Nehmen wir als einfaches Szenario an, dass Sie bestimmte Nachrichten entsprechend der Erkennung von Mensch und Voicemail abspielen möchten. Zum Beispiel:

  1. Abspielen einer Meldung "Ich spreche mit einem Menschen", wenn eine Person erkannt wird

  2. Abspielen der Nachricht "Ich spreche mit Voicemail vor dem Piepton", wenn Voicemail erkannt wird

  3. Abspielen einer Nachricht "Ich spreche nach dem Piepton mit der Mailbox", wenn der Piepton erkannt wird

Beachten Sie, dass Sie die Ergebnisse der Voicemail-Erkennung bereits in der Anrufweiterleitung über Callbacks erhalten; es geht nur darum, die Informationen zu verarbeiten und die Entscheidungslogik in Ihren Flask-Code einzufügen. Hier ist der aktualisierte Flask-Code, der in der Lage ist, die Voicemail-Erkennung zu verarbeiten und die erwartete Antwort zu erzeugen:

from flask import Flask, request

app = Flask(__name__)

play_to_human = "I am talking to human."
play_to_voicemail = "I am talking to voicemail before the beep."
play_after_beep = "I am talking to voicemail after the beep."

@app.route("/", methods=["GET", "POST"])
def callback_listener():
    ncco, message_to_play = "", ""
    if request.is_json and "status" in request.get_json():
        req_json = request.get_json()
        print(f'status received --> {req_json["status"]}')
        if req_json["status"] == "machine" and "sub_state" not in req_json:
            message_to_play = play_to_voicemail
        elif req_json["status"] == "machine" and "sub_state" in req_json:
            message_to_play = play_after_beep
        elif req_json["status"] == "human":
            message_to_play = play_to_human
        ncco = [{ "action": "talk", "text": message_to_play, "loop": 3 }] if message_to_play != "" else ""
        print(f'response to send --> {ncco}')
    else:
        print(f'event received --> {request.data}')
    return (ncco if ncco != "" else "", 200)

Führen Sie den Aufruf erneut mit dem Befehl curl und der Option advanced_machine_detection durch:

curl --location 'https://api-us.vonage.com/v1/calls' \
--header 'Authorization: Bearer <YOUR_JWT>' \
--header 'Content-Type: application/json' \
--data '{
    "to": [ { "type": "phone", "number": "<YOUR_MOBILE_NUMBER>" } ],
    "from": { "type": "phone", "number": "<YOUR_VIRTUAL_NUMBER>" },
    "advanced_machine_detection": { "behavior": "continue", "beep_timeout": "45" },
    "event_url": ["YOUR_CALLBACK_UR"], 
    "ncco": [
        { "action": "talk",
        "text": "This is a test call." }
    ]
}'

Im obigen Beispiel wird der Anruf mit einer einfachen Gesprächsaktion gestartet:

{ "action": "talk", "text": "This is a test call." }

Im weiteren Verlauf des Gesprächs wird die Gesprächsaktion durch eine andere Gesprächsaktion ersetzt, je nachdem, ob ein Mensch oder eine Voicemail erkannt wurde, z. B:

In case if call is picked up by human (i.e. status: human):
{ "action": "talk", 
"text": "I am talking to human.", 
"loop": 3 }

In case if call goes to voicemail before the beep is detected (i.e status: machine):
{ "action": "talk", 
"text": "I am talking to voicemail before the beep.", 
"loop": 3 }

In case if call goes to voicemail and beep is detected (i.e. status:machine and sub_state: beep_start):
{ "action": "talk", 
"text": "I am talking to voicemail after the beep.", 
"loop": 3 }

5. Abschluss mit Beispielen aus der Praxis

Lassen Sie uns nun diese erweiterten Voice-Calling-Funktionen anhand eines realen Szenarios anwenden. Stellen Sie sich vor, Sie führen eine Sprachanruf-Kampagne durch und sind nur daran interessiert, Anrufe mit einer echten Person entgegenzunehmen. Wenn also eine Person den Anruf annimmt, wird sie mit Ihrer Telefonnummer verbunden. Andernfalls hinterlassen Sie eine Nachricht nach dem Signalton, wenn der Anruf auf der Mailbox landet. Um den Anwendungsfall zusammenzufassen:

  1. Verbinden Sie das Telefon des Wahlkämpfers, um mit der Person zu sprechen, die das Telefon bedient

  2. Andernfalls hinterlassen Sie nach dem Piepton eine Nachricht auf dem Anrufbeantworter: "Wir haben versucht, Sie zu erreichen; bitte kontaktieren Sie uns umgehend."

Hier ist der aktualisierte Flask-Code, der in der Lage sein wird, die Voicemail-Erkennung zu verarbeiten und die erwartete Antwort zu erzeugen:

from flask import Flask, request

app = Flask(__name__)

action_when_human = { "action": "connect", "from": "<YOUR_VIRTUAL_NUMBER>", "endpoint": [{ "type": "phone", "number": "<CALL_CAMPAIGNER_PHONE_NUMBER>" }] }
action_when_beep = { "action": "talk", "text": "We tried to reach you, please contact us immediately."}

@app.route("/", methods=["GET", "POST"])
def callback_listener():
    ncco = ""
    if request.is_json and "status" in request.get_json():
        req_json = request.get_json()
        if req_json["status"] == "machine" and "sub_state" in req_json and req_json["sub_state"] == "beep_start":
            ncco = [action_when_beep]
            print(f'status received --> {req_json["status"]}:{req_json["sub_state"]}')
            print(f'response to send --> {ncco}')
        elif req_json["status"] == "human":
            ncco = [action_when_human]
            print(f'status received --> {req_json["status"]}')
            print(f'response to send --> {ncco}')
    else:
        print(f'event received --> {request.data}')
    return (ncco if ncco != "" else "", 200)

Ersetzen Sie in dem Code IHRE_VIRTUELLE_NUMMER durch eine virtuelle Nummer, die Sie zuvor erhalten haben, und CALL_CAMPAIGNER_PHONE_NUMBER durch eine Nummer, mit der Sie verbunden werden möchten, wenn eine Person einen Anruf annimmt.

Testen wir den Code, indem wir einen Aufruf mit dem Befehl curl tätigen:

curl --location 'https://api-us.vonage.com/v1/calls' \
--header 'Authorization: Bearer <YOUR_JWT>' \
--header 'Content-Type: application/json' \
--data '{
    "to": [ { "type": "phone", "number": "<YOUR_MOBILE_NUMBER>" } ],
    "from": { "type": "phone", "number": "<YOUR_VIRTUAL_NUMBER>" },
    "advanced_machine_detection": { "behavior": "continue", "beep_timeout": "45" },
    "event_url": ["YOUR_CALLBACK_UR"], 
    "ncco": [
        { "action": "talk",
        "text": "Please wait while we connect you to an agent." }
    ]
}'

6. Schlussfolgerung

Indem Sie die Schritte in diesem Tutorial befolgt haben, haben Sie erfolgreich eine erweiterte Sprachanruf-Funktion erstellt, die erkennt, ob ein Mensch, eine Voicemail oder ein Anrufbeantworter den Anruf mit einem Piepton annimmt. Gleichzeitig haben Sie die Flask-Anwendung verwendet, um dynamisch über den Ablauf des Anrufs zu entscheiden. Mit diesen einfachen Codeschnipseln können Sie schnell Anrufkampagnen durchführen, Massenanrufe tätigen und Sprachnachrichten korrekt und ohne menschliche Interaktion versenden. Den Quellcode für diese Anwendung finden Sie wiederum auf Github.

Zusätzliche Concepts und Dokumentation zur Machine Detection API finden Sie unter Erweiterte maschinelle Erkennung.

Haben Sie Fragen oder Anregungen zu diesem Tutorial? Teilen Sie Ihre Gedanken mit uns auf Twitter oder unserem Vonage Community Slack-Kanal und zitieren Sie diesen Artikel, um eine schnelle Antwort zu erhalten. Sie können sich auch mit mir auf Twitter. Viel Glück und viel Spaß beim Kodieren!

Teilen Sie:

https://a.storyblok.com/f/270183/400x400/620f535ce9/atique-khan.jpg
Atique Khan

Atique is a computer graduate and proficient Python developer with a passion for exploring new technologies. With a strong background in programming and system engineering, he holds over 10 years of experience in automation, testing, and integration. His interests span single-board computers, software-defined radios, and continuous experimentation with generative AI tools.