통화 자동화는 REST API 인터페이스를 사용하여 작업 요청을 받고 요청이 성공적으로 제출되었는지 여부를 알리는 응답을 제공합니다. 통화의 비동기 특성으로 인해 대부분의 작업에는 작업이 성공적으로 완료되거나 실패할 때 트리거되는 해당 이벤트가 있습니다. 이 가이드에서는 CreateCall, Transfer, Redirect 및 참가자 관리와 같이 통화를 조정하는 데 사용할 수 있는 작업에 대해 설명합니다. 작업에는 해당 작업을 호출하는 방법에 대한 샘플 코드와 작업을 호출한 후 예상되는 이벤트를 설명하는 시퀀스 다이어그램이 함께 제공됩니다. 이러한 다이어그램은 통화 자동화를 사용하여 서비스 애플리케이션을 프로그래밍하는 방법을 시각화하는 데 도움이 됩니다.
통화 자동화는 별도의 가이드가 있는 통화 미디어 및 녹음/녹화를 관리하는 다양한 다른 작업을 지원합니다.
필수 구성 요소로 이 가이드를 최대한 활용하려면 다음 문서를 참조하는 것이 좋습니다.
통화 자동화 개념 가이드 - 작업-이벤트 프로그래밍 모델 및 이벤트 콜백에 대해 설명합니다.
이 가이드에서 사용되는 사용자 식별자(예: CommunicationUserIdentifier 및 PhoneNumberIdentifier)에 대해 알아봅니다.
모든 코드 샘플에서 client는 표시된 대로 만들 수 있는 CallAutomationClient 개체이고, callConnection은 Answer 또는 CreateCall 응답에서 가져오는 CallConnection 개체입니다. 애플리케이션에서 받는 콜백 이벤트에서도 가져올 수 있습니다.
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);
String callbackUri = "https://<myendpoint>/Events"; //the callback endpoint where you want to receive subsequent events
PhoneNumberIdentifier callerIdNumber = new PhoneNumberIdentifier("+18001234567"); // This is the Azure Communication Services provisioned phone number for the caller
CallInvite callInvite = new CallInvite(new PhoneNumberIdentifier("+16471234567"), callerIdNumber); // person to call
CreateCallResult response = client.createCall(callInvite, callbackUri).block();
const callInvite = {
targetParticipant: { phoneNumber: "+18008008800" }, // person to call
sourceCallIdNumber: { phoneNumber: "+18888888888" } // This is the Azure Communication Services provisioned phone number for the caller
};
const callbackUri = "https://<myendpoint>/Events"; // the callback endpoint where you want to receive subsequent events
const response = await client.createCall(callInvite, callbackUri);
callback_uri = "https://<myendpoint>/Events" # the callback endpoint where you want to receive subsequent events
caller_id_number = PhoneNumberIdentifier(
"+18001234567"
) # This is the Azure Communication Services provisioned phone number for the caller
call_invite = CallInvite(
target=PhoneNumberIdentifier("+16471234567"),
source_caller_id_number=caller_id_number,
)
call_connection_properties = client.create_call(call_invite, callback_uri)
전화 번호가 포함된 그룹 통화를 할 때 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);
String callbackUri = "https://<myendpoint>/Events"; //the callback endpoint where you want to receive subsequent events
PhoneNumberIdentifier callerIdNumber = new PhoneNumberIdentifier("+18001234567"); // This is the Azure Communication Services provisioned phone number for the caller
List<CommunicationIdentifier> targets = new ArrayList<>(Arrays.asList(new PhoneNumberIdentifier("+16471234567"), new CommunicationUserIdentifier("<user_id_of_target>")));
CreateGroupCallOptions groupCallOptions = new CreateGroupCallOptions(targets, callbackUri);
groupCallOptions.setSourceCallIdNumber(callerIdNumber);
Response<CreateCallResult> response = client.createGroupCallWithResponse(createGroupCallOptions).block();
const callbackUri = "https://<myendpoint>/Events"; // the callback endpoint where you want to receive subsequent events
const participants = [
{ phoneNumber: "+18008008800" },
{ communicationUserId: "<user_id_of_target>" }, //user id looks like 8:a1b1c1-...
];
const createCallOptions = {
sourceCallIdNumber: { phoneNumber: "+18888888888" }, // This is the Azure Communication Services provisioned phone number for the caller
};
const response = await client.createGroupCall(participants, callbackUri, createCallOptions);
callback_uri = "https://<myendpoint>/Events" # the callback endpoint where you want to receive subsequent events
caller_id_number = PhoneNumberIdentifier(
"+18888888888"
) # This is the Azure Communication Services provisioned phone number for the caller
pstn_endpoint = PhoneNumberIdentifier("+18008008800")
voip_endpoint = CommunicationUserIdentifier(
"<user_id_of_target>"
) # user id looks like 8:a1b1c1-...
call_connection_properties = client.create_group_call(
target_participants=[voip_endpoint, pstn_endpoint],
callback_url=callback_uri,
source_caller_id_number=caller_id_number,
)
응답은 이 통화가 연결되면 추가 작업을 수행하는 데 사용할 수 있는 CallConnection 개체를 제공합니다. 통화에 응답하면 두 개의 이벤트가 이전에 제공한 콜백 엔드포인트에 게시됩니다.
수신자와의 통화가 설정되었음을 알리는 CallConnected 이벤트
통화 참가자의 최신 목록을 포함하는 ParticipantsUpdated 이벤트
호출이 실패하는 경우 추가 문제 해결을 CallDisconnected 위해 오류 코드가 포함된 이벤트 및 CreateCallFailed 메시지가 표시됩니다(오류 코드에 대한 자세한 내용은 이 페이지를 참조하세요).
통화에 연결
연결 작업을 통해 서비스는 진행 중인 통화와 연결을 설정하고 이에 대한 조치를 취할 수 있습니다. 이는 대화방 통화를 관리하거나 클라이언트 애플리케이션이 통화 자동화가 포함되지 않은 1:1 또는 그룹 통화를 시작한 경우에 유용합니다. 연결은 CallLocator 속성을 사용하여 설정되며 ServerCallLocator, GroupCallLocator 및 RoomCallLocator 형식일 수 있습니다. 이러한 ID는 통화가 처음 설정되거나 대화방이 만들어질 때 찾을 수 있으며 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);
String callbackUri = "https://<myendpoint>/Events"; //the callback endpoint where you want to receive subsequent events
CallLocator serverCallLocator = new ServerCallLocator("<ServerCallId>");
ConnectCallResult response = client.connectCall(serverCallLocator, callbackUri).block();
const callbackUri = "https://<myendpoint>/Events"; // the callback endpoint where you want to receive subsequent events
const serverCallLocator = { kind: "serverCallLocator", id: "<serverCallId>" };
const response = await client.connectCall(serverCallLocator, callbackUri);
callback_uri = "https://<myendpoint>/Events" # the callback endpoint where you want to receive subsequent events
server_call_locator = ServerCallLocator("<server_call_id>")
call_connection_properties = client.connect_call(call_locator=server_call_locator, callback_url=callback_uri)
대화방 통화에 연결하려면 RoomId를 사용하는 RoomCallLocator를 사용합니다. Rooms에 대해 자세히 알아보고 통화 자동화 API를 사용하여 진행 중인 Rooms 통화를 관리하는 방법을 알아봅니다.
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);
String callbackUri = "https://<myendpoint>/Events"; //the callback endpoint where you want to receive subsequent events
CallLocator roomCallLocator = new RoomCallLocator("<RoomId>");
ConnectCallResult response = client.connectCall(roomCallLocator, callbackUri).block();
const roomCallLocator = { kind: "roomCallLocator", id: "<RoomId>" };
const callbackUri = "https://<myendpoint>/Events"; // the callback endpoint where you want to receive subsequent events
const response = await client.connectCall(roomCallLocator, callbackUri);
callback_uri = "https://<myendpoint>/Events" # the callback endpoint where you want to receive subsequent events
room_call_locator = RoomCallLocator("<room_id>")
call_connection_properties = client.connect_call(call_locator=room_call_locator, callback_url=callback_uri)
성공적인 응답은 이 호출에 대한 추가 작업을 수행하는 데 사용할 수 있는 CallConnection 개체를 제공합니다. 이전에 제공한 콜백 엔드포인트에 두 가지 이벤트가 게시됩니다.
통화에 성공적으로 연결되었음을 알리는 CallConnected 이벤트입니다.
통화 참가자의 최신 목록을 포함하는 ParticipantsUpdated 이벤트
연결이 성공한 후 언제든지 이 호출에서 서비스 연결이 끊어지면 CallDisconected 이벤트를 통해 알림을 받게 됩니다. 처음에 통화 연결에 실패하면 ConnectFailed 이벤트가 발생합니다.
수신 전화 응답
리소스에 대한 수신 전화 알림을 받도록 구독하면 수신 전화에 응답하게 됩니다. 통화에 응답할 때 콜백 URL을 제공해야 합니다. Communication Services는 이 통화에 대한 모든 후속 이벤트를 해당 URL에 게시합니다.
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);
String incomingCallContext = "<IncomingCallContext_From_IncomingCall_Event>";
CallInvite target = new CallInvite(new CommunicationUserIdentifier("<user_id_of_target>")); //user id looks like 8:a1b1c1-...
RedirectCallOptions redirectCallOptions = new RedirectCallOptions(incomingCallContext, target);
Response<Void> response = client.redirectCallWithResponse(redirectCallOptions).block();
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);
PhoneNumberIdentifier callerIdNumber = new PhoneNumberIdentifier("+16044561234"); // This is the Azure Communication Services provisioned phone number for the caller
CallInvite target = new CallInvite(new PhoneNumberIdentifier("+18001234567"), callerIdNumber);
caller_id_number = PhoneNumberIdentifier(
"+18888888888"
) # This is the Azure Communication Services provisioned phone number for the caller
call_invite = CallInvite(
target=PhoneNumberIdentifier("+16471234567"),
source_caller_id_number=caller_id_number,
)
리디렉션에 대한 이벤트가 게시되지 않습니다. 대상이 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);
CommunicationIdentifier transferDestination = new CommunicationUserIdentifier("<user_id>");
TransferCallToParticipantOptions options = new TransferCallToParticipantOptions(transferDestination)
.setOperationContext("<operation_context>")
.setOperationCallbackUrl("<url_endpoint>"); // Sending event to a non-default endpoint.
// set customCallingContext
options.getCustomCallingContext().addVoip("voipHeaderName", "voipHeaderValue");
Response<TransferCallResult> transferResponse = callConnectionAsync.transferToParticipantCallWithResponse(options).block();
애플리케이션이 그룹 통화에 응답하거나 엔드포인트에 아웃바운드 그룹 통화를 수행하거나 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);
// Transfer User
CommunicationIdentifier transferDestination = new CommunicationUserIdentifier("<user_id>");
CommunicationIdentifier transferee = new CommunicationUserIdentifier("<transferee_user_id>");
TransferCallToParticipantOptions options = new TransferCallToParticipantOptions(transferDestination);
options.setTransferee(transferee);
options.setOperationContext("<Your_context>");
options.setOperationCallbackUrl("<url_endpoint>");
// set customCallingContext
options.getCustomCallingContext().addVoip("voipHeaderName", "voipHeaderValue");
Response<TransferCallResult> transferResponse = callConnectionAsync.transferToParticipantCallWithResponse(options).block();
// Transfer Pstn User
CommunicationIdentifier transferDestination = new PhoneNumberIdentifier("<taget_phoneNumber>");
CommunicationIdentifier transferee = new PhoneNumberIdentifier("<transferee_phoneNumber>");
TransferCallToParticipantOptions options = new TransferCallToParticipantOptions(transferDestination);
options.setTransferee(transferee);
options.setOperationContext("<Your_context>");
options.setOperationCallbackUrl("<url_endpoint>");
// set customCallingContext
options.getCustomCallingContext().addSipUui("UUIvalue");
options.getCustomCallingContext().addSipX("sipHeaderName", "value");
Response<TransferCallResult> transferResponse = callConnectionAsync.transferToParticipantCallWithResponse(options).block();
// 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);
// Add user
CallInvite callInvite = new CallInvite(new CommunicationUserIdentifier("<user_id>"));
// add custom calling context
callInvite.getCustomCallingContext().addVoip("voipHeaderName", "voipHeaderValue");
AddParticipantOptions addParticipantOptions = new AddParticipantOptions(callInvite)
.setOperationContext("<operation_context>")
.setOperationCallbackUrl("<url_endpoint>");
Response<AddParticipantResult> addParticipantResultResponse = callConnectionAsync.addParticipantWithResponse(addParticipantOptions).block();
// Add PSTN user
PhoneNumberIdentifier callerIdNumber = new PhoneNumberIdentifier("+16044561234"); // This is the Azure Communication Services provisioned phone number for the caller
CallInvite callInvite = new CallInvite(new PhoneNumberIdentifier("+16041234567"), callerIdNumber);
// add custom calling context
callInvite.getCustomCallingContext().addSipUui("value");
callInvite.getCustomCallingContext().addSipX("header1", "customSipHeaderValue1");
AddParticipantOptions addParticipantOptions = new AddParticipantOptions(callInvite)
.setOperationContext("<operation_context>")
.setOperationCallbackUrl("<url_endpoint>");
Response<AddParticipantResult> addParticipantResultResponse = callConnectionAsync.addParticipantWithResponse(addParticipantOptions).block();
// 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);
// Add user
CallInvite callInvite = new CallInvite(new CommunicationUserIdentifier("<user_id>"));
AddParticipantOperationOptions addParticipantOperationOptions = new AddParticipantOptions(callInvite);
Response<AddParticipantResult> addParticipantOperationResultResponse = callConnectionAsync.addParticipantWithResponse(addParticipantOptions).block();
// cancel the request
CancelAddParticipantOperationOptions cancelAddParticipantOperationOptions = new CancelAddParticipantOperationOptions(addParticipantResultResponse.invitationId)
.setOperationContext("<operation_context>")
.setOperationCallbackUrl("<url_endpoint>");
callConnectionAsync.cancelAddParticipantOperationWithResponse(cancelAddParticipantOperationOptions).block();
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);
CommunicationIdentifier removeThisUser = new CommunicationUserIdentifier("<user_id>");
RemoveParticipantOptions removeParticipantOptions = new RemoveParticipantOptions(removeThisUser)
.setOperationContext("<operation_context>")
.setOperationCallbackUrl("<url_endpoint>");
Response<RemoveParticipantResult> removeParticipantResultResponse = callConnectionAsync.removeParticipantWithResponse(removeParticipantOptions).block();