https://a.storyblok.com/f/270183/1368x665/68e78d6262/25mar_dev_blog_php-stream-audio-2.jpg

Wiedergabe einer Audiodatei in einem Voice-Anruf mit PHP

Zuletzt aktualisiert am June 18, 2025

Lesedauer: 9 Minuten

Jedes Mal, wenn ich anrufe mein örtliches Freizeitzentrum anrufe, um einen Schwimmkurs zu buchen, werde ich mit einer Ankündigung der neuesten Nachrichten begrüßt: Das Zentrum ist am kommenden Montag für zwei Stunden geschlossen, der Zeitplan für das Familienschwimmen hat sich geändert, usw. In diesem Artikel zeige ich Ihnen ein Beispiel dafür, wie sie dies mit Voice API von Vonage und einem PHP-Backend, das mit dem Slim-Framework geschrieben wurde, um Audio in ein laufendes Telefongespräch zu spielen.

Voraussetzungen

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.

Erstens brauchen wir eine neue Slim-Anwendung. Ich werde diese so einfach wie möglich gestalten - keine großen Boilerplates, kein automatisches Templating. Wir werden einen Endpunkt haben, der einen ausgehenden Anruf auslöst, und einen eingehenden Endpunkt, um den Webhook zu lesen, der erzeugt wird, wenn der Endbenutzer einen Anruf entgegennimmt.

Erstellen Sie ein Verzeichnis, das unseren Code enthält, und verwenden Sie Composer, um ein neues Projekt zu erstellen:

composer init

Sie können alle interaktiven Fragen überspringen, indem Sie die Eingabetaste drücken, wodurch die Standardeinstellungen verwendet werden. Wenn Sie gefragt werden, ob Sie interaktiv Pakete hinzufügen möchten, müssen Sie dies ablehnen, damit ich in diesem Artikel die Befehle zum Einziehen des Frameworks zeigen kann.

Der Composer erzeugt seine Konfigurationsdatei composer.json, und einen Abhängigkeitsordner, vendor. Mit den Standardeinstellungen wird auch das Verzeichnis erstellt, in dem Ihr Code gespeichert werden soll, src.

In der Befehlszeile müssen wir das Slim-Framework und eine PSR-7-Schnittstelle für die Anfrage-/Antwort-Klassen. Mit dem letzten Befehl wird das Vonage PHP SDKein, das die API-Anfragen für Sie erledigt. Schließlich ist unser Vonage-Client mit Umgebungsvariablen konfiguriert, so dass wir die De-facto-Bibliothek benötigen, um dies zu handhaben.

composer require slim/slim
composer require slim/psr7
composer require vonage/client
composer require vlucas/phpdotenv

Nun, da wir Slim und unsere anderen erforderlichen Abhängigkeiten haben, können wir mit dem Schreiben der Anwendung beginnen. Das Vonage PHP SDK erfordert eine Anwendungs-ID und einen privaten Schlüssel, die Sie beide erhalten, wenn Sie eine neue Anwendungsinstanz im Vonage Dashboard erstellen. Alternativ können Sie dies auch über die Vonage CLIdurchführen, was wir hier tun werden.

Installieren und Konfigurieren der Vonage CLI

Installieren Sie die Vonage CLI global mit dem folgenden Befehl:

npm install @vonage/cli -g

dann, konfigurieren Sie die CLI mit Ihrem Vonage API-Schlüssel und -Geheimnis, die Sie im Developer Dashboard finden:

Vonage auth set –api-key=’VONAGE_API_KEY –api-secret=’VONAGE_API_SECRET’

Ersetzen Sie die VONAGE_API_KEY und VONAGE_API_SECRET durch Ihre Angaben, um die CLI zu authentifizieren.

Öffnen Sie Ihre API-Einstellungen-Seite um auf Ihren Vonage API-Schlüssel und Ihr API-Geheimnis zuzugreifen, die beide wie im Screenshot unten dargestellt angezeigt werden. Der API-Schlüssel befindet sich oben auf der Seite, und um auf Ihr API-Geheimnis zuzugreifen, lesen Sie bitte den Unterabschnitt "Account secret".

Hinweis: Falls Sie sich nicht an Ihr zuvor erstelltes API-Geheimnis erinnern können, klicken Sie auf "+ Neues Geheimnis erstellen" und speichern Sie es sicher.

Sie können Ihre Authentifizierung mit dem folgenden Befehl überprüfen, um sicherzustellen, dass alles funktioniert:

vonage auth check

Wenn Sie die CLI nicht global, sondern in Ihrem lokalen Projekt installiert haben, können Sie ein zusätzliches Flag zur Überprüfung hinzufügen:

Vonage auth check --local

Um eine virtuelle Rufnummer zu kaufen, gehen Sie zu Ihrem API-Dashboard und befolgen Sie die unten aufgeführten Schritte.

Steps on how to purchase a phone number from the dashboard, from selecting the number and confirming the selection.Purchase a phone number

  1. Gehen Sie zu Ihrem API-Dashboard

  2. Navigieren Sie zu BUILD & MANAGE > Numbers > Buy Numbers.

  3. Wählen Sie die gewünschten Attribute und klicken Sie dann auf Suchen

  4. Klicken Sie auf die Schaltfläche Kaufen neben der gewünschten Nummer und bestätigen Sie Ihren Kauf.

  5. Um zu bestätigen, dass Sie die virtuelle Nummer erworben haben, gehen Sie im linken Navigationsmenü unter BUILD & MANAGE auf Numbers und dann auf Your Numbers

Erstellen der Voice-Applikation

Um die Voice API zu verwenden, müssen Sie eine Voice API Anwendung. Dies ist nicht dasselbe wie die Webanwendung, die Sie erstellen. Es handelt sich lediglich um einen Container für die Konfigurations- und Sicherheitsinformationen, die Sie für die Verbindung mit den APIs von Vonage benötigen.

vonage apps create "Play audio app" --private-key-file=~/private.key

Sie erhalten folgende Daten (Beispiel, Dummy) zum Notieren:

Name: play audio app

Anwendung ID: 7a319bf9-49e7-413d-914b-402fe8e68XXX

Verbesserung der KI: Aus

Privater/öffentlicher Schlüssel: Einstellen

Sie werden feststellen, dass wir dem Befehl das folgende Argument gegeben haben private-key-file. Dadurch wird Ihr privater Schlüssel für Sie heruntergeladen, sobald der Befehl ausgeführt wurde: Suchen Sie diese Schlüsseldatei (im Befehl habe ich das UNIX-ähnliche ~/ locationverwendet, was der Home-Ordner ist; Sie sollten ihn auf etwas wie C:\Users\YOUR-USER-NAME wenn Sie Powershell unter Windows verwenden) und legen Sie die Datei im Stammverzeichnis Ihres Projekts ab.

Wir haben die Anwendung noch nicht so eingestellt, dass sie die Voice API verwendet. Führen Sie daher den folgenden Befehl aus, um die Voice-Funktion hinzuzufügen:

vonage apps capabilities update [VONAGE_APPLICATION_ID] --voice-answer-url=https://example.com/answer --voice-event-url=https://example.com/event-status

Sie werden feststellen, dass wir die voice-answer-url und die voice-event-url hier auf der Anwendungsebene setzen. Dies sind vorerst Platzhalter, und Sie brauchen diese Werte nicht zu ändern. Der Grund hierfür ist, dass der Code, der für den Aufruf verwendet wird, diese Werte während der HTTP-Aufrufe dynamisch erstellt.

Denn Sie sollten niemals Geheimnisse in Ihre Codebasis aufnehmensollten, erstellen Sie eine neue Datei im Stammverzeichnis Ihres Projekts mit dem Namen .env. Füllen Sie die Variablen mit den entsprechenden Informationen, wobei die TO_NUMBER ist die Nummer, die das Wählgerät anruft. Wir werden auf die BASE_URL später. Die VONAGE_PRIVATE_KEY_PATH kann so belassen werden wie im Beispiel unten, und die VONAGE_NUMBER sollte eine gekaufte virtuelle Vonage-Nummer sein, die im Dashboard erworben wurde.

Im Verzeichnis src Verzeichnis eine neue Datei an, index.php, und fügen Sie den folgenden Code hinzu:

<?php

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use Vonage\Client\Credentials\Keypair;
use Vonage\Voice\Endpoint\Phone;
use Vonage\Voice\OutboundCall;
use Vonage\Voice\Webhook;

require DIR . '/../vendor/autoload.php';

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
$dotenv->load();

$app = AppFactory::create();

$app->get('/dial', function (Request $request, Response $response, array $args) {
   $privateKeyPath = realpath(__DIR__ . '/../' . $_ENV['VONAGE_APPLICATION_PRIVATE_KEY_PATH']);
   $credentials = new Keypair(
       file_get_contents($privateKeyPath),
       $_ENV['VONAGE_APPLICATION_ID']
   );

   $client = new \Vonage\Client($credentials);

   $call = new OutboundCall(
       new Phone($_ENV['TO_NUMBER']),
       new Phone($_ENV['VONAGE_NUMBER'])
   );

   $call
       ->setAnswerWebhook(
           new Webhook($_ENV['BASE_URL'] . '/webhooks/answer', 'POST')
       )
       ->setEventWebhook(
           new Webhook($_ENV['BASE_URL'] . '/webhooks/event', 'POST')
       )
   ;

   $client->voice()->createOutboundCall($call);
   $response->getBody()->write('Outbound Call Started');
   return $response;
});

$app->post('/webhooks/answer', function (Request $request, Response $response, array $args) {
   $builder = new Vonage\Voice\NCCO\NCCO();
   $builder->addAction(new \Vonage\Voice\NCCO\Action\Talk('Here is some soothing music for you'));
   $builder->addAction(new \Vonage\Voice\NCCO\Action\Stream($_ENV['BASE_URL'] . '/music.mp3'));

   $response->getBody()->write(json_encode($builder->jsonSerialize()));

   return $response->withHeader('Content-Type', 'application/json');

});

$app->post('/webhooks/event', function (Request $request, Response $response, array $args) {
   var_dump($request->getParsedBody());
});

$app->run();

Hier gibt es eine Menge zu tun, also schlüsseln wir das mal auf.

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
$dotenv->load();

Dieser Code lädt den Inhalt der Datei .env Datei in die PHP-Superglobale $_ENV Array, um unseren Vonage Client einzurichten. $app = AppFactory::create() erstellt eine neue Slim-Anwendungsinstanz, damit wir unsere Endpunkte einrichten können.

Unser Outbound-Dialer ist als HTTP-GET-Route definiert, /dial. Der nachstehende Code wird also ausgeführt, wenn diese Route aufgerufen wird. Hier richten wir den Vonage-Client mit unseren Anmeldedaten ein, auf die wir über das $_ENV Objekt:

$privateKeyPath = realpath(__DIR__ . '/../' . $_ENV['VONAGE_APPLICATION_PRIVATE_KEY_PATH']);
$credentials = new Keypair(
   file_get_contents($privateKeyPath),
   $_ENV['VONAGE_APPLICATION_ID']
);

$client = new \Vonage\Client($credentials);

Es gibt mehrere Möglichkeiten, Anmeldedaten in Vonage auf verschiedene Weise zu verwenden. Das Wichtigste ist jedoch, dass das Keypair Objekt den String der privaten Schlüsseldatei Ihrer Vonage-Anwendung und die Anwendungs-ID enthält. Die praktische Funktion des PHP SDK besteht darin, dass Ihr JWT zur Laufzeit automatisch erstellt und dem Header hinzugefügt wird. Dies ist wichtig für die Anwendung, denn während Sie können Während Sie bei einigen Vonage-APIs die einfache Authentifizierung verwenden können, funktioniert die eingehende Webhook-Konfiguration aus Sicherheitsgründen nur mit einem JWT.

Es ist möglich, eine Vonage-Anwendung im Dashboard so zu konfigurieren, dass immer dieselbe Antwort-URL und dieselbe Ereignis-URL für laufende Anwendungsaktualisierungen verwendet werden. Wie Sie jedoch aus dem verwendeten Code ersehen können, können Sie diese Webhook-Endpunkte auch dynamisch festlegen. Dies wäre nützlich, wenn Sie Instanzen mehrerer verschiedener Workflows haben und den Fortschritt einzelner Anrufe verfolgen wollen. Sie können zum Beispiel eine Datenbanktabelle hinzufügen, die dann CRUD-ähnliche Operationen mit einer UUID im URL-Pfad durchführen kann. Dies gibt Ihnen die Flexibilität, mehrere Abfragen auf einmal zu bearbeiten, wenn Sie etwas wie Route Model Binding mit Laravel Octane. Unser Slim-Code ist zur besseren Lesbarkeit etwas einfacher:

$call = new OutboundCall(
   new Phone($_ENV['TO_NUMBER']),
   new Phone($_ENV['VONAGE_NUMBER'])
);

$call
   ->setAnswerWebhook(
       new Webhook($_ENV['BASE_URL'] . '/webhooks/answer', 'POST')
   )
   ->setEventWebhook(
       new Webhook($_ENV['BASE_URL'] . '/webhooks/event', 'POST')
   );

$client->voice()->createOutboundCall($call);

$response->getBody()->write('Outbound Call Started');

return $response;

Der Webhook-Pfad wird mit Hilfe der Umgebungsvariablen BASE_URL. Da wir nun den Pfad für ausgehende Anrufe haben, müssen wir definieren, was diese BASE_URL ist.

Sie müssen die Anwendung zunächst lokal bereitstellen. Um die Sache so einfach wie möglich zu gestalten, verwenden wir den in PHP integrierten Server. Navigieren Sie zum Verzeichnis src Verzeichnis und starten Sie ihn dann:

php -S localhost:8080

Unsere Webhooks sind POST Anfragen, die direkt von Vonage kommen. Ohne unsere Anwendung dem Internet auszusetzen, gibt es also keine Möglichkeit, dass Vonage auf unsere Localhost-Anwendung zugreifen kann. Das gebräuchlichste Tool, um dies zu ermöglichen, ist Ngrokdas Sie hier finden Installationsanweisungen finden Sie hier. Wenn Sie es strikt auf PHP beschränken wollen, können Sie Expose von Beyond Codeverwenden, das die Leistungsfähigkeit einer Ereignisschleife nutzt, die von ReactPHP. Wichtig ist, dass Sie eines dieser Tools ausführen und sich die zurückgegebene URL notieren. Von dort aus fügen Sie sie in die BASE_URL in der .env Datei ein und schon kann es losgehen! Eine Möglichkeit, eingehende Daten zu konsumieren.

Unser letzter Teil des Ausführungscodes nimmt diese Daten, kündigt an, dass ein Ton kommt, und spielt dann den Ton ab.

$app->post('/webhooks/answer', function (Request $request, Response $response, array $args) {
   $builder = new Vonage\Voice\NCCO\NCCO();
   $builder->addAction(new \Vonage\Voice\NCCO\Action\Talk('Here is some soothing music for you'));
   $builder->addAction(new \Vonage\Voice\NCCO\Action\Stream($_ENV['BASE_URL'] . '/audio.mp3'));

   $response->getBody()->write(json_encode($builder->jsonSerialize()));

   return $response->withHeader('Content-Type', 'application/json');
});

Dieser Code besteht im Wesentlichen darin, ein JSON zu erstellen, das an Vonage gesendet wird, das dann die Anweisungen verarbeitet. Dazu werden eindeutige NCCO-Objekte von Vonage verwendet, und die gute Nachricht ist, dass das PHP SDK einen Builder hat, der dies einfach macht! Wir haben zwei Aktionen: Erstens, eine Sprechen Aktion, die ausgelöst wird, wenn der Anruf angenommen wird, und dann eine Stream Aktion für das Audio. Sie werden feststellen, dass es hier eine URL gibt, die die BASE_URL und dann eine Datei namens audio.mp3. Dies ist ein Platzhalter - damit es funktioniert, legen Sie eine beliebige Datei mit dem Namen audio.mp3 im Verzeichnis src ein, und diese Datei wird dann in den Anruf eingespielt. Vonage kann dies tun, weil die Audiodatei in demselben Verzeichnis liegt, das vom integrierten Webserver angezeigt wird.

Sie sind bereit: Navigieren Sie zu Ihrer URL für /Wahl und genießen Sie, was immer Sie für Ihre Audiodatei auswählen, sei es entspannender Elevator Jazz oder, wenn Sie Ihre Endnutzer nicht mögen, moderner Dubstep.

Schlussfolgerung

In diesem Beitrag haben Sie gelernt, wie man Audio in ein bestehendes Gespräch einspielt und wie man die NCCO Aktionen die den Gesprächsablauf steuern. Sie können gerne experimentieren, indem Sie verschiedene Audiodateien und NCCO Aktionen. Die folgenden Ressourcen können Ihnen dabei helfen:

Haben Sie eine Frage oder möchten Sie uns mitteilen, was Sie gerade bauen?

Bleiben Sie auf dem Laufenden und halten Sie sich über die neuesten Nachrichten, Tipps und Veranstaltungen für Entwickler auf dem Laufenden.

Teilen Sie:

https://a.storyblok.com/f/270183/400x385/12b3020c69/james-seconde.png
James SecondeSenior PHP Entwickler Advocate

Als ausgebildeter Schauspieler mit einer Dissertation in Standup-Comedy bin ich über die Meetup-Szene zur PHP-Entwicklung gekommen. Man findet mich, wenn ich über Technik spreche oder schreibe, oder wenn ich seltsame Platten aus meiner Vinylsammlung spiele oder kaufe.