Démarrage rapide : effectuer un appel sortant à l’aide de l’automatisation des appels

Les APIs d’automatisation des appels d’Azure Communication Services sont un moyen puissant pour créer des expériences d’appel interactives. Dans ce guide de démarrage rapide, nous expliquons une manière d’effectuer un appel sortant et de reconnaître différents événements dans l’appel.

Prérequis

Exemple de code

Téléchargez ou clonez le code d’exemple de démarrage rapide du GitHub.

Accédez au CallAutomation_OutboundCalling dossier et ouvrez la solution dans un éditeur de code.

Configurez et hébergez votre Azure DevTunnel

Azure DevTunnels est un service Azure qui vous permet de partager des services web locaux hébergés sur Internet. Exécutez les commandes pour connecter votre environnement de développement local à l’internet public. DevTunnels crée une URL de point de terminaison persistante qui autorise l’accès anonyme. Nous utilisons ce point de terminaison pour notifier votre application des évènements d’appel à partir du service d’automatisation des appels d’Azure Communication Services.

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

Vous pouvez également suivre les instructions pour configurer votre Azure DevTunnel dans Visual Studio

Mettez à jour la configuration de votre application

Ensuite, Mettez à jour votre Program.cs fichier avec les valeurs suivantes :

  • acsConnectionString : la chaîne de connexion pour votre ressource Azure Communication Services. Vous pouvez trouver votre chaîne de connexion Azure Communication Services à l’aide des instructions fournies ici.
  • callbackUriHost : une fois votre hôte DevTunnel initialisé, mettez à jour ce champ avec cet URI.
  • acsPhonenumber : mettez à jour ce champ avec le numéro de téléphone Azure Communication Services que vous avez obtenu. Ce numéro de téléphone doit utiliser le format E164 (par exemple : +18881234567)
  • targetPhonenumber : mettez à jour le champ avec le numéro de téléphone que vous souhaitez que votre application appelle. Ce numéro de téléphone doit utiliser le format E164 (par exemple : +18881234567)
  • cognitiveServiceEndpoint : mettez à jour le champ avec votre point de terminaison de Azure AI services.
  • targetTeamsUserId: (facultatif) mettez à jour le champ avec l’ID d’utilisateur Microsoft Teams que vous souhaitez ajouter à l’appel. Consultez Utiliser l’API Graph pour obtenir l’ID d’utilisateur 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>";

Exécution d’un appel téléphonique

Pour effectuer l’appel sortant à partir d’Azure Communication Services, cet exemple utilise le targetPhonenumber que vous avez défini précédemment dans l’application pour créer l’appel en utilisant l’API CreateCallAsync . Ce code effectue un appel sortant à partir du numéro de téléphone cible.

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);

Gérer les événements d’automatisation des appels

Plus tôt dans notre application, nous avons inscrit le callbackUriHost auprès du service d’automatisation des appels. L’hôte indique le point de terminaison dont le service a besoin pour nous informer des événements d’appel qui se produisent. Nous pouvons ensuite itérer à travers des événements, ainsi que détecter des événements spécifiques que notre application cherche à comprendre. Dans le code ci-dessous, nous répondons à l’événement 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
    }
  }
});

(Facultatif) Ajouter un utilisateur Microsoft Teams à l’appel

Vous pouvez ajouter un utilisateur Microsoft Teams à l’appel à l’aide de la méthode AddParticipantAsync avec un MicrosoftTeamsUserIdentifier et l’ID de l’utilisateur Teams. Vous devez d’abord compléter le prérequis Autorisation pour votre ressource Azure Communication Services afin d’activer l’appel aux utilisateurs de Microsoft Teams. Vous pouvez également facultativement transmettre un SourceDisplayName pour contrôler le texte affiché dans la notification toast de l’utilisateur Teams.

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

Démarrer l’enregistrement d’un appel

Le service d’automatisation des appels permet également de démarrer l’enregistrement et de stocker des enregistrements d’appels vocaux et vidéo. Vous pouvez en savoir plus sur les différentes fonctionnalités dans les APIs d’enregistrement d’appels ici.

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

Lire le message de bienvenue et reconnaître

À l’aide de TextSource, vous pouvez fournir au service le texte que vous souhaitez synthétiser et utiliser pour votre message d’accueil. Le service d’automatisation des appels d’Azure Communication Services diffuse ce message lors de l’événement CallConnected.

Ensuite, nous transmettons le texte dans le CallMediaRecognizeChoiceOptions, puis nous appelons StartRecognizingAsync. Cela permet à votre application de reconnaître l’option choisie par l’appelant.

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
    }
  };
}

Gérer les événements Choice

L’automatisation des appels d’Azure Communication Services déclenche le api/callbacks webhook que nous avons configuré et nous informe de l’événement RecognizeCompleted. L’événement nous donne la possibilité de répondre à une entrée reçue et de déclencher une action. L’application lit ensuite un message à l’appelant en fonction de l’entrée spécifique reçue.

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);
}

Raccrocher et arrêter l’enregistrement

Pour finir, lorsque nous détectons une condition qui justifie de mettre fin à l’appel, nous pouvons utiliser la méthode HangUpAsync pour raccrocher l’appel.

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

Exécuter le code

Pour exécuter l’application avec VS Code, ouvrez une fenêtre de terminal et exécutez la commande suivante

dotnet run

Ouvrez http://localhost:8080/swagger/index.html ou votre URL de tunnel de développement dans le navigateur. L’URL du tunnel ressemble à ceci : <YOUR DEV TUNNEL ENDPOINT>/swagger/index.html

Prérequis

Exemple de code

Téléchargez ou clonez le code d’exemple de démarrage rapide du GitHub.

Accédez au CallAutomation_OutboundCalling dossier et ouvrez la solution dans un éditeur de code.

Configurez et hébergez votre Azure DevTunnel

Azure DevTunnels est un service Azure qui vous permet de partager des services web locaux hébergés sur Internet. Exécutez les commandes DevTunnel pour connecter votre environnement de développement local à l’internet public. DevTunnels crée ensuite un tunnel avec une URL de point de terminaison persistante et qui autorise l’accès anonyme. Azure Communication Services utilise ce point de terminaison pour notifier votre application des évènements d’appel à partir du service d’automatisation des appels d’Azure Communication Services.

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

Mettez à jour la configuration de votre application

Ouvrez ensuite le application.yml fichier dans le /resources dossier pour configurer les valeurs suivantes :

  • connectionstring : la chaîne de connexion pour votre ressource Azure Communication Services. Vous pouvez trouver votre chaîne de connexion Azure Communication Services à l’aide des instructions fournies ici.
  • basecallbackuri : une fois votre hôte DevTunnel initialisé, mettez à jour ce champ avec cet URI.
  • callerphonenumber : mettez à jour ce champ avec le numéro de téléphone Azure Communication Services que vous avez obtenu. Ce numéro de téléphone doit utiliser le format E164 (par exemple : +18881234567)
  • targetphonenumber : mettez à jour le champ avec le numéro de téléphone que vous souhaitez que votre application appelle. Ce numéro de téléphone doit utiliser le format E164 (par exemple : +18881234567)
  • cognitiveServiceEndpoint : mettez à jour le champ avec votre point de terminaison de Azure AI services.
  • targetTeamsUserId: (facultatif) mettez à jour le champ avec l’ID d’utilisateur Microsoft Teams que vous souhaitez ajouter à l’appel. Consultez Utiliser l’API Graph pour obtenir l’ID d’utilisateur 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">

Passer un appel sortant et lire un média

Pour effectuer l’appel sortant à partir d’Azure Communication Services, cet exemple utilise le targetphonenumber que vous avez défini précédemment dans le fichier application.yml pour créer l’appel en utilisant l’API createCallWithResponse.

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);

(Facultatif) Ajouter un utilisateur Microsoft Teams à l’appel

Vous pouvez ajouter un utilisateur Microsoft Teams à l’appel à l’aide de la méthode addParticipant avec un MicrosoftTeamsUserIdentifier et l’ID de l’utilisateur Teams. Vous devez d’abord compléter le prérequis Autorisation pour votre ressource Azure Communication Services afin d’activer l’appel aux utilisateurs de Microsoft Teams. Vous pouvez également facultativement transmettre un SourceDisplayName pour contrôler le texte affiché dans la notification toast de l’utilisateur Teams.

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

Démarrer l’enregistrement d’un appel

Le service d’automatisation des appels permet également de démarrer l’enregistrement et de stocker des enregistrements d’appels vocaux et vidéo. Vous pouvez en savoir plus sur les différentes fonctionnalités dans les APIs d’enregistrement d’appels ici.

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();

Répondre aux événements d’appel

Plus tôt dans notre application, nous avons inscrit le basecallbackuri auprès du service d’automatisation des appels. L’URI indique le point de terminaison que le service utilisera pour nous informer des événements d’appel qui se produisent. Nous pouvons ensuite itérer à travers des événements, ainsi que détecter des événements spécifiques que notre application cherche à comprendre. Dans le code ci-dessous, nous répondons à l’événement 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");
    }
}

Lire le message de bienvenue et reconnaître

À l’aide de TextSource, vous pouvez fournir au service le texte que vous souhaitez synthétiser et utiliser pour votre message d’accueil. Le service d’automatisation des appels d’Azure Communication Services diffuse ce message lors de l’événement CallConnected.

Ensuite, nous transmettons le texte dans le CallMediaRecognizeChoiceOptions, puis nous appelons StartRecognizingAsync. Cela permet à votre application de reconnaître l’option choisie par l’appelant.

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;
}

Gérer les événements Choice

L’automatisation des appels d’Azure Communication Services déclenche le api/callbacks webhook que nous avons configuré et nous informe de l’événement RecognizeCompleted. L’événement nous donne la possibilité de répondre à une entrée reçue et de déclencher une action. L’application lit ensuite un message à l’appelant en fonction de l’entrée spécifique reçue.

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);
}

Mettre fin à l’appel

Pour finir, lorsque nous détectons une condition qui justifie de mettre fin à l’appel, nous pouvons utiliser la méthode hangUp pour raccrocher l’appel.

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

Exécuter le code

Accédez au répertoire contenant le fichier pom.xml, puis utilisez les commandes mvn suivantes :

  • Compiler l’application : mvn compile
  • Générer le paquet : mvn package
  • Exécutez l’application : mvn exec:java

Prérequis

Exemple de code

Téléchargez ou clonez le code d’exemple de démarrage rapide du GitHub.

Accédez au CallAutomation_OutboundCalling dossier et ouvrez la solution dans un éditeur de code.

Configurer l’environnement

Téléchargez l’exemple de code, accédez au répertoire du projet et exécutez la npm commande qui installe les dépendances nécessaires et configure votre environnement de développeur.

npm install

Configurez et hébergez votre Azure DevTunnel

Azure DevTunnels est un service Azure qui vous permet de partager des services web locaux hébergés sur Internet. Utilisez les commandes CLI DevTunnel pour connecter votre environnement de développement local à l’internet public. Nous utilisons ce point de terminaison pour notifier votre application des évènements d’appel à partir du service d’automatisation des appels d’Azure Communication Services.

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

Mettez à jour la configuration de votre application

Ensuite, mettez à jour votre .env fichier avec les valeurs suivantes :

  • CONNECTION_STRING : la chaîne de connexion pour votre ressource Azure Communication Services. Vous pouvez trouver votre chaîne de connexion Azure Communication Services à l’aide des instructions fournies ici.
  • CALLBACK_URI : une fois votre hôte DevTunnel initialisé, mettez à jour ce champ avec cet URI.
  • TARGET_PHONE_NUMBER : mettez à jour le champ avec le numéro de téléphone que vous souhaitez que votre application appelle. Ce numéro de téléphone doit utiliser le format E164 (par exemple : +18881234567)
  • ACS_RESOURCE_PHONE_NUMBER : mettez à jour ce champ avec le numéro de téléphone Azure Communication Services que vous avez obtenu. Ce numéro de téléphone doit utiliser le format E164 (par exemple : +18881234567)
  • COGNITIVE_SERVICES_ENDPOINT : mettez à jour le champ avec votre point de terminaison de Azure AI services.
  • TARGET_TEAMS_USER_ID: (facultatif) mettez à jour le champ avec l’ID d’utilisateur Microsoft Teams que vous souhaitez ajouter à l’appel. Consultez Utiliser l’API Graph pour obtenir l’ID d’utilisateur 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>"

Passer un appel sortant et lire un média

Pour passer l’appel sortant à partir d’Azure Communication Services, vous utilisez le numéro de téléphone que vous avez fourni à l’environnement. Vérifiez que le numéro de téléphone est au format E164 (par exemple : +18881234567)

Le code effectue un appel sortant en utilisant le target_phone_number que vous avez fourni et passe un appel sortant à ce numéro :

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);

(Facultatif) Ajouter un utilisateur Microsoft Teams à l’appel

Vous pouvez ajouter un utilisateur Microsoft Teams à l’appel à l’aide de la méthode addParticipant avec la propriété microsoftTeamsUserId. Vous devez d’abord compléter le prérequis Autorisation pour votre ressource Azure Communication Services afin d’activer l’appel aux utilisateurs de Microsoft Teams. Vous pouvez également facultativement transmettre un sourceDisplayName pour contrôler le texte affiché dans la notification toast de l’utilisateur Teams.

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

Démarrer l’enregistrement d’un appel

Le service d’automatisation des appels permet également de démarrer l’enregistrement et de stocker des enregistrements d’appels vocaux et vidéo. Vous pouvez en savoir plus sur les différentes fonctionnalités dans les APIs d’enregistrement d’appels ici.

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

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

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

recordingId = response.recordingId;

Répondre aux événements d’appel

Plus tôt dans notre application, nous avons inscrit le CALLBACK_URI auprès du service d’automatisation des appels. L’URI indique le point de terminaison que le service utilise pour nous informer des événements d’appel qui se produisent. Nous pouvons ensuite itérer à travers des événements, ainsi que détecter des événements spécifiques que notre application cherche à comprendre. Nous répondons à l’événement CallConnected pour être avertis et lancer des opérations en aval. À l’aide de TextSource, vous pouvez fournir au service le texte que vous souhaitez synthétiser et utiliser pour votre message d’accueil. Le service d’automatisation des appels d’Azure Communication Services diffuse ce message lors de l’événement CallConnected.

Ensuite, nous transmettons le texte dans le CallMediaRecognizeChoiceOptions, puis nous appelons StartRecognizingAsync. Cela permet à votre application de reconnaître l’option choisie par l’appelant.

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)
 }

Gérer les événements Choice

L’automatisation des appels d’Azure Communication Services déclenche le api/callbacks webhook que nous avons configuré et nous informe de l’événement RecognizeCompleted. L’événement nous donne la possibilité de répondre à une entrée reçue et de déclencher une action. L’application lit ensuite un message à l’appelant en fonction de l’entrée spécifique reçue.

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]); 
} 

Mettre fin à l’appel

Pour finir, lorsque nous détectons une condition qui justifie de mettre fin à l’appel, nous pouvons utiliser la méthode hangUp() pour raccrocher l’appel.

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

Exécuter le code

Pour exécuter l’application, ouvrez une fenêtre de terminal et exécutez la commande suivante :

  npm run dev

Prérequis

Exemple de code

Téléchargez ou clonez le code d’exemple de démarrage rapide du GitHub.

Accédez au CallAutomation_OutboundCalling dossier et ouvrez la solution dans un éditeur de code.

Configurer un environnement Python

Créez et activez l’environnement Python et installez les paquets requis en utilisant la commande suivante. Vous pouvez en savoir plus sur la gestion des paquets ici

pip install -r requirements.txt

Configurez et hébergez votre Azure DevTunnel

Azure DevTunnels est un service Azure qui vous permet de partager des services web locaux hébergés sur Internet. Utilisez les commandes pour connecter votre environnement de développement local à l’Internet public. DevTunnels crée un tunnel avec une URL de point de terminaison persistante et qui autorise l’accès anonyme. Nous utilisons ce point de terminaison pour notifier votre application des évènements d’appel à partir du service d’automatisation des appels d’Azure Communication Services.

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

Mettez à jour la configuration de votre application

Ensuite, mettez à jour votre main.py fichier avec les valeurs suivantes :

  • ACS_CONNECTION_STRING : la chaîne de connexion pour votre ressource Azure Communication Services. Vous pouvez trouver votre chaîne de connexion Azure Communication Services à l’aide des instructions fournies ici.
  • CALLBACK_URI_HOST : une fois votre hôte DevTunnel initialisé, mettez à jour ce champ avec cet URI.
  • TARGET_PHONE_NUMBER : mettez à jour le champ avec le numéro de téléphone que vous souhaitez que votre application appelle. Ce numéro de téléphone doit utiliser le format E164 (par exemple : +18881234567)
  • ACS_PHONE_NUMBER : mettez à jour ce champ avec le numéro de téléphone Azure Communication Services que vous avez obtenu. Ce numéro de téléphone doit utiliser le format E164 (par exemple : +18881234567)
  • COGNITIVE_SERVICES_ENDPOINT : mettez à jour le champ avec votre point de terminaison de Azure AI services.
  • TARGET_TEAMS_USER_ID: (facultatif) mettez à jour le champ avec l’ID d’utilisateur Microsoft Teams que vous souhaitez ajouter à l’appel. Consultez Utiliser l’API Graph pour obtenir l’ID d’utilisateur 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>"

Exécution d’un appel téléphonique

Pour passer l’appel sortant à partir d’Azure Communication Services, vous devez d’abord indiquer le numéro de téléphone que vous souhaitez recevoir l’appel. Pour simplifier les choses, vous pouvez mettre à jour le target_phone_number avec un numéro de téléphone au format E164 (par exemple : +18881234567)

Effectuez un appel sortant en utilisant le target_phone_number que vous avez fourni :

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("/") 

(Facultatif) Ajouter un utilisateur Microsoft Teams à l’appel

Vous pouvez ajouter un utilisateur Microsoft Teams à l’appel à l’aide de la méthode add_participant avec un MicrosoftTeamsUserIdentifier et l’ID de l’utilisateur Teams. Vous devez d’abord compléter le prérequis Autorisation pour votre ressource Azure Communication Services afin d’activer l’appel aux utilisateurs de Microsoft Teams. Vous pouvez également facultativement transmettre un source_display_name pour contrôler le texte affiché dans la notification toast de l’utilisateur Teams.

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

Démarrer l’enregistrement d’un appel

Le service d’automatisation des appels permet également de démarrer l’enregistrement et de stocker des enregistrements d’appels vocaux et vidéo. Vous pouvez en savoir plus sur les différentes fonctionnalités dans les APIs d’enregistrement d’appels ici.

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

Répondre aux événements d’appel

Plus tôt dans notre application, nous avons inscrit le CALLBACK_URI_HOST auprès du service d’automatisation des appels. L’URI indique le point de terminaison que le service utilise pour nous informer des événements d’appel qui se produisent. Nous pouvons ensuite itérer à travers des événements, ainsi que détecter des événements spécifiques que notre application cherche à comprendre. Dans le code ci-dessous, nous répondons à l’événement 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)

Lire le message de bienvenue et reconnaître

À l’aide de TextSource, vous pouvez fournir au service le texte que vous souhaitez synthétiser et utiliser pour votre message d’accueil. Le service d’automatisation des appels d’Azure Communication Services diffuse ce message lors de l’événement CallConnected.

Ensuite, nous transmettons le texte dans le CallMediaRecognizeChoiceOptions, puis nous appelons StartRecognizingAsync. Cela permet à votre application de reconnaître l’option choisie par l’appelant.


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 

Gérer les événements Choice

L’automatisation des appels d’Azure Communication Services déclenche le api/callbacks webhook que nous avons configuré et nous informe de l’événement RecognizeCompleted. L’événement nous donne la possibilité de répondre à une entrée reçue et de déclencher une action. L’application lit ensuite un message à l’appelant en fonction de l’entrée spécifique reçue.

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)

Mettre fin à l’appel

Pour finir, lorsque nous détectons une condition qui justifie de mettre fin à l’appel, nous pouvons utiliser la méthode hang_up() pour raccrocher l’appel. Pour finir, nous pouvons également arrêter en toute sécurité l’opération d’enregistrement des appels.

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

Exécuter le code

Pour exécuter l’application avec VS Code, ouvrez une fenêtre de terminal et exécutez la commande suivante

python main.py