Guida introduttiva: Effettuare una chiamata in uscita con Automazione chiamate

Servizi di comunicazione di Azure API di automazione delle chiamate sono un modo efficace per creare esperienze di chiamata interattive. In questa guida introduttiva viene illustrato un modo per effettuare una chiamata in uscita e riconoscere vari eventi nella chiamata.

Prerequisiti

Codice di esempio

Scaricare o clonare il codice di esempio di avvio rapido da GitHub.

Passare alla CallAutomation_OutboundCalling cartella e aprire la soluzione in un editor di codice.

Configurare e ospitare Azure DevTunnel

Azure DevTunnels è un servizio di Azure che consente di condividere servizi Web locali ospitati su Internet. Eseguire i comandi per connettere l'ambiente di sviluppo locale alla rete Internet pubblica. DevTunnels crea un URL dell'endpoint permanente che consente l'accesso anonimo. Questo endpoint viene usato per notificare all'applicazione gli eventi di chiamata dal servizio di automazione delle chiamate Servizi di comunicazione di Azure.

devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host

Aggiornare la configurazione dell'applicazione

Aggiornare quindi il Program.cs file con i valori seguenti:

  • acsConnectionString: stringa di connessione per la risorsa Servizi di comunicazione di Azure. È possibile trovare il Servizi di comunicazione di Azure stringa di connessione seguendo le istruzioni riportate qui.
  • callbackUriHost: dopo aver inizializzato l'host DevTunnel, aggiornare questo campo con tale URI.
  • acsPhonenumber: aggiornare questo campo con il numero di telefono Servizi di comunicazione di Azure acquisito. Questo numero di telefono deve usare il formato numero di telefono E164 (ad esempio +18881234567)
  • targetPhonenumber: aggiornare il campo con il numero di telefono che si desidera chiamare l'applicazione. Questo numero di telefono deve usare il formato numero di telefono E164 (ad esempio +18881234567)
  • cognitiveServiceEndpoint: campo di aggiornamento con l'endpoint di Servizi di intelligenza artificiale di Azure.
  • targetTeamsUserId: campo di aggiornamento (facoltativo) con l'ID utente di Microsoft Teams che si vuole aggiungere alla chiamata. Vedere Usare l'API Graph per ottenere l'ID utente di Teams.
// Your ACS resource connection string 
var acsConnectionString = "<ACS_CONNECTION_STRING>"; 

// Your ACS resource phone number will act as source number to start outbound call 
var acsPhonenumber = "<ACS_PHONE_NUMBER>"; 
 
// Target phone number you want to receive the call. 
var targetPhonenumber = "<TARGET_PHONE_NUMBER>";

// Base url of the app 
var callbackUriHost = "<CALLBACK_URI_HOST_WITH_PROTOCOL>"; 

// Your cognitive service endpoint 
var cognitiveServiceEndpoint = "<COGNITIVE_SERVICE_ENDPOINT>";

// (Optional) User Id of the target teams user you want to receive the call.
var targetTeamsUserId = "<TARGET_TEAMS_USER_ID>";

Effettuare una chiamata in uscita

Per effettuare la chiamata in uscita da Servizi di comunicazione di Azure, questo esempio usa l'oggetto targetPhonenumber definito in precedenza nell'applicazione per creare la chiamata usando l'APICreateCallAsync. Questo codice eseguirà una chiamata in uscita usando il numero di telefono di destinazione.

PhoneNumberIdentifier target = new PhoneNumberIdentifier(targetPhonenumber);
PhoneNumberIdentifier caller = new PhoneNumberIdentifier(acsPhonenumber);
var callbackUri = new Uri(callbackUriHost + "/api/callbacks");
CallInvite callInvite = new CallInvite(target, caller);
var createCallOptions = new CreateCallOptions(callInvite, callbackUri) {
  CallIntelligenceOptions = new CallIntelligenceOptions() {
    CognitiveServicesEndpoint = new Uri(cognitiveServiceEndpoint)
  }
};
CreateCallResult createCallResult = await callAutomationClient.CreateCallAsync(createCallOptions);

Gestire gli eventi di automazione delle chiamate

In precedenza nell'applicazione è stato registrato callbackUriHost nel servizio di automazione delle chiamate. L'host indica che l'endpoint richiesto dal servizio deve inviare una notifica agli eventi di chiamata che si verificano. È quindi possibile scorrere gli eventi e rilevare eventi specifici che l'applicazione vuole comprendere. Nel codice riportato di seguito viene risposto all'evento CallConnected .

app.MapPost("/api/callbacks", async (CloudEvent[] cloudEvents, ILogger < Program > logger) => {
  foreach(var cloudEvent in cloudEvents) {
    logger.LogInformation($"Event received: {JsonConvert.SerializeObject(cloudEvent)}");
    CallAutomationEventBase parsedEvent = CallAutomationEventParser.Parse(cloudEvent);
    logger.LogInformation($"{parsedEvent?.GetType().Name} parsedEvent received for call connection id: {parsedEvent?.CallConnectionId}");
    var callConnection = callAutomationClient.GetCallConnection(parsedEvent.CallConnectionId);
    var callMedia = callConnection.GetCallMedia();
    if (parsedEvent is CallConnected) {
      //Handle Call Connected Event
    }
  }
});

(Facoltativo) Aggiungere un utente di Microsoft Teams alla chiamata

È possibile aggiungere un utente di Microsoft Teams alla chiamata usando il AddParticipantAsync metodo con un MicrosoftTeamsUserIdentifier e l'ID dell'utente di Teams. Per abilitare la chiamata agli utenti di Microsoft Teams, è prima necessario completare il passaggio prerequisito Autorizzazione per la risorsa Servizi di comunicazione di Azure. Facoltativamente, è anche possibile passare un oggetto SourceDisplayName per controllare il testo visualizzato nella notifica di tipo avviso popup per l'utente di Teams.

await callConnection.AddParticipantAsync(
    new CallInvite(new MicrosoftTeamsUserIdentifier(targetTeamsUserId))
    {
        SourceDisplayName = "Jack (Contoso Tech Support)"
    });

Avviare la registrazione di una chiamata

Il servizio Di automazione delle chiamate consente anche di avviare la registrazione e archiviare le registrazioni delle chiamate vocali e video. Altre informazioni sulle varie funzionalità disponibili nelle API di registrazione delle chiamate sono disponibili qui.

CallLocator callLocator = new ServerCallLocator(parsedEvent.ServerCallId);
var recordingResult = await callAutomationClient.GetCallRecording().StartAsync(new StartRecordingOptions(callLocator));
recordingId = recordingResult.Value.RecordingId;

Riprodurre un messaggio di benvenuto e riconoscere

TextSourceUsando , è possibile fornire al servizio il testo che si vuole sintetizzare e usare per il messaggio di benvenuto. Il servizio di automazione delle chiamate Servizi di comunicazione di Azure riproduce questo messaggio all'eventoCallConnected.

Passare quindi il testo nell'oggetto CallMediaRecognizeChoiceOptions e quindi chiamare StartRecognizingAsync. Ciò consente all'applicazione di riconoscere l'opzione scelta dal chiamante.

if (parsedEvent is CallConnected callConnected) {
  logger.LogInformation($"Start Recording...");
  CallLocator callLocator = new ServerCallLocator(parsedEvent.ServerCallId);
  var recordingResult = await callAutomationClient.GetCallRecording().StartAsync(new StartRecordingOptions(callLocator));
  recordingId = recordingResult.Value.RecordingId;

  var choices = GetChoices();

  // prepare recognize tones 
  var recognizeOptions = GetMediaRecognizeChoiceOptions(mainMenu, targetPhonenumber, choices);

  // Send request to recognize tones 
  await callMedia.StartRecognizingAsync(recognizeOptions);
}

CallMediaRecognizeChoiceOptions GetMediaRecognizeChoiceOptions(string content, string targetParticipant, List < RecognitionChoice > choices, string context = "") {
  var playSource = new TextSource(content) {
    VoiceName = SpeechToTextVoice
  };

  var recognizeOptions = new CallMediaRecognizeChoiceOptions(targetParticipant: new PhoneNumberIdentifier(targetParticipant), choices) {
    InterruptCallMediaOperation = false,
      InterruptPrompt = false,
      InitialSilenceTimeout = TimeSpan.FromSeconds(10),
      Prompt = playSource,
      OperationContext = context
  };
  return recognizeOptions;
}

List < RecognitionChoice > GetChoices() {
  return new List < RecognitionChoice > {
    new RecognitionChoice("Confirm", new List < string > {
      "Confirm",
      "First",
      "One"
    }) {
      Tone = DtmfTone.One
    },
    new RecognitionChoice("Cancel", new List < string > {
      "Cancel",
      "Second",
      "Two"
    }) {
      Tone = DtmfTone.Two
    }
  };
}

Gestire gli eventi di scelta

Servizi di comunicazione di Azure Call Automation attiva l'oggetto api/callbacks sul webhook configurato e invia una notifica all'eventoRecognizeCompleted. L'evento consente di rispondere all'input ricevuto e attivare un'azione. L'applicazione riproduce quindi un messaggio al chiamante in base all'input specifico ricevuto.

if (parsedEvent is RecognizeCompleted recognizeCompleted) {
  var choiceResult = recognizeCompleted.RecognizeResult as ChoiceResult;
  var labelDetected = choiceResult?.Label;
  var phraseDetected = choiceResult?.RecognizedPhrase;

  // If choice is detected by phrase, choiceResult.RecognizedPhrase will have the phrase detected,  
  // If choice is detected using dtmf tone, phrase will be null  
  logger.LogInformation("Recognize completed succesfully, labelDetected={labelDetected}, phraseDetected={phraseDetected}", labelDetected, phraseDetected);

  var textToPlay = labelDetected.Equals(ConfirmChoiceLabel, StringComparison.OrdinalIgnoreCase) ? ConfirmedText : CancelText;

  await HandlePlayAsync(callMedia, textToPlay);
}

async Task HandlePlayAsync(CallMedia callConnectionMedia, string text) {
  // Play goodbye message 
  var GoodbyePlaySource = new TextSource(text) {
    VoiceName = "en-US-NancyNeural"
  };
  await callConnectionMedia.PlayToAllAsync(GoodbyePlaySource);
}

Blocco e arresto della registrazione

Infine, quando viene rilevata una condizione che ha senso per terminare la chiamata, è possibile usare il HangUpAsync metodo per appendere la chiamata.

if ((parsedEvent is PlayCompleted) || (parsedEvent is PlayFailed))
{
    logger.LogInformation($"Stop recording and terminating call.");
    callAutomationClient.GetCallRecording().Stop(recordingId);
    await callConnection.HangUpAsync(true);
}

Eseguire il codice

Per eseguire l'applicazione con VS Code, aprire una finestra del terminale ed eseguire il comando seguente

dotnet run

Prerequisiti

Codice di esempio

Scaricare o clonare il codice di esempio di avvio rapido da GitHub.

Passare alla CallAutomation_OutboundCalling cartella e aprire la soluzione in un editor di codice.

Configurare e ospitare Azure DevTunnel

Azure DevTunnels è un servizio di Azure che consente di condividere servizi Web locali ospitati su Internet. Eseguire i comandi devTunnel per connettere l'ambiente di sviluppo locale alla rete Internet pubblica. DevTunnels crea quindi un tunnel con un URL dell'endpoint permanente e che consente l'accesso anonimo. Servizi di comunicazione di Azure usa questo endpoint per notificare all'applicazione gli eventi di chiamata dal servizio di automazione delle chiamate Servizi di comunicazione di Azure.

devtunnel create --allow-anonymous
devtunnel port create -p MY_SPRINGAPP_PORT
devtunnel host

Aggiornare la configurazione dell'applicazione

Aprire quindi il application.yml file nella /resources cartella per configurare i valori seguenti:

  • connectionstring: stringa di connessione per la risorsa Servizi di comunicazione di Azure. È possibile trovare il Servizi di comunicazione di Azure stringa di connessione seguendo le istruzioni riportate qui.
  • basecallbackuri: dopo aver inizializzato l'host DevTunnel, aggiornare questo campo con tale URI.
  • callerphonenumber: aggiornare questo campo con il numero di telefono Servizi di comunicazione di Azure acquisito. Questo numero di telefono deve usare il formato numero di telefono E164 (ad esempio +18881234567)
  • targetphonenumber: aggiornare il campo con il numero di telefono che si desidera chiamare l'applicazione. Questo numero di telefono deve usare il formato numero di telefono E164 (ad esempio +18881234567)
  • cognitiveServiceEndpoint: campo di aggiornamento con l'endpoint di Servizi di intelligenza artificiale di Azure.
  • targetTeamsUserId: campo di aggiornamento (facoltativo) con l'ID utente di Microsoft Teams che si vuole aggiungere alla chiamata. Vedere Usare l'API Graph per ottenere l'ID utente di Teams.
acs:
  connectionstring: <YOUR ACS CONNECTION STRING> 
  basecallbackuri: <YOUR DEV TUNNEL ENDPOINT> 
  callerphonenumber: <YOUR ACS PHONE NUMBER ex. "+1425XXXAAAA"> 
  targetphonenumber: <YOUR TARGET PHONE NUMBER ex. "+1425XXXAAAA"> 
  cognitiveServiceEndpoint: <YOUR COGNITIVE SERVICE ENDPOINT>
  targetTeamsUserId: <(OPTIONAL) YOUR TARGET TEAMS USER ID ex. "ab01bc12-d457-4995-a27b-c405ecfe4870">

Effettuare una chiamata in uscita e riprodurre contenuti multimediali

Per effettuare la chiamata in uscita da Servizi di comunicazione di Azure, questo esempio usa l'oggetto targetphonenumber definito nel application.yml file per creare la chiamata usando l'APIcreateCallWithResponse.

PhoneNumberIdentifier caller = new PhoneNumberIdentifier(appConfig.getCallerphonenumber());
PhoneNumberIdentifier target = new PhoneNumberIdentifier(appConfig.getTargetphonenumber());
CallInvite callInvite = new CallInvite(target, caller);
CreateCallOptions createCallOptions = new CreateCallOptions(callInvite, appConfig.getCallBackUri());
CallIntelligenceOptions callIntelligenceOptions = new CallIntelligenceOptions().setCognitiveServicesEndpoint(appConfig.getCognitiveServiceEndpoint());
createCallOptions = createCallOptions.setCallIntelligenceOptions(callIntelligenceOptions);
Response<CreateCallResult> result = client.createCallWithResponse(createCallOptions, Context.NONE);

(Facoltativo) Aggiungere un utente di Microsoft Teams alla chiamata

È possibile aggiungere un utente di Microsoft Teams alla chiamata usando il addParticipant metodo con un MicrosoftTeamsUserIdentifier e l'ID dell'utente di Teams. Per abilitare la chiamata agli utenti di Microsoft Teams, è prima necessario completare il passaggio prerequisito Autorizzazione per la risorsa Servizi di comunicazione di Azure. Facoltativamente, è anche possibile passare un oggetto SourceDisplayName per controllare il testo visualizzato nella notifica di tipo avviso popup per l'utente di Teams.

client.getCallConnection(callConnectionId).addParticipant(
    new CallInvite(new MicrosoftTeamsUserIdentifier(targetTeamsUserId))
        .setSourceDisplayName("Jack (Contoso Tech Support)"));

Avviare la registrazione di una chiamata

Il servizio Di automazione delle chiamate consente anche di avviare la registrazione e archiviare le registrazioni delle chiamate vocali e video. Altre informazioni sulle varie funzionalità disponibili nelle API di registrazione delle chiamate sono disponibili qui.

ServerCallLocator serverCallLocator = new ServerCallLocator(
    client.getCallConnection(callConnectionId)
        .getCallProperties()
        .getServerCallId());
        
StartRecordingOptions startRecordingOptions = new StartRecordingOptions(serverCallLocator);

Response<RecordingStateResult> response = client.getCallRecording()
    .startWithResponse(startRecordingOptions, Context.NONE);

recordingId = response.getValue().getRecordingId();

Rispondere agli eventi di chiamata

In precedenza nell'applicazione è stato registrato basecallbackuri nel servizio di automazione delle chiamate. L'URI indica che l'endpoint che il servizio userà per notificare gli eventi di chiamata che si verificano. È quindi possibile scorrere gli eventi e rilevare eventi specifici che l'applicazione vuole comprendere. Nel codice riportato di seguito viene risposto all'evento CallConnected .

List<CallAutomationEventBase> events = CallAutomationEventParser.parseEvents(reqBody);
for (CallAutomationEventBase event : events) {
    String callConnectionId = event.getCallConnectionId();
    if (event instanceof CallConnected) {
        log.info("CallConnected event received");
    }
    else if (event instanceof RecognizeCompleted) {
        log.info("Recognize Completed event received");
    }
}

Riprodurre un messaggio di benvenuto e riconoscere

TextSourceUsando , è possibile fornire al servizio il testo che si vuole sintetizzare e usare per il messaggio di benvenuto. Il servizio di automazione delle chiamate Servizi di comunicazione di Azure riproduce questo messaggio all'eventoCallConnected.

Passare quindi il testo nell'oggetto CallMediaRecognizeChoiceOptions e quindi chiamare StartRecognizingAsync. Ciò consente all'applicazione di riconoscere l'opzione scelta dal chiamante.

var playSource = new TextSource().setText(content).setVoiceName("en-US-NancyNeural");

var recognizeOptions = new CallMediaRecognizeChoiceOptions(new PhoneNumberIdentifier(targetParticipant), getChoices())
  .setInterruptCallMediaOperation(false)
  .setInterruptPrompt(false)
  .setInitialSilenceTimeout(Duration.ofSeconds(10))
  .setPlayPrompt(playSource)
  .setOperationContext(context);

client.getCallConnection(callConnectionId)
  .getCallMedia()
  .startRecognizing(recognizeOptions);

private List < RecognitionChoice > getChoices() {
  var choices = Arrays.asList(
    new RecognitionChoice().setLabel(confirmLabel).setPhrases(Arrays.asList("Confirm", "First", "One")).setTone(DtmfTone.ONE),
    new RecognitionChoice().setLabel(cancelLabel).setPhrases(Arrays.asList("Cancel", "Second", "Two")).setTone(DtmfTone.TWO)
  );

  return choices;
}

Gestire gli eventi di scelta

Servizi di comunicazione di Azure Call Automation attiva l'oggetto api/callbacks sul webhook configurato e invia una notifica all'eventoRecognizeCompleted. L'evento consente di rispondere all'input ricevuto e attivare un'azione. L'applicazione riproduce quindi un messaggio al chiamante in base all'input specifico ricevuto.

else if (event instanceof RecognizeCompleted) {
  log.info("Recognize Completed event received");

  RecognizeCompleted acsEvent = (RecognizeCompleted) event;

  var choiceResult = (ChoiceResult) acsEvent.getRecognizeResult().get();

  String labelDetected = choiceResult.getLabel();

  String phraseDetected = choiceResult.getRecognizedPhrase();

  log.info("Recognition completed, labelDetected=" + labelDetected + ", phraseDetected=" + phraseDetected + ", context=" + event.getOperationContext());

  String textToPlay = labelDetected.equals(confirmLabel) ? confirmedText : cancelText;

  handlePlay(callConnectionId, textToPlay);
}

private void handlePlay(final String callConnectionId, String textToPlay) {
  var textPlay = new TextSource()
    .setText(textToPlay)
    .setVoiceName("en-US-NancyNeural");

  client.getCallConnection(callConnectionId)
    .getCallMedia()
    .playToAll(textPlay);
}

Riagganciare la chiamata

Infine, quando viene rilevata una condizione che ha senso per terminare la chiamata, è possibile usare il hangUp metodo per appendere la chiamata.

client.getCallConnection(callConnectionId).hangUp(true);

Eseguire il codice

Passare alla directory contenente il file pom.xml e usare i comandi mvn seguenti:

  • Compilare l'applicazione: mvn compile
  • Compilare il pacchetto: mvn package
  • Eseguire l'app: mvn exec:java

Prerequisiti

Codice di esempio

Scaricare o clonare il codice di esempio di avvio rapido da GitHub.

Passare alla CallAutomation_OutboundCalling cartella e aprire la soluzione in un editor di codice.

Configurare l'ambiente

Scaricare il codice di esempio e passare alla directory del progetto ed eseguire il npm comando che installa le dipendenze necessarie e configurare l'ambiente per sviluppatori.

npm install

Configurare e ospitare Azure DevTunnel

Azure DevTunnels è un servizio di Azure che consente di condividere servizi Web locali ospitati su Internet. Usare i comandi dell'interfaccia della riga di comando di DevTunnel per connettere l'ambiente di sviluppo locale a Internet pubblico. Questo endpoint viene usato per notificare all'applicazione gli eventi di chiamata dal servizio di automazione delle chiamate Servizi di comunicazione di Azure.

devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host

Aggiornare la configurazione dell'applicazione

Aggiornare quindi il .env file con i valori seguenti:

  • CONNECTION_STRING: stringa di connessione per la risorsa Servizi di comunicazione di Azure. È possibile trovare il Servizi di comunicazione di Azure stringa di connessione seguendo le istruzioni riportate qui.
  • CALLBACK_URI: dopo aver inizializzato l'host DevTunnel, aggiornare questo campo con tale URI.
  • TARGET_PHONE_NUMBER: aggiornare il campo con il numero di telefono che si desidera chiamare l'applicazione. Questo numero di telefono deve usare il formato numero di telefono E164 (ad esempio +18881234567)
  • ACS_RESOURCE_PHONE_NUMBER: aggiornare questo campo con il numero di telefono Servizi di comunicazione di Azure acquisito. Questo numero di telefono deve usare il formato numero di telefono E164 (ad esempio +18881234567)
  • COGNITIVE_SERVICES_ENDPOINT: campo di aggiornamento con l'endpoint di Servizi di intelligenza artificiale di Azure.
  • TARGET_TEAMS_USER_ID: campo di aggiornamento (facoltativo) con l'ID utente di Microsoft Teams che si vuole aggiungere alla chiamata. Vedere Usare l'API Graph per ottenere l'ID utente di Teams.
CONNECTION_STRING="<YOUR_CONNECTION_STRING>" 
ACS_RESOURCE_PHONE_NUMBER ="<YOUR_ACS_NUMBER>" 
TARGET_PHONE_NUMBER="<+1XXXXXXXXXX>" 
CALLBACK_URI="<VS_TUNNEL_URL>" 
COGNITIVE_SERVICES_ENDPOINT="<COGNITIVE_SERVICES_ENDPOINT>" 
TARGET_TEAMS_USER_ID="<TARGET_TEAMS_USER_ID>"

Effettuare una chiamata in uscita e riprodurre contenuti multimediali

Per effettuare la chiamata in uscita da Servizi di comunicazione di Azure, usare il numero di telefono fornito all'ambiente. Assicurarsi che il numero di telefono sia nel formato E164 (ad esempio +18881234567)

Il codice effettua una chiamata in uscita usando il target_phone_number specificato e inserisce una chiamata in uscita a tale numero:

const callInvite: CallInvite = {
	targetParticipant: callee,
	sourceCallIdNumber: {
		phoneNumber: process.env.ACS_RESOURCE_PHONE_NUMBER || "",
	},
};

const options: CreateCallOptions = {
	cognitiveServicesEndpoint: process.env.COGNITIVE_SERVICES_ENDPOINT
};

console.log("Placing outbound call...");
acsClient.createCall(callInvite, process.env.CALLBACK_URI + "/api/callbacks", options);

(Facoltativo) Aggiungere un utente di Microsoft Teams alla chiamata

È possibile aggiungere un utente di Microsoft Teams alla chiamata usando il addParticipant metodo con la microsoftTeamsUserId proprietà . Per abilitare la chiamata agli utenti di Microsoft Teams, è prima necessario completare il passaggio prerequisito Autorizzazione per la risorsa Servizi di comunicazione di Azure. Facoltativamente, è anche possibile passare un oggetto sourceDisplayName per controllare il testo visualizzato nella notifica di tipo avviso popup per l'utente di Teams.

await acsClient.getCallConnection(callConnectionId).addParticipant({
    targetParticipant: { microsoftTeamsUserId: process.env.TARGET_TEAMS_USER_ID },
    sourceDisplayName: "Jack (Contoso Tech Support)"
});

Avviare la registrazione di una chiamata

Il servizio Di automazione delle chiamate consente anche di avviare la registrazione e archiviare le registrazioni delle chiamate vocali e video. Altre informazioni sulle varie funzionalità disponibili nelle API di registrazione delle chiamate sono disponibili qui.

const callLocator: CallLocator = {
    id: serverCallId,
    kind: "serverCallLocator",
};

const recordingOptions: StartRecordingOptions = {
    callLocator: callLocator,
};

const response = await acsClient.getCallRecording().start(recordingOptions);

recordingId = response.recordingId;

Rispondere agli eventi di chiamata

In precedenza nell'applicazione è stato registrato CALLBACK_URI nel servizio di automazione delle chiamate. L'URI indica l'endpoint usato dal servizio per notificare gli eventi che si verificano. È quindi possibile scorrere gli eventi e rilevare eventi specifici che l'applicazione vuole comprendere. Rispondiamo all'evento CallConnected per ricevere una notifica e avviare le operazioni downstream. TextSourceUsando , è possibile fornire al servizio il testo che si vuole sintetizzare e usare per il messaggio di benvenuto. Il servizio di automazione delle chiamate Servizi di comunicazione di Azure riproduce questo messaggio all'eventoCallConnected.

Passare quindi il testo nell'oggetto CallMediaRecognizeChoiceOptions e quindi chiamare StartRecognizingAsync. Ciò consente all'applicazione di riconoscere l'opzione scelta dal chiamante.

callConnectionId = eventData.callConnectionId;
serverCallId = eventData.serverCallId;
console.log("Call back event received, callConnectionId=%s, serverCallId=%s, eventType=%s", callConnectionId, serverCallId, event.type);
callConnection = acsClient.getCallConnection(callConnectionId);
const callMedia = callConnection.getCallMedia();

if (event.type === "Microsoft.Communication.CallConnected") {
 	console.log("Received CallConnected event");
 	await startRecording();
	await startRecognizing(callMedia, mainMenu, "");
}

async function startRecognizing(callMedia: CallMedia, textToPlay: string, context: string) {
	const playSource: TextSource = {
 		text: textToPlay,
 		voiceName: "en-US-NancyNeural",
 		kind: "textSource"
 	};

 	const recognizeOptions: CallMediaRecognizeChoiceOptions = {
 		choices: await getChoices(),
 		interruptPrompt: false,
 		initialSilenceTimeoutInSeconds: 10,
 		playPrompt: playSource,
 		operationContext: context,
 		kind: "callMediaRecognizeChoiceOptions"
 	};

 	await callMedia.startRecognizing(callee, recognizeOptions)
 }

Gestire gli eventi di scelta

Servizi di comunicazione di Azure Call Automation attiva l'oggetto api/callbacks sul webhook configurato e invia una notifica all'eventoRecognizeCompleted. L'evento consente di rispondere all'input ricevuto e attivare un'azione. L'applicazione riproduce quindi un messaggio al chiamante in base all'input specifico ricevuto.

else if (event.type === "Microsoft.Communication.RecognizeCompleted") { 
	if(eventData.recognitionType === "choices"){ 
        	console.log("Recognition completed, event=%s, resultInformation=%s",eventData, eventData.resultInformation); 
        	var context = eventData.operationContext; 
            	const labelDetected = eventData.choiceResult.label;  
            	const phraseDetected = eventData.choiceResult.recognizedPhrase; 
            	console.log("Recognition completed, labelDetected=%s, phraseDetected=%s, context=%s", labelDetected, phraseDetected, eventData.operationContext); 
            	const textToPlay = labelDetected === confirmLabel ? confirmText : cancelText;            
            	await handlePlay(callMedia, textToPlay); 
        } 
}  
 
async function handlePlay(callConnectionMedia:CallMedia, textContent:string){ 
	const play : TextSource = { text:textContent , voiceName: "en-US-NancyNeural", kind: "textSource"} 
	await callConnectionMedia.playToAll([play]); 
} 

Riagganciare la chiamata

Infine, quando viene rilevata una condizione che ha senso per terminare la chiamata, è possibile usare il hangUp() metodo per appendere la chiamata.

  await acsClient.getCallRecording().stop(recordingId);
  callConnection.hangUp(true);

Eseguire il codice

Per eseguire l'applicazione, aprire una finestra del terminale ed eseguire il comando seguente:

  npm run dev

Prerequisiti

Codice di esempio

Scaricare o clonare il codice di esempio di avvio rapido da GitHub.

Passare alla CallAutomation_OutboundCalling cartella e aprire la soluzione in un editor di codice.

Configurare l'ambiente Python

Creare e attivare l'ambiente Python e installare i pacchetti necessari usando il comando seguente. Altre informazioni sulla gestione dei pacchetti sono disponibili qui

pip install -r requirements.txt

Configurare e ospitare Azure DevTunnel

Azure DevTunnels è un servizio di Azure che consente di condividere servizi Web locali ospitati su Internet. Usare i comandi per connettere l'ambiente di sviluppo locale alla rete Internet pubblica. DevTunnels crea un tunnel con un URL dell'endpoint permanente e che consente l'accesso anonimo. Questo endpoint viene usato per notificare all'applicazione gli eventi di chiamata dal servizio di automazione delle chiamate Servizi di comunicazione di Azure.

devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host

Aggiornare la configurazione dell'applicazione

Aggiornare quindi il main.py file con i valori seguenti:

  • ACS_CONNECTION_STRING: stringa di connessione per la risorsa Servizi di comunicazione di Azure. È possibile trovare il Servizi di comunicazione di Azure stringa di connessione seguendo le istruzioni riportate qui.
  • CALLBACK_URI_HOST: dopo aver inizializzato l'host DevTunnel, aggiornare questo campo con tale URI.
  • TARGET_PHONE_NUMBER: aggiornare il campo con il numero di telefono che si desidera chiamare l'applicazione. Questo numero di telefono deve usare il formato numero di telefono E164 (ad esempio +18881234567)
  • ACS_PHONE_NUMBER: aggiornare questo campo con il numero di telefono Servizi di comunicazione di Azure acquisito. Questo numero di telefono deve usare il formato numero di telefono E164 (ad esempio +18881234567)
  • COGNITIVE_SERVICES_ENDPOINT: campo di aggiornamento con l'endpoint di Servizi di intelligenza artificiale di Azure.
  • TARGET_TEAMS_USER_ID: campo di aggiornamento (facoltativo) con l'ID utente di Microsoft Teams che si vuole aggiungere alla chiamata. Vedere Usare l'API Graph per ottenere l'ID utente di Teams.
# Your ACS resource connection string 
ACS_CONNECTION_STRING = "<ACS_CONNECTION_STRING>" 

# Your ACS resource phone number will act as source number to start outbound call 
ACS_PHONE_NUMBER = "<ACS_PHONE_NUMBER>" 

# Target phone number you want to receive the call. 
TARGET_PHONE_NUMBER = "<TARGET_PHONE_NUMBER>" 

# Callback events URI to handle callback events. 
CALLBACK_URI_HOST = "<CALLBACK_URI_HOST_WITH_PROTOCOL>" 
CALLBACK_EVENTS_URI = CALLBACK_URI_HOST + "/api/callbacks" 

#Your Cognitive service endpoint 
COGNITIVE_SERVICES_ENDPOINT = "<COGNITIVE_SERVICES_ENDPOINT>" 

#(OPTIONAL) Your target Microsoft Teams user Id ex. "ab01bc12-d457-4995-a27b-c405ecfe4870"
TARGET_TEAMS_USER_ID = "<TARGET_TEAMS_USER_ID>"

Effettuare una chiamata in uscita

Per effettuare la chiamata in uscita da Servizi di comunicazione di Azure, specificare prima di tutto il numero di telefono che si vuole ricevere la chiamata. Per semplificare l'operazione target_phone_number , è possibile aggiornare con un numero di telefono nel formato numero di telefono E164 (ad esempio +18881234567)

Effettuare una chiamata in uscita usando il target_phone_number specificato:

target_participant = PhoneNumberIdentifier(TARGET_PHONE_NUMBER) 
source_caller = PhoneNumberIdentifier(ACS_PHONE_NUMBER) 
call_invite = CallInvite(target=target_participant, source_caller_id_number=source_caller) 
call_connection_properties = call_automation_client.create_call(call_invite, CALLBACK_EVENTS_URI, 
cognitive_services_endpoint=COGNITIVE_SERVICES_ENDPOINT) 
    app.logger.info("Created call with connection id: %s",
call_connection_properties.call_connection_id) 
return redirect("/") 

(Facoltativo) Aggiungere un utente di Microsoft Teams alla chiamata

È possibile aggiungere un utente di Microsoft Teams alla chiamata usando il add_participant metodo con un MicrosoftTeamsUserIdentifier e l'ID dell'utente di Teams. Per abilitare la chiamata agli utenti di Microsoft Teams, è prima necessario completare il passaggio prerequisito Autorizzazione per la risorsa Servizi di comunicazione di Azure. Facoltativamente, è anche possibile passare un oggetto source_display_name per controllare il testo visualizzato nella notifica di tipo avviso popup per l'utente di Teams.

call_connection_client.add_participant(target_participant = CallInvite(
    target = MicrosoftTeamsUserIdentifier(user_id=TARGET_TEAMS_USER_ID),
    source_display_name = "Jack (Contoso Tech Support)"))

Avviare la registrazione di una chiamata

Il servizio Di automazione delle chiamate consente anche di avviare la registrazione e archiviare le registrazioni delle chiamate vocali e video. Altre informazioni sulle varie funzionalità disponibili nelle API di registrazione delle chiamate sono disponibili qui.

recording_properties = call_automation_client.start_recording(ServerCallLocator(event.data['serverCallId']))
recording_id = recording_properties.recording_id

Rispondere agli eventi di chiamata

In precedenza nell'applicazione è stato registrato CALLBACK_URI_HOST nel servizio di automazione delle chiamate. L'URI indica l'endpoint usato dal servizio per notificare gli eventi che si verificano. È quindi possibile scorrere gli eventi e rilevare eventi specifici che l'applicazione vuole comprendere. Nel codice riportato di seguito viene risposto all'evento CallConnected .

@app.route('/api/callbacks', methods=['POST'])
def callback_events_handler():
    for event_dict in request.json:
        event = CloudEvent.from_dict(event_dict)
        if event.type == "Microsoft.Communication.CallConnected":
            # Handle Call Connected Event
            ...
            return Response(status=200)

Riprodurre un messaggio di benvenuto e riconoscere

TextSourceUsando , è possibile fornire al servizio il testo che si vuole sintetizzare e usare per il messaggio di benvenuto. Il servizio di automazione delle chiamate Servizi di comunicazione di Azure riproduce questo messaggio all'eventoCallConnected.

Passare quindi il testo nell'oggetto CallMediaRecognizeChoiceOptions e quindi chiamare StartRecognizingAsync. Ciò consente all'applicazione di riconoscere l'opzione scelta dal chiamante.


get_media_recognize_choice_options( 
    call_connection_client=call_connection_client, 
    text_to_play=MainMenu,  
    target_participant=target_participant, 
    choices=get_choices(),context="") 

def get_media_recognize_choice_options(call_connection_client: CallConnectionClient, text_to_play: str, target_participant:str, choices: any, context: str): 
    play_source =  TextSource (text= text_to_play, voice_name= SpeechToTextVoice) 
    call_connection_client.start_recognizing_media( 
        input_type=RecognizeInputType.CHOICES, 

        target_participant=target_participant,
        choices=choices, 
        play_prompt=play_source, 
        interrupt_prompt=False, 
        initial_silence_timeout=10, 
        operation_context=context 
    ) 

def get_choices(): 
    choices = [ 
        RecognitionChoice(label = ConfirmChoiceLabel, phrases= ["Confirm", "First", "One"], tone = DtmfTone.ONE), 
        RecognitionChoice(label = CancelChoiceLabel, phrases= ["Cancel", "Second", "Two"], tone = DtmfTone.TWO) 
    ] 
return choices 

Gestire gli eventi di scelta

Servizi di comunicazione di Azure Call Automation attiva l'oggetto api/callbacks sul webhook configurato e invia una notifica all'eventoRecognizeCompleted. L'evento consente di rispondere all'input ricevuto e attivare un'azione. L'applicazione riproduce quindi un messaggio al chiamante in base all'input specifico ricevuto.

elif event.type == "Microsoft.Communication.RecognizeCompleted":
	app.logger.info("Recognize completed: data=%s", event.data)
if event.data['recognitionType'] == "choices":
	labelDetected = event.data['choiceResult']['label'];
phraseDetected = event.data['choiceResult']['recognizedPhrase'];
app.logger.info("Recognition completed, labelDetected=%s, phraseDetected=%s, context=%s", labelDetected, phraseDetected, event.data.get('operationContext'))
if labelDetected == ConfirmChoiceLabel:
	textToPlay = ConfirmedText
else:
	textToPlay = CancelText
handle_play(call_connection_client = call_connection_client, text_to_play = textToPlay)
def handle_play(call_connection_client: CallConnectionClient, text_to_play: str):
	play_source = TextSource(text = text_to_play, voice_name = SpeechToTextVoice)
call_connection_client.play_media_to_all(play_source)

Riagganciare la chiamata

Infine, quando viene rilevata una condizione che ha senso per terminare la chiamata, è possibile usare il hang_up() metodo per appendere la chiamata. Infine, è anche possibile arrestare in modo sicuro l'operazione di registrazione delle chiamate.

call_automation_client.stop_recording(recording_id)
call_connection_client.hang_up(is_for_everyone=True)

Eseguire il codice

Per eseguire l'applicazione con VS Code, aprire una finestra del terminale ed eseguire il comando seguente

python main.py