Call Automation を使用して通話を制御および操作する方法

Call Automation は、REST API インターフェイスを使用してアクションの要求を受信し、要求が正常に送信されたかどうかを通知する応答を提供するものです。 通話の非同期性のため、ほとんどのアクションには、アクションが正常に完了または失敗したときにトリガーされる、対応するイベントがあります。 このガイドでは、CreateCall、転送、リダイレクト、参加者の管理など、通話の操作に使用できるアクションについて説明します。 アクションには、そのアクションを呼び出す方法を示すサンプル コードと、アクション呼び出し後に予期されるイベントを記述したシーケンス図が付属しています。 これらの図は、Call Automation を使用してサービス アプリケーションをプログラミングする方法を視覚化するのに役立ちます。

Call Automation では、別のガイドがある通話メディアと記録を管理するための他のさまざまなアクションがサポートされています。

Note

Call Automation では現在、ルーム通話はサポートされていません。

このガイドを最大限に活用するには、前提条件として次の記事を参照することをお勧めします。

  1. Call Automation の概念ガイドでは、アクション イベント プログラミング モデルとイベント コールバックについて説明しています。
  2. このガイドで使用している CommunicationUserIdentifier や PhoneNumberIdentifier などのユーザー識別子についての説明。

すべてのコード サンプルについて、client は示されている方法で作成できる CallAutomationClient オブジェクトであり、callConnection は、Answer または CreateCall 応答から取得される CallConnection オブジェクトです。 アプリケーションで受信するコールバック イベントから取得することもできます。

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

発信通話を実行する

コミュニケーション ユーザーまたは電話番号 (パブリックまたは 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 オブジェクトが提供されます。このオブジェクトを使用して、接続後にこの呼び出しに対してさらにアクションを実行できます。 通話に応答があると、前に指定したコールバック エンドポイントに 2 つのイベントが発行されます。

  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 オブジェクトが提供されます。このオブジェクトを使用して、接続後にこの呼び出しに対してさらにアクションを実行できます。 通話に応答があると、前に指定したコールバック エンドポイントに 2 つのイベントが発行されます。

  1. 呼び出し元との通話が確立されたことを通知する CallConnected イベント。
  2. 通話参加者の最新リストを含む ParticipantsUpdated イベント。

Sequence diagram for answering an incoming call.

通話を拒否する

次に示すように、着信を拒否することを選択できます。 拒否の理由として、none、busy、または forbidden を指定できます。 何も指定しない場合、既定では none が選択されます。

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

拒否アクションのイベントは発行されません。

通話をリダイレクトする

着信に応答せずに別のエンドポイントにリダイレクトすることを選択できます。 通話をリダイレクトすると、アプリケーションで Call Automation を使用して通話を制御することはできなくなります。

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 イベントが生成されます。

通話中に参加者を転送する

アプリケーションで通話に応答するか、エンドポイントに発信通話を行った場合、そのエンドポイントを別の宛先エンドポイントに転送できます。 一対一の通話を転送すると、アプリケーションは通話から削除されるため、Call Automation を使用して通話を制御できなくなります。 ターゲットへの通話の招待には、転送されるエンドポイントの発信者 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 を使用すると、AddParticipantSucceeded または AddParticipantFailed イベントが、通話参加者の最新リストを提供する ParticipantUpdated と共に発行されます。

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 を使用すると、RemoveParticipantSucceeded または RemoveParticipantFailed イベントが、通話参加者の最新リストを提供する ParticipantUpdated イベントと共に発行されます。 削除された参加者はリストから省略されます。
Sequence diagram for removing a participant from the call.

通話を切断する

切断アクションを使用すると、アプリケーションを通話から削除したり、forEveryone パラメーターを true に設定してグループ通話を終了したりできます。 一対一の通話の場合、通話を切断すると、既定により、もう一方の参加者との通話が終了します。

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