Поделиться через


Управляйте и направляйте вызовы с помощью автоматизации вызовов

Служба автоматизации вызовов использует интерфейс REST API для получения запросов на действия и предоставления ответов, чтобы сообщить, был ли запрос успешно отправлен или нет. Из-за асинхронного характера вызова большинство действий имеют соответствующие события, которые активируются при успешном завершении или сбое действия. В этой статье рассматриваются действия, доступные для направления вызовов, таких как CreateCall, Transfer и Redirect, а также управление участниками. Пример кода показывает, как вызвать конкретное действие. Схемы последовательностей описывают события, ожидаемые после вызова действия. Схемы помогают визуализировать программирование приложения-службы с помощью автоматизации вызовов.

Автоматизация вызовов поддерживает другие действия для управления медиа вызова и записью, которые имеют отдельные статьи.

Prerequisites

Для всех примеров кода объект client, который можно создать, как показано. Кроме того, callConnection — это CallConnection объект, который вы получаете из Answer или CreateCall ответа. Вы также можете получить его из событий обратного вызова, получаемых приложением.

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

Совершить исходящий звонок

Вы можете осуществить 1:1 или групповой звонок пользователю или на номер телефона (общедоступному номеру или номеру, который принадлежит службе Azure Communication Services). При вызове конечной точки общедоступной телефонной сети (ТСОП) необходимо также указать номер телефона, который будет использоваться в качестве исходного идентификатора абонента и который отображается как уведомление о вызове в целевую конечную точку ТСОП.

Чтобы совершить вызов пользователю Служб коммуникации Azure, необходимо предоставить CommunicationUserIdentifier объект вместо 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);

При выполнении группового звонка, включающего номер телефона, необходимо указать номер телефона для использования в качестве идентификации вызывающего абонента для узла сети PSTN.

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

Ответ предоставляет CallConnection объект, который можно использовать для дальнейших действий по этому вызову после подключения. После ответа на вызов два события публикуются в конечной точке обратного вызова, предоставленной ранее:

  • CallConnected: уведомляет о том, что вызов был установлен с вызывающим абонентом.

  • ParticipantsUpdated: содержит последний список участников на звонке.

    Схема, показывающая последовательность для осуществления исходящего вызова.

Если вызов завершается сбоем, вы получаете событие CallDisconnected и событие CreateCallFailed, оба с кодами ошибок для дальнейшего устранения неполадок. Дополнительные сведения о кодах ошибок см. в разделе "Устранение неполадок кодов ответа на вызов".

Подключитесь к вызову

Действие подключения позволяет службе установить соединение с текущим вызовом и выполнить действия по нему. Эта функция полезна для управления вызовом в комнатах или когда клиентские приложения инициируют вызов один на один или групповой вызов, где автоматизация вызовов не используется. Используйте свойство CallLocator для установления подключения. Параметры типа: ServerCallLocator, GroupCallLocatorи RoomCallLocator. Эти идентификаторы можно найти при первоначальном создании вызова или комнаты, а также они могут быть опубликованы в рамках события CallStarted.

Чтобы подключиться к любому вызову 1:1 или групповому вызову, используйте ServerCallLocator. Если вы использовали GroupCallId для запуска вызова, можно также использовать 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);

Чтобы подключиться на звонок в Rooms, используйте RoomCallLocator, который принимает RoomId. Узнайте больше о комнатах и о том, как использовать API автоматизации звонков для управления текущим звонком в комнатах.

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

Успешный CallConnection ответ предоставляет объект, который можно использовать для дальнейших действий по этому вызову. На указанный вами ранее адрес обратного вызова публикуются два события.

  • CallConnected: уведомляет об успешном подключении к вызову.
  • ParticipantsUpdated: содержит последний список участников на звонке.

В любой момент после успешного подключения, если ваша служба отключится от этого вызова, событие CallDisconnected уведомит вас. Сбой подключения к вызову на начальном этапе приводит к событию ConnectFailed.

Схема, показывющая последовательность подключения к вызову.

Ответ на входящий вызов

После подписки на получение входящих уведомлений о звонках в ресурс можно ответить на входящий звонок. При ответе на звонок необходимо указать URL-адрес обратного вызова. Службы связи Azure публикуют все последующие события об этом вызове по указанному 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; 

Ответ предоставляет CallConnection объект, который можно использовать для дальнейших действий по этому вызову после подключения. После ответа на вызов два события публикуются в конечной точке обратного вызова, предоставленной ранее:

  • CallConnected: уведомляет о том, что вызов был установлен с вызывающим абонентом.
  • ParticipantsUpdated: содержит последний список участников на звонке.

Схема, показывющая последовательность для ответа на входящий вызов.

Если операция ответа завершается ошибкой AnswerFailed , вы получите событие с кодами ошибок для дальнейшего устранения неполадок. Дополнительные сведения о кодах ошибок см. в разделе "Устранение неполадок кодов ответа на вызов".

Отклонение вызова

Вы можете отклонить входящий звонок. Причины отказа : NoneBusyили Forbidden. Если ничего не указано, используется Noneзначение по умолчанию.

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

События не публикуются для действия «отклонение».

Перенаправление вызова

Вы можете перенаправить входящий вызов на другую конечную точку, не отвечая на нее. Перенаправление вызова удаляет возможность приложения управлять вызовом с помощью службы автоматизации вызовов.

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

Чтобы перенаправить звонок на номер телефона, создайте целевой идентификатор и идентификатор вызывающего абонента с помощью 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);

События не публикуются для перенаправления. Если целевой объект является пользователем Служб коммуникации Azure или номером телефона, принадлежащим вашему ресурсу, он создает новое IncomingCall событие с to заданным полем для указанного целевого объекта.

Перевод участника на другой вызов

Когда приложение отвечает на вызов или помещает исходящий вызов в конечную точку, приложение может перенести конечную точку в другую конечную точку назначения. При переводе вызова 1:1 ваше приложение выводится из вызова и теряет возможность управления вызовом с помощью Call Automation. Приглашение на вызов в целевой объект показывает идентификатор вызывающего объекта конечной точки, передаваемой. Предоставление пользовательского идентификатора вызывающего объекта не поддерживается.

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

Когда приложение отвечает на групповой вызов, помещает исходящий групповой вызов в конечную точку или добавляет участника в вызов 1:1, приложение может перенести конечную точку из вызова в другую конечную точку назначения, за исключением конечной точки службы автоматизации вызовов. При передаче участника в групповом вызове соответствующий участник удаляется из вызова. Приглашение на вызов в целевой объект показывает идентификатор вызывающего объекта конечной точки, передаваемой. Предоставление пользовательского идентификатора вызывающего объекта не поддерживается.

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

На схеме последовательности показан ожидаемый поток, когда приложение помещает исходящий вызов, а затем передает его в другую конечную точку.

Схема, показывающая последовательность для осуществления вызова 1:1 и затем его передачи.

Добавьте участника в вызов

Вы можете добавить участника, например пользователя Служб коммуникации Azure или номер телефона в существующий звонок. При добавлении номера телефона необходимо указать идентификатор абонента. Этот идентификатор вызывающего абонента отображается в уведомлении о вызове для добавленного участника.

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

Чтобы добавить пользователя Служб коммуникации Azure, укажите CommunicationUserIdentifier вместо PhoneNumberIdentifier. В этом случае идентификатор вызывающего абонента не является обязательным.

AddParticipant затем публикует событие AddParticipantSucceeded или AddParticipantFailed, а также ParticipantUpdated, предоставляющее последний список участников звонка.

Схема, показывающая последовательность добавления участника в вызов.

Отмена запроса на добавление участника

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

Перемещение участника на вызов из другого вызова

С помощью пакета SDK автоматизации вызовов Служб коммуникации Azure можно переместить участника из одного текущего вызова в другой с помощью API MoveParticipants. Это обеспечивает динамическую маршрутизацию и гибкую оркестрацию вызовов— распространенные в сценариях, таких как перемещение переводчика в звонок врача-пациента или передача клиента из вызова лобби в активный звонок в службу поддержки.

Примеры сценариев:

  • Врач + Маршрутизация комнат переводчика — перемещение отдельных переводчиков в основной вызов.

  • Передача звонков в лобби — удерживайте участников в отдельном вызове, пока не утверждено присоединиться к основному вызову.

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

// CallConnectionId for the call that you want to move the participant from
var fromCallId = "<callConnectionId>";

// Move a participant from another call to current call with optional parameters
var moveParticipantsOptions = new MoveParticipantOptions(
    new List<CommunicationIdentifier> { targetParticipant }, 
    fromCallId)
{
    OperationContext = "operationContext",
    OperationCallbackUri = new Uri("uri_endpoint") // Sending event to a non-default endpoint.
};

MoveParticipantsResult result = await callConnection.MoveParticipantsAsync(moveParticipantsOptions);

MoveParticipants публикует событие MoveParticipantSucceeded или MoveParticipantFaileded в целевом вызове.

Удаление участника из вызова

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 публикует событие RemoveParticipantSucceeded или RemoveParticipantFailed, а также событие ParticipantUpdated, который содержит последний список участников в звонке. Удаленный участник опущен из списка.

Схема, показывающая последовательность удаления участника из вызова.

Завершить звонок

Вы можете использовать действие hangUp для удаления вашего приложения из вызова или завершения группового вызова, задав для параметра forEveryone значение true. Для вызова 1:1 hangUp по умолчанию завершает звонок с другим участником.

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

Событие CallDisconnected публикуется после успешного hangUp завершения действия.

Получение сведений об участнике вызова

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

Получение сведений обо всех участниках вызова

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

Получение последних сведений о вызове

CallConnectionProperties callConnectionProperties = await callConnection.GetCallConnectionPropertiesAsync();