Enregistrer un appel avec un son partagé

Un extrait de code qui montre comment répondre à un appel entrant et le configurer pour d'enregistrer séparément les segments de la conversation, puis de connecter l'appel. Lorsque l'appel est terminé, le eventUrl que vous spécifiez dans le record action du BCN recevront un webhook contenant l'URL de l'enregistrement à télécharger.

Exemple

Remplacez les variables suivantes dans le code de l'exemple :

CléDescription
VONAGE_VIRTUAL_NUMBER

Your Vonage Number. E.g. 447700900000

VOICE_TO_NUMBER

The recipient number to call, e.g. 447700900002.

Conditions préalables

npm install express body-parser

Rédiger le code

Ajouter ce qui suit à record-a-call-with-split-audio.js:

const Express = require('express');
const bodyParser = require('body-parser');

const app = new Express();
app.use(bodyParser.json());

const onInboundCall = (request, response) => {
  const ncco = [
    {
      action: 'record',
      split: 'conversation',
      channels: 2,
      eventUrl: [`${request.protocol}://${request.get('host')}/webhooks/recordings`],
    },
    {
      action: 'connect',
      from: VONAGE_VIRTUAL_NUMBER,
      endpoint: [
        {
          type: 'phone',
          number: VOICE_TO_NUMBER,
        },
      ],
    },
  ];
  response.json(ncco);
};

const onRecording = (request, response) => {
  const recording_url = request.body.recording_url;
  console.log(`Recording URL = ${recording_url}`);

  response.status(204).send();
};

app
  .get('/webhooks/answer', onInboundCall)
  .post('/webhooks/recordings', onRecording);

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});

Voir la source complète

Exécutez votre code

Enregistrez ce fichier sur votre machine et exécutez-le :

node record-a-call-with-split-audio.js

Conditions préalables

Ajouter ce qui suit à build.gradle:

implementation 'com.vonage:server-sdk-kotlin:2.1.1'
implementation 'io.ktor:ktor-server-netty'
implementation 'io.ktor:ktor-serialization-jackson'

Rédiger le code

Ajouter ce qui suit à la méthode main du fichier RecordCallSplitAudio:

embeddedServer(Netty, port = 8000) {
    routing {
        get("/webhooks/answer") {
            call.response.header("Content-Type", "application/json")
            call.respond(
                Ncco(
                    recordAction {
                        eventUrl(call.request.path().replace("answer", "recordings"))
                        channels(2)
                    },
                    connectToPstn(VOICE_TO_NUMBER) {
                        from(VONAGE_VIRTUAL_NUMBER)
                    }
                ).toJson()
            )
        }
        post("/webhooks/recordings") {
            val event = EventWebhook.fromJson(call.receive())
            println("Recording URL: ${event.recordingUrl}")
            call.respond(204)
        }
    }
}.start(wait = true)

Voir la source complète

Exécutez votre code

Nous pouvons utiliser le plugin application pour Gradle afin de simplifier l'exécution de notre application. Mettez à jour votre build.gradle avec ce qui suit :

apply plugin: 'application'
mainClassName = project.hasProperty('main') ? project.getProperty('main') : ''

Lancez la commande suivante gradle pour exécuter votre application, en remplaçant com.vonage.quickstart.kt.voice par le paquet contenant RecordCallSplitAudio:

gradle run -Pmain=com.vonage.quickstart.kt.voice.RecordCallSplitAudio

Conditions préalables

Ajouter ce qui suit à build.gradle:

implementation 'com.vonage:server-sdk:9.3.1'
implementation 'com.sparkjava:spark-core:2.9.4'

Rédiger le code

Ajouter ce qui suit à la méthode main du fichier RecordCallSplitAudio:

/*
 * Route to answer and connect incoming calls with recording.
 */
Route answerRoute = (req, res) -> {
    String recordingUrl = String.format("%s://%s/webhooks/recordings", req.scheme(), req.host());

    RecordAction record = RecordAction.builder()
            .eventUrl(recordingUrl)
            .channels(2)
            .build();

    ConnectAction connect = ConnectAction.builder(PhoneEndpoint.builder(VOICE_TO_NUMBER).build())
            .from(VONAGE_VIRTUAL_NUMBER).build();

    res.type("application/json");

    return new Ncco(record, connect);
};

/*
 * Route which prints out the recording URL it is given to stdout.
 */
Route recordingRoute = (req, res) -> {
    System.out.println(EventWebhook.fromJson(req.body()).getRecordingUrl());

    res.status(204);
    return "";
};

Spark.port(3000);
Spark.get("/webhooks/answer", answerRoute);
Spark.post("/webhooks/recordings", recordingRoute);

Voir la source complète

Exécutez votre code

Nous pouvons utiliser le plugin application pour Gradle afin de simplifier l'exécution de notre application. Mettez à jour votre build.gradle avec ce qui suit :

apply plugin: 'application'
mainClassName = project.hasProperty('main') ? project.getProperty('main') : ''

Lancez la commande suivante gradle pour exécuter votre application, en remplaçant com.vonage.quickstart.voice par le paquet contenant RecordCallSplitAudio:

gradle run -Pmain=com.vonage.quickstart.voice.RecordCallSplitAudio

Conditions préalables

Install-Package Vonage

Rédiger le code

Ajouter ce qui suit à SplitAudioController.cs:

[HttpGet("webhooks/answer")]
public IActionResult Answer()
{
    var VOICE_TO_NUMBER = Environment.GetEnvironmentVariable("VOICE_TO_NUMBER") ?? "VOICE_TO_NUMBER";
    var VONAGE_VIRTUAL_NUMBER = Environment.GetEnvironmentVariable("VONAGE_VIRTUAL_NUMBER") ?? "VONAGE_VIRTUAL_NUMBER";
    var host = Request.Host.ToString();
    //Uncomment the next line if using ngrok with --host-header option
    //host = Request.Headers["X-Original-Host"];

    var eventUrl = $"{Request.Scheme}://{host}/SplitAudio/webhooks/recording";
    var talkAction = new TalkAction {Text = "recording call", BargeIn = false};
    var recordAction = new RecordAction
    {
        EventUrl = new[] {eventUrl},
        EventMethod = "POST",
        Channels = 2,
        Split = "conversation"
    };

    var connectAction = new ConnectAction()
    {
        From = VONAGE_VIRTUAL_NUMBER,
        Endpoint = new[] {new PhoneEndpoint {Number = VOICE_TO_NUMBER}},
    };

    var ncco = new Ncco(talkAction, recordAction, connectAction);
    return Ok(ncco.ToString());
}

[HttpPost("webhooks/recording")]
public async Task<IActionResult> Recording()
{
    var record = await WebhookParser.ParseWebhookAsync<Record>(Request.Body, Request.ContentType);
    Console.WriteLine($"Record event received on webhook - URL: {record?.RecordingUrl}");
    return StatusCode(204);
}

Voir la source complète

Conditions préalables

composer require slim/slim:^3.8 vonage/client

Rédiger le code

Ajouter ce qui suit à index.php:

require 'vendor/autoload.php';

$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load();

define('TO_NUMBER', getenv('TO_NUMBER'));
define('VONAGE_NUMBER', getenv('VONAGE_NUMBER'));

$app = new \Slim\App();

$app->get('/webhooks/answer', function (Request $request, Response $response) {
    //Get our public URL for this route
    $uri = $request->getUri();
    $url = $uri->getScheme() . '://'.$uri->getHost() . ($uri->getPort() ? ':'.$uri->getPort() : '') . '/webhooks/recording';

    $record = new \Vonage\Voice\NCCO\Action\Record();
    $record->setEventWebhook(new \Vonage\Voice\Webhook($url));
    $record->setChannels(2);

    $connect = new \Vonage\Voice\NCCO\Action\Connect(new \Vonage\Voice\Endpoint\Phone(TO_NUMBER));
    $connect->setFrom(VONAGE_NUMBER);

    $ncco = new \Vonage\Voice\NCCO\NCCO();
    $ncco->addAction($connect);
    $ncco->addAction($record);

    return new JsonResponse($ncco);
});

$app->post('/webhooks/recording', function (Request $request, Response $response) {
    /** @var \Vonage\Voice\Webhook\Record */
    $recording = \Vonage\Voice\Webhook\Factory::createFromRequest($request);
    error_log($recording->getRecordingUrl());

    return $response->withStatus(204);
});

$app->run();

Voir la source complète

Exécutez votre code

Enregistrez ce fichier sur votre machine et exécutez-le :

php index.php

Conditions préalables

pip install vonage python-dotenv fastapi[standard]

Rédiger le code

Ajouter ce qui suit à record-a-call-with-split-audio.py:

import os
from os.path import dirname, join
from pprint import pprint

from dotenv import load_dotenv
from fastapi import Body, FastAPI
from vonage_voice import Connect, NccoAction, PhoneEndpoint, Record

dotenv_path = join(dirname(__file__), '../.env')
load_dotenv(dotenv_path)

VONAGE_VIRTUAL_NUMBER = os.environ.get('VONAGE_VIRTUAL_NUMBER')
VOICE_TO_NUMBER = os.environ.get('VOICE_TO_NUMBER')

app = FastAPI()


@app.get('/webhooks/answer')
async def inbound_call():
    ncco: list[NccoAction] = [
        Record(
            split='conversation',
            channels=2,
            eventUrl=['https://demo.ngrok.io/webhooks/recordings'],
        ),
        Connect(
            from_=VONAGE_VIRTUAL_NUMBER, endpoint=[PhoneEndpoint(number=VOICE_TO_NUMBER)]
        ),
    ]

    return [step.model_dump(by_alias=True, exclude_none=True) for step in ncco]


@app.post('/webhooks/recordings')
async def recordings(data: dict = Body(...)):
    pprint(data)
    return {'message': 'webhook received'}

Voir la source complète

Exécutez votre code

Enregistrez ce fichier sur votre machine et exécutez-le :

fastapi dev voice/record-a-call-with-split-audio.py

Conditions préalables

gem install sinatra sinatra-contrib

Rédiger le code

Ajouter ce qui suit à record-a-call-with-split-audio.rb:

require 'dotenv/load'
require 'sinatra'
require 'sinatra/multi_route'
require 'json'

VOICE_TO_NUMBER = ENV['VOICE_TO_NUMBER']
VONAGE_VIRTUAL_NUMBER = ENV['VONAGE_VIRTUAL_NUMBER']

before do
  content_type :json
end

helpers do
  def parsed_body
    JSON.parse(request.body.read)
  end
end

route :get, :post, '/webhooks/answer' do
  [
    {
      "action": "record",
      "split": "conversation",
      "channels": 2,
      "eventUrl": ["#{request.base_url}/webhooks/recordings"]
    },
    {
      "action": "connect",
      "from": VONAGE_VIRTUAL_NUMBER,
      "endpoint": [
        {
          "type": "phone",
          "number": VOICE_TO_NUMBER
        }
      ]
    }
  ].to_json
end

route :get, :post, '/webhooks/recordings' do
  recording_url = params['recording_url'] || parsed_body['recording_url']
  puts "Recording URL = #{recording_url}"

  halt 204
end

set :port, 3000

Voir la source complète

Exécutez votre code

Enregistrez ce fichier sur votre machine et exécutez-le :

ruby record-a-call-with-split-audio.rb

Essayez-le

Vous devrez :

  1. Répondez et enregistrez l'appel avec un son partagé (cet extrait de code).
  2. Télécharger l'enregistrement. Voir l'enregistrement Télécharger un enregistrement pour savoir comment procéder.