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


Управление вызовами и управление ими с помощью службы автоматизации вызовов

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

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

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

  1. Основные понятия службы автоматизации вызовов, описывающие модель программирования действий и обратные вызовы событий.
  2. Сведения об идентификаторах пользователей, таких как CommunicationUserIdentifier и PhoneNumberIdentifier, используемых в этом руководстве.

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

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

Вызов исходящего трафика

Вы можете разместить 1:1 или групповой звонок пользователю связи или номеру телефона (общедоступному или сетевому номеру служб коммуникации). При вызове конечной точки ТСОП необходимо также указать номер телефона, который используется в качестве исходного идентификатора вызывающего абонента и показан в уведомлении о вызове в целевую конечную точку ТСОП. Чтобы разместить звонок пользователю Служб коммуникации, необходимо предоставить объект 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);

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

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

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

В случае сбоя вызова вы получите CallDisconnected и CreateCallFailed событие с кодами ошибок для дальнейшего устранения неполадок (дополнительные сведения о кодах ошибок см . на этой странице ).

Подключение к вызову

Действие подключения позволяет службе установить соединение с текущим вызовом и выполнить действия по нему. Это полезно для управления вызовом комнат или при запуске клиентских приложений вызова 1:1 или группового вызова, в результате чего автоматизация звонков не является частью. Подключение устанавливается с помощью свойства 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);

Чтобы подключиться к вызову комнаты, используйте 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, который можно использовать для дальнейших действий по этому вызову. Два события публикуются в конечной точке обратного вызова, предоставленной ранее:

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

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

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

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

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

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

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

В случае сбоя операции ответа вы получите AnswerFailed событие с кодами ошибок для дальнейшего устранения неполадок (дополнительные сведения о кодах ошибок см . на этой странице ).

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

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

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

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

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

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

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 и последующей передачи.

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

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

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

Чтобы добавить пользователя служб коммуникации, укажите 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);

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

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 событием, предоставляющим последний список участников вызова. Удаленный участник опущен из списка.
Схема последовательности для удаления участника из вызова.

Повесить на звонок

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

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