Comment contrôler et diriger les appels avec Call Automation

Call Automation utilise une interface d’API REST pour recevoir des requêtes d’actions et fournir des réponses pour indiquer si la requête a été envoyée avec succès ou non. Pour la plupart des actions, des événements correspondants sont déclenchés lorsque l’action se termine correctement ou échoue, et ce, en raison de la nature asynchrone de l’appel. Ce guide décrit les actions disponibles pour diriger les appels, comme CreateCall, Transfer, Redirect et la gestion des participants. Les actions sont accompagnées d’un exemple de code sur la façon d’appeler l’action en question, et de diagrammes de séquence qui décrivent les événements attendus après l’appel d’une action. Ces diagrammes vous aident à visualiser comment programmer votre application de service avec Call Automation.

Call Automation prend en charge différentes autres actions pour gérer les supports d’appel et l’enregistrement qui ont des repères distincts.

Comme condition préalable, nous vous recommandons de lire ces articles pour tirer le meilleur parti de ce guide :

  1. Guide des concepts de Call Automation, qui décrit le modèle de programmation d’événements d’action et les rappels d’événements.
  2. Découvrez les identificateurs d’utilisateur comme CommunicationUserIdentifier et PhoneNumberIdentifier utilisés dans ce guide.

Pour tous les exemples de code, client est l’objet CallAutomationClient qui peut être créé comme indiqué, et callConnection est l’objet CallConnection obtenu à partir de la réponse Answer ou CreateCall. Vous pouvez également l’obtenir à partir d’événements de rappel reçus par votre application.

var client = new CallAutomationClient("<resource_connection_string>"); 

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

Vous pouvez passer un appel 1:1 ou un appel de groupe à un utilisateur de communication ou à un numéro de téléphone (numéro public ou appartenant à Communication Services). Lors de l’appel d’un point de terminaison RTC, vous devez également fournir un numéro de téléphone utilisé comme ID d’appelant source et affiché dans la notification d’appel au point de terminaison RTC cible. Pour passer un appel à un utilisateur Communication Services, vous devez fournir un objet CommunicationUserIdentifier au lieu de PhoneNumberIdentifier.

Uri callbackUri = new Uri("https://<myendpoint>/Events"); //the callback endpoint where you want to receive subsequent events 
var callerIdNumber = new PhoneNumberIdentifier("+16044561234"); // This is the Azure Communication Services provisioned phone number for the caller  
var callThisPerson = new CallInvite(new PhoneNumberIdentifier("+16041234567"), callerIdNumber); // person to call
CreateCallResult response = await client.CreateCallAsync(callThisPerson, callbackUri);

Lorsque vous effectuez un appel de groupe incluant un numéro de téléphone, vous devez fournir un numéro de téléphone utilisé comme numéro d’ID d’appelant au point de terminaison RTC.

Uri callbackUri = new Uri("https://<myendpoint>/Events"); //the callback endpoint where you want to receive subsequent events 
var pstnEndpoint = new PhoneNumberIdentifier("+16041234567");
var voipEndpoint = new CommunicationUserIdentifier("<user_id_of_target>"); //user id looks like 8:a1b1c1-...
var groupCallOptions = new CreateGroupCallOptions(new List<CommunicationIdentifier>{ pstnEndpoint, voipEndpoint }, callbackUri)
{
    SourceCallerIdNumber = new PhoneNumberIdentifier("+16044561234"), // This is the Azure Communication Services provisioned phone number for the caller
};
CreateCallResult response = await client.CreateGroupCallAsync(groupCallOptions);

La réponse vous fournit l’objet CallConnection que vous pouvez utiliser pour effectuer d’autres actions sur cet appel une fois qu’il est connecté. Une fois l’appel répondu, deux événements sont publiés sur le point de terminaison de rappel que vous avez fourni précédemment :

  1. Événement CallConnected signalant que l’appel a été établi avec l’appelé.
  2. L’événement ParticipantsUpdated qui contient la dernière liste des participants à l’appel. Diagramme de séquence pour placer un appel sortant.

En cas d’échec de l’appel, vous recevrez les événements CallDisconnected et CreateCallFailed avec des codes d’erreur pour une résolution des problèmes plus approfondie (consultez cette page pour plus d’informations sur les codes d’erreur Call Automation).

Se connecter à un appel (en préversion)

L’action de connexion permet à votre service d’établir une connexion avec un appel en cours et de prendre des mesures dessus. Cela est utile pour gérer un appel de salles ou lorsque les applications clientes ont démarré un appel de groupe ou 1:1 dont l’automatisation des appels ne fait pas partie. La connexion est établie à l’aide de la propriété CallLocator et peut être de type : ServerCallLocator, GroupCallLocator et RoomCallLocator. Ces ID sont disponibles lorsque l’appel est initialement établi ou qu’une salle est créée, et également publiée dans le cadre d’événement CallStarted.

Pour vous connecter à n’importe quel appel de groupe ou 1:1, utilisez ServerCallLocator. Si vous avez démarré un appel à l’aide de GroupCallId, vous pouvez également utiliser GroupCallLocator.

Uri callbackUri = new Uri("https://<myendpoint>/Events"); //the callback endpoint where you want to receive subsequent events
CallLocator serverCallLocator = new ServerCallLocator("<ServerCallId>");
ConnectCallResult response = await client.ConnectCallAsync(serverCallLocator, callbackUri);

Pour vous connecter à un appel RoomCallLocator, utilisez RoomCallLocator qui prend RoomId. Découvrez plus d’informations sur Rooms et comment l’API Automation des appels peut être utilisé pour gérer un appel Rooms en cours.

Uri callbackUri = new Uri("https://<myendpoint>/Events"); //the callback endpoint where you want to receive subsequent events
CallLocator roomCallLocator = new RoomCallLocator("<RoomId>");
ConnectCallResult response = await client.ConnectCallAsync(roomCallLocator, callbackUri);

Une réponse réussie vous fournit un objet CallConnection que vous pouvez utiliser pour effectuer d’autres actions sur cet appel. Deux événements sont publiés sur le point de terminaison de rappel que vous avez fourni précédemment :

  1. CallConnected événement signalant que vous vous connectez correctement à l’appel.
  2. L’événement ParticipantsUpdated qui contient la dernière liste des participants à l’appel.

À tout moment après une connexion réussie, si votre service est déconnecté de cet appel, vous serez averti via un événement CallDisconected. L’échec de la connexion à l’appel en premier lieu entraîne l’événement ConnectFailed.

Diagramme de séquence pour la connexion à l’appel.

Répondre à un appel entrant

Une fois que vous avez souscrit pour recevoir des notifications d’appel entrantes à votre ressource, vous répondez à un appel entrant. Lorsque vous répondez à un appel, il est nécessaire de fournir une URL de rappel. Communication Services publie tous les événements suivants sur cet appel à cette URL.

string incomingCallContext = "<IncomingCallContext_From_IncomingCall_Event>"; 
Uri callBackUri = new Uri("https://<myendpoint_where_I_want_to_receive_callback_events"); 

var answerCallOptions = new AnswerCallOptions(incomingCallContext, callBackUri);  
AnswerCallResult answerResponse = await client.AnswerCallAsync(answerCallOptions);
CallConnection callConnection = answerResponse.CallConnection; 

La réponse vous fournit l’objet CallConnection que vous pouvez utiliser pour effectuer d’autres actions sur cet appel une fois qu’il est connecté. Une fois l’appel répondu, deux événements sont publiés sur le point de terminaison de rappel que vous avez fourni précédemment :

  1. Événement CallConnected signalant que l’appel a été établi avec l’appelant.
  2. L’événement ParticipantsUpdated qui contient la dernière liste des participants à l’appel.

Diagramme de séquence pour répondre à un appel entrant.

Rejeter un appel

Vous pouvez choisir de rejeter un appel entrant comme indiqué ci-dessous. Vous pouvez fournir un motif de rejet : aucun, occupé ou interdit. Si rien n’est fourni, « aucun » est choisi par défaut.

string incomingCallContext = "<IncomingCallContext_From_IncomingCall_Event>"; 
var rejectOption = new RejectCallOptions(incomingCallContext); 
rejectOption.CallRejectReason = CallRejectReason.Forbidden; 
_ = await client.RejectCallAsync(rejectOption); 

Aucun événement n’est publié pour l’action de rejet.

Rediriger un appel

Vous pouvez choisir de rediriger un appel entrant vers un autre point de terminaison sans y répondre. La redirection d’un appel supprime la capacité de votre application à contrôler l’appel à l’aide de Call Automation.

string incomingCallContext = "<IncomingCallContext_From_IncomingCall_Event>"; 
var target = new CallInvite(new CommunicationUserIdentifier("<user_id_of_target>")); //user id looks like 8:a1b1c1-... 
_ = await client.RedirectCallAsync(incomingCallContext, target); 

Pour rediriger l’appel vers un numéro de téléphone, construisez l’ID de cible et d’appelant avec PhoneNumberIdentifier.

var callerIdNumber = new PhoneNumberIdentifier("+16044561234"); // This is the Azure Communication Services provisioned phone number for the caller
var target = new CallInvite(new PhoneNumberIdentifier("+16041234567"), callerIdNumber);

Aucun événement n’est publié pour la redirection. Si la cible est un utilisateur Communication Services ou un numéro de téléphone appartenant à votre ressource, il génère un nouvel événement IncomingCall avec le champ « to » défini sur la cible que vous avez spécifiée.

Transférer un participant à l’appel

Lorsque votre application répond à un appel ou passe un appel sortant vers un point de terminaison, ce point de terminaison peut être transféré vers un autre point de terminaison de destination. Le transfert d’un appel 1:1 supprime votre application de l’appel et supprime donc sa capacité à contrôler l’appel à l’aide de Call Automation. L’invitation d’appel à la cible affiche l’ID de l’appelant du point de terminaison transféré. La fourniture d’un ID d’appelant personnalisé n’est pas prise en charge.

var transferDestination = new CommunicationUserIdentifier("<user_id>"); 
var transferOption = new TransferToParticipantOptions(transferDestination) {
    OperationContext = "<Your_context>",
    OperationCallbackUri = new Uri("<uri_endpoint>") // Sending event to a non-default endpoint.
};
// adding customCallingContext
transferOption.CustomCallingContext.AddVoip("customVoipHeader1", "customVoipHeaderValue1");
transferOption.CustomCallingContext.AddVoip("customVoipHeader2", "customVoipHeaderValue2");

TransferCallToParticipantResult result = await callConnection.TransferCallToParticipantAsync(transferOption);

Lorsque votre application répond à un appel de groupe ou place un appel de groupe sortant vers un point de terminaison ou ajouté un participant à un appel 1:1, un point de terminaison peut être transféré de l’appel vers un autre point de terminaison de destination, à l’exception du point de terminaison Automation des appels. Le transfert d’un participant dans un appel de groupe supprime le point de terminaison transféré de l’appel. L’invitation d’appel à la cible affiche l’ID de l’appelant du point de terminaison transféré. La fourniture d’un ID d’appelant personnalisé n’est pas prise en charge.

// Transfer User
var transferDestination = new CommunicationUserIdentifier("<user_id>");
var transferee = new CommunicationUserIdentifier("<transferee_user_id>"); 
var transferOption = new TransferToParticipantOptions(transferDestination);
transferOption.Transferee = transferee;

// adding customCallingContext
transferOption.CustomCallingContext.AddVoip("customVoipHeader1", "customVoipHeaderValue1");
transferOption.CustomCallingContext.AddVoip("customVoipHeader2", "customVoipHeaderValue2");

transferOption.OperationContext = "<Your_context>";
transferOption.OperationCallbackUri = new Uri("<uri_endpoint>");
TransferCallToParticipantResult result = await callConnection.TransferCallToParticipantAsync(transferOption);

// Transfer PSTN User
var transferDestination = new PhoneNumberIdentifier("<target_phoneNumber>");
var transferee = new PhoneNumberIdentifier("<transferee_phoneNumber>"); 
var transferOption = new TransferToParticipantOptions(transferDestination);
transferOption.Transferee = transferee;

// adding customCallingContext
transferOption.CustomCallingContext.AddSipUui("uuivalue");
transferOption.CustomCallingContext.AddSipX("header1", "headerValue");

transferOption.OperationContext = "<Your_context>";

// Sending event to a non-default endpoint.
transferOption.OperationCallbackUri = new Uri("<uri_endpoint>");

TransferCallToParticipantResult result = await callConnection.TransferCallToParticipantAsync(transferOption);

Le diagramme de séquence montre le flux attendu lorsque votre application place un appel sortant, puis le transfère vers un autre point de terminaison.

Diagramme de séquence pour placer un appel 1:1, puis le transférer.

Ajouter un participant à un appel

Vous pouvez ajouter un participant (utilisateur ou numéro de téléphone Communication Services) à un appel existant. Lors de l’ajout d’un numéro de téléphone, il est obligatoire de fournir un ID d’appelant. Cet ID d’appelant s’affiche lors de la notification d’appel au participant ajouté.

// Add user
var addThisPerson = new CallInvite(new CommunicationUserIdentifier("<user_id>"));
// add custom calling context
addThisPerson.CustomCallingContext.AddVoip("myHeader", "myValue");
AddParticipantsResult result = await callConnection.AddParticipantAsync(addThisPerson);

// Add PSTN user
var callerIdNumber = new PhoneNumberIdentifier("+16044561234"); // This is the Azure Communication Services provisioned phone number for the caller
var addThisPerson = new CallInvite(new PhoneNumberIdentifier("+16041234567"), callerIdNumber);
// add custom calling context
addThisPerson.CustomCallingContext.AddSipUui("value");
addThisPerson.CustomCallingContext.AddSipX("header1", "customSipHeaderValue1");

// Use option bag to set optional parameters
var addParticipantOptions = new AddParticipantOptions(new CallInvite(addThisPerson))
{
    InvitationTimeoutInSeconds = 60,
    OperationContext = "operationContext",
    OperationCallbackUri = new Uri("uri_endpoint"); // Sending event to a non-default endpoint.
};

AddParticipantsResult result = await callConnection.AddParticipantAsync(addParticipantOptions); 

Pour ajouter un utilisateur Communication Services, fournissez communicationUserIdentifier au lieu de PhoneNumberIdentifier. L’ID de l’appelant n’est pas obligatoire dans ce cas.

AddParticipant publie un événement AddParticipantSucceeded ou AddParticipantFailed , ainsi qu’un ParticipantUpdated fournissant la dernière liste des participants à l’appel.

Diagramme de séquence pour l’ajout d’un participant à l’appel.

Annuler une demande d’ajout de participant

// add a participant
var addThisPerson = new CallInvite(new CommunicationUserIdentifier("<user_id>"));
var addParticipantResponse = await callConnection.AddParticipantAsync(addThisPerson);

// cancel the request with optional parameters
var cancelAddParticipantOperationOptions = new CancelAddParticipantOperationOptions(addParticipantResponse.Value.InvitationId)
{
    OperationContext = "operationContext",
    OperationCallbackUri = new Uri("uri_endpoint"); // Sending event to a non-default endpoint.
}
await callConnection.CancelAddParticipantOperationAsync(cancelAddParticipantOperationOptions);

Supprimer un participant d’un appel

var removeThisUser = new CommunicationUserIdentifier("<user_id>"); 

// remove a participant from the call with optional parameters
var removeParticipantOptions = new RemoveParticipantOptions(removeThisUser)
{
    OperationContext = "operationContext",
    OperationCallbackUri = new Uri("uri_endpoint"); // Sending event to a non-default endpoint.
}

RemoveParticipantsResult result = await callConnection.RemoveParticipantAsync(removeParticipantOptions);

RemoveParticipant publiera un événement RemoveParticipantSucceeded ou RemoveParticipantFailed, en plus d’un ParticipantUpdated fournissant la liste la plus récente des participants à l’appel. Le participant supprimé est omis de la liste.
Diagramme de séquence pour supprimer un participant de l’appel.

Raccrocher lors d’un appel

L’action Raccrocher peut être utilisée pour supprimer votre application de l’appel ou pour arrêter un appel de groupe en définissant le paramètre forEveryone sur true. Pour un appel 1:1, raccrocher l’appel avec l’autre participant par défaut.

_ = await callConnection.HangUpAsync(forEveryone: true); 

L’événement CallDisconnected est publié une fois l’action hangUp terminée.

Obtenir des informations sur un participant à l’appel

CallParticipant participantInfo = await callConnection.GetParticipantAsync(new CommunicationUserIdentifier("<user_id>"));

Obtenir des informations sur tous les participants à l’appel

List<CallParticipant> participantList = (await callConnection.GetParticipantsAsync()).Value.ToList(); 

Obtenir les dernières informations sur un appel

CallConnectionProperties callConnectionProperties = await callConnection.GetCallConnectionPropertiesAsync();