통화 자동화를 사용하여 통화를 제어하고 조정하는 방법

통화 자동화는 REST API 인터페이스를 사용하여 작업 요청을 받고 요청이 성공적으로 제출되었는지 여부를 알리는 응답을 제공합니다. 통화의 비동기 특성으로 인해 대부분의 작업에는 작업이 성공적으로 완료되거나 실패할 때 트리거되는 해당 이벤트가 있습니다. 이 가이드에서는 CreateCall, Transfer, Redirect 및 참가자 관리와 같이 통화를 조정하는 데 사용할 수 있는 작업에 대해 설명합니다. 작업에는 해당 작업을 호출하는 방법에 대한 샘플 코드와 작업을 호출한 후 예상되는 이벤트를 설명하는 시퀀스 다이어그램이 함께 제공됩니다. 이러한 다이어그램은 통화 자동화를 사용하여 서비스 애플리케이션을 프로그래밍하는 방법을 시각화하는 데 도움이 됩니다.

통화 자동화는 별도의 가이드가 있는 통화 미디어 및 녹음/녹화를 관리하는 다양한 다른 작업을 지원합니다.

참고 항목

통화 자동화는 현재 통화를 지원하지 않습니다.

필수 구성 요소로 이 가이드를 최대한 활용하려면 다음 문서를 참조하는 것이 좋습니다.

  1. 통화 자동화 개념 가이드 - 작업-이벤트 프로그래밍 모델 및 이벤트 콜백에 대해 설명합니다.
  2. 이 가이드에서 사용되는 사용자 식별자(예: CommunicationUserIdentifier 및 PhoneNumberIdentifier)에 대해 알아봅니다.

모든 코드 샘플에서 client는 표시된 대로 만들 수 있는 CallAutomationClient 개체이고, callConnection은 Answer 또는 CreateCall 응답에서 가져오는 CallConnection 개체입니다. 애플리케이션에서 받는 콜백 이벤트에서도 가져올 수 있습니다.

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

아웃바운드 통화 수행

1:1 또는 그룹 통화를 통신 사용자 또는 전화 번호(공용 번호 또는 Communication Services 소유 번호)로 수행할 수 있습니다. 통화를 PSTN 엔드포인트로 수행하는 경우 원본 발신자 ID로 사용되고 대상 PSTN 엔드포인트에 대한 통화 알림에 표시되는 전화 번호도 제공해야 합니다. Communication Services 사용자에게 전화를 걸려면 PhoneNumberIdentifier 대신 CommunicationUserIdentifier 개체를 제공해야 합니다.

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 엔드포인트에 발신자 ID 번호로 사용되는 전화 번호를 제공해야 합니다.

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 이벤트 Sequence diagram for placing an outbound call.

수신 전화 응답

리소스에 대한 수신 전화 알림을 받도록 구독하면 수신 전화에 응답하게 됩니다. 통화에 응답할 때 콜백 URL을 제공해야 합니다. Communication Services는 이 통화에 대한 모든 후속 이벤트를 해당 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 이벤트

Sequence diagram for answering an incoming call.

통화 거부

아래와 같이 착신 통화를 거부하도록 선택할 수 있습니다. 거부 이유(없음, 통화 중 또는 금지됨)를 제공할 수 있습니다. 아무것도 제공되지 않으면 기본적으로 '없음'이 선택됩니다.

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를 사용하여 대상 및 발신자 ID를 구성합니다.

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

리디렉션에 대한 이벤트가 게시되지 않습니다. 대상이 Communication Services 사용자이거나 리소스가 소유한 전화 번호인 경우 지정한 대상으로 설정된 'to' 필드가 있는 새 IncomingCall 이벤트를 생성합니다.

통화 중인 참가자 전송

애플리케이션에서 통화에 응답하거나 아웃바운드 통화를 엔드포인트로 수행하면 해당 엔드포인트를 다른 대상 엔드포인트로 전환할 수 있습니다. 1:1 통화를 전송하면 통화에서 애플리케이션이 제거되므로 통화 자동화를 사용하여 통화를 제어하는 기능이 제거됩니다. 대상에 대한 통화 초대에는 전송 중인 엔드포인트의 발신자 ID가 표시됩니다. 사용자 지정 발신자 ID를 제공하는 것은 지원되지 않습니다.

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 통화에 참가자를 추가하면 통화 자동화 엔드포인트를 제외하고 엔드포인트를 통화에서 다른 대상 엔드포인트로 전송할 수 있습니다. 그룹 통화에서 참가자를 전환하면 통화에서 전환 중인 엔드포인트가 제거됩니다. 대상에 대한 통화 초대에는 전송 중인 엔드포인트의 발신자 ID가 표시됩니다. 사용자 지정 발신자 ID를 제공하는 것은 지원되지 않습니다.

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

시퀀스 다이어그램에서는 애플리케이션에서 아웃바운드 통화를 수행한 다음, 다른 엔드포인트로 전송하는 경우 예상되는 흐름을 보여줍니다.

Sequence diagram for placing a 1:1 call and then transferring it.

통화에 참가자 추가

참가자(Communication Services 사용자 또는 전화 번호)를 기존 통화에 추가할 수 있습니다. 전화 번호를 추가하는 경우 발시자 ID를 제공해야 합니다. 이 발신자 ID는 추가되는 참가자에 대한 통화 알림에 표시됩니다.

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

Communication Services 사용자를 추가하려면 PhoneNumberIdentifier 대신 CommunicationUserIdentifier를 제공합니다. 이 경우 발신자 ID는 필수가 아닙니다.

AddParticipant는 통화 참가자의 최신 목록을 제공하는 ParticipantUpdated와 함께 AddParticipantSucceeded 또는 AddParticipantFailed 이벤트를 게시합니다.

Sequence diagram for adding a participant to the call.

참가자 추가 요청 취소

// 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는 통화 참가자의 최신 목록을 제공하는 ParticipantUpdated와 함께 RemoveParticipantSucceeded 또는 RemoveParticipantFailed 이벤트를 게시합니다. 제거된 참가자는 목록에서 생략됩니다.
Sequence diagram for removing a participant from the call.

통화에서 전화 끊기

전화 끊기 작업은 통화에서 애플리케이션을 제거하거나 forEveryone 매개 변수를 true로 설정하여 그룹 통화를 종료하는 데 사용할 수 있습니다. 1:1 통화의 경우 전화를 끊으면 기본적으로 상대방과의 통화가 종료됩니다.

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

hangUp 작업이 성공적으로 완료되면 CallDisconnected 이벤트가 게시됩니다.

통화 참가자에 대한 정보 가져오기

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

모든 통화 참가자에 대한 정보 가져오기

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

통화에 대한 최신 정보 가져오기

CallConnectionProperties callConnectionProperties = await callConnection.GetCallConnectionPropertiesAsync();