Steuern und Weiterleiten von Anrufen mit der Anrufautomatisierung

Die Anrufautomatisierung verwendet eine REST-API-Schnittstelle, um Anforderungen für Aktionen zu empfangen und Antworten bereitzustellen, um darüber zu informieren, ob die Anforderung erfolgreich übermittelt wurde. Da Anrufe asynchron erfolgen, verfügen die meisten Aktionen über entsprechende Ereignisse, die ausgelöst werden, wenn die Aktion erfolgreich oder mit Fehlern abgeschlossen wird. In diesem Leitfaden werden die verfügbaren Aktionen für die Steuerung von Anrufen behandelt, z. B. das Erstellen von Anrufen, die Übertragung, Umleitung und Verwaltung von Teilnehmenden. Die Aktionen werden mit Beispielcode zum Aufrufen der besagten Aktion und Sequenzdiagramme ergänzt, mit denen die nach dem Aufrufen einer Aktion erwarteten Ereignisse beschrieben werden. Diese Diagramme veranschaulichen die Programmierung Ihrer Dienstanwendung mit Anrufautomatisierung.

Die Anrufautomatisierung unterstützt verschiedene andere Aktionen zum Verwalten von Anrufmedien und Aufzeichnungen, die in anderen Leitfäden behandelt werden.

Als Voraussetzung wird empfohlen, diese Artikel zu lesen, um diesen Leitfaden optimal nutzen zu können:

  1. Im Leitfaden mit Konzepten der Anrufautomatisierung werden das Programmiermodell für Aktionen und Ereignisse sowie Ereignisrückrufe beschrieben.
  2. Erfahren Sie mehr über Benutzerbezeichner wie CommunicationUserIdentifier und PhoneNumberIdentifier, die in diesem Leitfaden verwendet werden.

Für alle Codebeispiele ist client das CallAutomationClient-Objekt, das wie gezeigt erstellt werden kann, und callConnection ist das CallConnection-Objekt, das aus der Antwort oder der CreateCall-Antwort abgerufen wird. Sie können es auch aus Rückrufereignissen abrufen, die von Ihrer Anwendung empfangen wurden.

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

Ausführen eines ausgehenden Anrufs

Sie können einen 1:1- oder Gruppenanruf mit Kommunikationsbenutzer*innen oder Telefonnummern (öffentliche oder Communication Services-Nummer) tätigen. Beim Anrufen eines PSTN-Endpunkts müssen Sie auch eine Telefonnummer angeben, die als Quellanrufer-ID verwendet und in der Anrufbenachrichtigung für den PSTN-Zielendpunkt angezeigt wird. Um Communication Services-Benutzer anzurufen, müssen Sie anstelle von „PhoneNumberIdentifier“ ein CommunicationUserIdentifier-Objekt bereitstellen.

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

Wenn Sie einen Gruppenanruf tätigen, der eine Telefonnummer enthält, müssen Sie eine Telefonnummer angeben, die als Anrufer-ID-Nummer für den PSTN-Endpunkt verwendet wird.

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

Die Antwort enthält das CallConnection-Objekt, das Sie verwenden können, um weitere Aktionen für diesen Aufruf auszuführen, sobald eine Verbindung besteht. Wenn der Anruf entgegengenommen wird, werden für den Rückrufendpunkt, den Sie zuvor angegeben haben, zwei Ereignisse veröffentlicht:

  1. Das CallConnected-Ereignis ist die Benachrichtigung, dass der Anruf mit der oder dem Angerufenen eingerichtet wurde.
  2. Das ParticipantsUpdated-Ereignis enthält die aktuelle Liste der Teilnehmenden am Anruf. Sequenzdiagramm für einen ausgehenden Anruf

Falls der Anruf fehlschlägt, erhalten Sie die Ereignisse CallDisconnected und CreateCallFailed mit Fehlercodes zur weiteren Problembehandlung (weitere Informationen zu Fehlercodes der Anrufautomatisierung finden Sie auf dieser Seite).

Herstellen einer Verbindung mit einem Anruf (Vorschau)

Die Verbindungsaktion ermöglicht es Ihrem Dienst, eine Verbindung mit einem laufenden Anruf herzustellen und Aktionen dafür auszuführen. Das ist hilfreich, wenn Sie einen Raumanruf verwalten möchten oder wenn von Clientanwendungen ein 1:1-Anruf oder ein Gruppenanruf gestartet wurde, an dem die Anrufautomatisierung nicht beteiligt ist. Die Verbindung wird unter Verwendung der CallLocator-Eigenschaft hergestellt. Folgende Arten von Verbindungen sind möglich: „ServerCallLocator“, „GroupCallLocator“ und „RoomCallLocator“. Diese IDs sind bei der ursprünglichen Anrufeinrichtung oder bei der Raumerstellung verfügbar. Außerdem werden sie im Rahmen des CallStarted-Ereignisses veröffentlicht.

Wenn Sie eine Verbindung mit einem beliebigen 1:1- oder Gruppenanruf herstellen möchten, verwenden Sie das ServerCallLocator-Element. Wenn Sie einen Anruf mit „GroupCallId“ gestartet haben, können Sie auch „GroupCallLocator“ verwenden.

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

Wenn Sie eine Verbindung mit einem Raumanruf herstellen möchten, verwenden Sie „RoomCallLocator“ mit der Raum-ID (RoomId). Erfahren Sie mehr über Räume und wie die API für die Anrufautomatisierung verwendet werden kann, um laufende Raumanrufe zu verwalten.

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

Bei einer erfolgreichen Antwort wird das CallConnection-Objekt bereitgestellt, das Sie verwenden können, um weitere Aktionen für diesen Anruf auszuführen. Für den Rückrufendpunkt, den Sie zuvor angegeben haben, werden zwei Ereignisse veröffentlicht:

  1. CallConnected-Ereignis, das angibt, dass Sie erfolgreich eine Verbindung mit dem Anruf hergestellt haben.
  2. Das ParticipantsUpdated-Ereignis enthält die aktuelle Liste der Teilnehmenden am Anruf.

Wenn Ihr Dienst nach erfolgreicher Verbindungsherstellung von diesem Anruf getrennt wird, werden Sie über ein CallDisconected-Ereignis darüber informiert. Falls gar nicht erst eine Verbindung mit dem Anruf hergestellt werden konnte, tritt ein ConnectFailed-Ereignis auf.

Sequenzdiagramm: Herstellen einer Verbindung mit einem Anruf

Annehmen eines eingehenden Anrufs

Nachdem Sie den Empfang von Benachrichtigungen über eingehende Anrufe für Ihre Ressource abonniert haben, nehmen Sie einen eingehenden Anruf entgegen. Wenn Sie einen Anruf annehmen, müssen Sie eine Rückruf-URL angeben. Communication Services sendet alle nachfolgenden Ereignisse zu diesem Anruf an diese 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; 

Die Antwort enthält das CallConnection-Objekt, das Sie verwenden können, um weitere Aktionen für diesen Aufruf auszuführen, sobald eine Verbindung besteht. Wenn der Anruf entgegengenommen wird, werden für den Rückrufendpunkt, den Sie zuvor angegeben haben, zwei Ereignisse veröffentlicht:

  1. Das CallConnected-Ereignis ist die Benachrichtigung, dass der Anruf mit der oder dem Anrufer*in eingerichtet wurde.
  2. Das ParticipantsUpdated-Ereignis enthält die aktuelle Liste der Teilnehmenden am Anruf.

Sequenzdiagramm für die Beantwortung eines eingehenden Anrufs

Ablehnen eines Anrufs

Sie können einen eingehenden Anruf wie unten gezeigt ablehnen. Sie können einen Ablehnungsgrund angeben: keiner, besetzt oder gesperrt. Wenn keine Angabe erfolgt, wird standardmäßig „keiner“ ausgewählt.

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

Für Ablehnungsaktionen werden keine Ereignisse veröffentlicht.

Umleiten eines Anrufs

Sie können einen eingehenden Anruf an einen anderen Endpunkt umleiten, ohne ihn entgegenzunehmen. Wenn ein Anruf umgeleitet wird, kann er nicht mehr von Ihrer Anwendung über die Anrufautomatisierung gesteuert werden.

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

Wenn Sie den Anruf an eine Telefonnummer umleiten möchten, konstruieren Sie das Ziel und die Anrufer-ID mithilfe von „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);

Für Umleitungsaktionen werden keine Ereignisse veröffentlicht. Wenn es sich bei dem Ziel um einen Communication Services-Benutzer oder um eine Telefonnummer handelt, die Ihrer Ressource gehören, wird ein neues IncomingCall-Ereignis generiert, dessen Feld „to“ auf das von Ihnen angegebene Ziel festgelegt ist.

Durchstellen eines Anrufteilnehmers

Wenn Ihre Anwendung einen Anruf annimmt oder einen ausgehenden Anruf an einen Endpunkt tätigt, kann dieser Endpunkt an einen anderen Zielendpunkt durchgestellt werden. Wenn ein 1:1-Anruf durchgestellt wird, wird Ihre Anwendung aus dem Anruf entfernt und kann somit den Anruf nicht mehr über die Anrufautomatisierung steuern. Die Anrufeinladung für das Ziel enthält die Anrufer-ID des Endpunkts, der durchgestellt wird. Die Angabe einer benutzerdefinierten Anrufer-ID wird nicht unterstützt.

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

Wenn Ihre Anwendung einen Gruppenanruf entgegennimmt, einen ausgehenden Gruppenanruf an einen Endpunkt tätigt oder einen Teilnehmer zu einem 1:1-Anruf hinzugefügt hat, kann ein Endpunkt aus dem Anruf an einen anderen Zielendpunkt durchgestellt werden (mit Ausnahme des Endpunkts für die Anrufautomatisierung). Wenn ein Teilnehmer in einem Gruppenanruf durchgestellt wird, wird dadurch der Endpunkt entfernt, der aus dem Anruf durchgestellt wird. Die Anrufeinladung für das Ziel enthält die Anrufer-ID des Endpunkts, der durchgestellt wird. Die Angabe einer benutzerdefinierten Anrufer-ID wird nicht unterstützt.

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

Das Sequenzdiagramm zeigt den erwarteten Ablauf, wenn Ihre Anwendung einen ausgehenden Anruf tätigt und ihn dann an einen anderen Endpunkt durchstellt.

Sequenzdiagramm eines 1:1-Aufrufs mit anschließendem Durchstellen

Hinzufügen eines Teilnehmers zu einem Anruf

Sie können einem bereits vorhandenen Anruf einen Teilnehmer (Communication Services-Benutzer oder Telefonnummer) hinzufügen. Beim Hinzufügen einer Telefonnummer muss zwingend eine Anrufer-ID angegeben werden. Diese Anrufer-ID wird den hinzugefügten Teilnehmenden in der Anrufbenachrichtigung angezeigt.

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

Um Communication Services-Benutzer*innen hinzuzufügen, geben Sie anstelle von PhoneNumberIdentifier die CommunicationUserIdentifier an. In diesem Fall ist die Anrufer-ID nicht zwingend erforderlich.

„AddParticipant“ veröffentlicht ein AddParticipantSucceeded- oder AddParticipantFailed-Ereignis sowie ParticipantUpdated mit der aktuellen Teilnehmerliste des Anrufs.

Sequenzdiagramm des Hinzufügens von Teilnehmenden zu einem Anruf

Abbrechen einer Anforderung für das Hinzufügen von Teilnehmern

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

Entfernen eines Teilnehmers aus einem Anruf

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“ veröffentlicht ein RemoveParticipantSucceeded- oder RemoveParticipantFailed-Ereignis sowie ein ParticipantUpdated-Ereignis mit der aktuellen Teilnehmerliste des Anrufs. Der entfernte Teilnehmer ist in der Liste nicht enthalten.
Sequenzdiagramm des Entfernens von Teilnehmenden aus dem Anruf

Auflegen eines Anrufs

Die hangUp-Aktion (Auflegen) kann verwendet werden, um Ihre Anwendung aus dem Aufruf zu entfernen oder einen Gruppenaufruf zu beenden, indem Sie den forEveryone-Parameter auf TRUE festlegen. Bei einem 1:1-Anruf wird durch Auflegen standardmäßig der Anruf mit dem anderen Teilnehmer beendet.

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

Das CallDisconnected-Ereignis wird einmal veröffentlicht, nachdem die hangUp-Aktion erfolgreich abgeschlossen wurde.

Abrufen von Informationen zu einzelnen Anrufteilnehmenden

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

Abrufen von Informationen zu allen Anrufteilnehmenden

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

Abrufen der neuesten Informationen zu einem Anruf

CallConnectionProperties callConnectionProperties = await callConnection.GetCallConnectionPropertiesAsync();