クイック スタート: Call Automation を使用して発信通話を行う

Azure Communication Services Call Automation API は、対話型の通話エクスペリエンスを作成するための強力な方法です。 このクイック スタートでは、発信通話を行い、通話のさまざまなイベントを認識する方法について説明します。

前提条件

サンプル コード

GitHub からクイックスタート サンプル コードをダウンロードまたは複製します。

CallAutomation_OutboundCalling フォルダーに移動し、コード エディターでソリューションを開きます。

Azure DevTunnel をセットアップしてホストする

Azure DevTunnels は、インターネット上でホストされているローカル Web サービスを共有可能にする Azure サービスです。 コマンドを実行して、ローカル開発環境をパブリック インターネットに接続します。 DevTunnels は、匿名アクセスが可能な永続的なエンドポイント URL を作成します。 このエンドポイントを使用して、Azure Communication Services Call Automation サービスからアプリケーションに通話イベントを通知します。

devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host

または、指示に従い、Visual Studio で Azure DevTunnel を設定します

アプリケーションの構成を更新する

次に、次の値を使用して Program.cs ファイルを更新します。

  • acsConnectionString: Azure Communications Service リソースの接続文字列。 Azure Communication Services 接続文字列は、こちらの手順を使用して確認できます。
  • callbackUriHost: DevTunnel ホストを初期化したら、その URI でこのフィールドを更新します。
  • acsPhonenumber: 取得した Azure Communication Services の電話番号でこのフィールドを更新します。 この電話番号では E164 電話番号形式を使用する必要があります (例: +18881234567)
  • targetPhonenumber: アプリケーションが使用する発信先の電話番号でフィールドを更新します。 この電話番号では E164 電話番号形式を使用する必要があります (例: +18881234567)
  • cognitiveServiceEndpoint: Azure AI サービス エンドポイントでフィールドを更新します。
  • targetTeamsUserId: (省略可能) 通話に追加する Microsoft Teams ユーザー ID でフィールドを更新します。 Graph API を使用した Teams ユーザー ID の取得に関するページを参照してください。
// Your ACS resource connection string 
var acsConnectionString = "<ACS_CONNECTION_STRING>"; 

// Your ACS resource phone number will act as source number to start outbound call 
var acsPhonenumber = "<ACS_PHONE_NUMBER>"; 
 
// Target phone number you want to receive the call. 
var targetPhonenumber = "<TARGET_PHONE_NUMBER>";

// Base url of the app 
var callbackUriHost = "<CALLBACK_URI_HOST_WITH_PROTOCOL>"; 

// Your cognitive service endpoint 
var cognitiveServiceEndpoint = "<COGNITIVE_SERVICE_ENDPOINT>";

// (Optional) User Id of the target teams user you want to receive the call.
var targetTeamsUserId = "<TARGET_TEAMS_USER_ID>";

発信通話を実行する

Azure Communication Services から発信通話を行うために、このサンプルでは、アプリケーションで以前に定義した targetPhonenumber を使用し、CreateCallAsync API を使用して通話を作成します。 このコードでは、発信先の電話番号を使用して発信通話を行います。

PhoneNumberIdentifier target = new PhoneNumberIdentifier(targetPhonenumber);
PhoneNumberIdentifier caller = new PhoneNumberIdentifier(acsPhonenumber);
var callbackUri = new Uri(callbackUriHost + "/api/callbacks");
CallInvite callInvite = new CallInvite(target, caller);
var createCallOptions = new CreateCallOptions(callInvite, callbackUri) {
  CallIntelligenceOptions = new CallIntelligenceOptions() {
    CognitiveServicesEndpoint = new Uri(cognitiveServiceEndpoint)
  }
};
CreateCallResult createCallResult = await callAutomationClient.CreateCallAsync(createCallOptions);

通話自動化イベントを処理する

このアプリケーションでは、前半で callbackUriHost を Call Automation Service に登録しました。 発生する通話イベントをサービスが通知するために必要なエンドポイントをホストが示します。 次に、イベントを反復処理して、アプリケーションが解釈する必要のある特定のイベントを検出することができます。 次のコードでは、CallConnected イベントに応答します。

app.MapPost("/api/callbacks", async (CloudEvent[] cloudEvents, ILogger < Program > logger) => {
  foreach(var cloudEvent in cloudEvents) {
    logger.LogInformation($"Event received: {JsonConvert.SerializeObject(cloudEvent)}");
    CallAutomationEventBase parsedEvent = CallAutomationEventParser.Parse(cloudEvent);
    logger.LogInformation($"{parsedEvent?.GetType().Name} parsedEvent received for call connection id: {parsedEvent?.CallConnectionId}");
    var callConnection = callAutomationClient.GetCallConnection(parsedEvent.CallConnectionId);
    var callMedia = callConnection.GetCallMedia();
    if (parsedEvent is CallConnected) {
      //Handle Call Connected Event
    }
  }
});

(省略可能) 通話に Microsoft Teams ユーザーを追加する

AddParticipantAsync メソッドで MicrosoftTeamsUserIdentifier と Teams ユーザーの ID を使用して、Microsoft Teams ユーザーを通話に追加できます。まず、事前に必要な手順「Microsoft Teams ユーザーへの通話を可能にするための Azure Communication Services リソースの認可」を実行する必要があります。 必要に応じて、SourceDisplayName を渡して Teams ユーザーのトースト通知に表示されるテキストを制御することもできます。

await callConnection.AddParticipantAsync(
    new CallInvite(new MicrosoftTeamsUserIdentifier(targetTeamsUserId))
    {
        SourceDisplayName = "Jack (Contoso Tech Support)"
    });

通話の記録を開始する

Call Automation サービスを使用すると、音声通話とビデオ通話の記録を開始して保存することもできます。 Call Recording API のさまざまな機能の詳細については、こちらを参照してください。

CallLocator callLocator = new ServerCallLocator(parsedEvent.ServerCallId);
var recordingResult = await callAutomationClient.GetCallRecording().StartAsync(new StartRecordingOptions(callLocator));
recordingId = recordingResult.Value.RecordingId;

ウェルカム メッセージを再生して認識する

TextSource を使用すると、合成してウェルカム メッセージに使用するテキストをサービスに提供できます。 CallConnected イベントが発生すると、Azure Communication Services Call Automation サービスによってこのメッセージが再生されます。

次に、テキストを CallMediaRecognizeChoiceOptions に渡して、StartRecognizingAsync を呼び出します。 これにより、呼び出し元が選択したオプションをアプリケーションで認識できるようになります。

if (parsedEvent is CallConnected callConnected) {
  logger.LogInformation($"Start Recording...");
  CallLocator callLocator = new ServerCallLocator(parsedEvent.ServerCallId);
  var recordingResult = await callAutomationClient.GetCallRecording().StartAsync(new StartRecordingOptions(callLocator));
  recordingId = recordingResult.Value.RecordingId;

  var choices = GetChoices();

  // prepare recognize tones 
  var recognizeOptions = GetMediaRecognizeChoiceOptions(mainMenu, targetPhonenumber, choices);

  // Send request to recognize tones 
  await callMedia.StartRecognizingAsync(recognizeOptions);
}

CallMediaRecognizeChoiceOptions GetMediaRecognizeChoiceOptions(string content, string targetParticipant, List < RecognitionChoice > choices, string context = "") {
  var playSource = new TextSource(content) {
    VoiceName = SpeechToTextVoice
  };

  var recognizeOptions = new CallMediaRecognizeChoiceOptions(targetParticipant: new PhoneNumberIdentifier(targetParticipant), choices) {
    InterruptCallMediaOperation = false,
      InterruptPrompt = false,
      InitialSilenceTimeout = TimeSpan.FromSeconds(10),
      Prompt = playSource,
      OperationContext = context
  };
  return recognizeOptions;
}

List < RecognitionChoice > GetChoices() {
  return new List < RecognitionChoice > {
    new RecognitionChoice("Confirm", new List < string > {
      "Confirm",
      "First",
      "One"
    }) {
      Tone = DtmfTone.One
    },
    new RecognitionChoice("Cancel", new List < string > {
      "Cancel",
      "Second",
      "Two"
    }) {
      Tone = DtmfTone.Two
    }
  };
}

選択イベントの処理

Azure Communication Services Call Automation はセットアップした Webhook に api/callbacks をトリガーし、RecognizeCompleted イベントが通知されます。 このイベントは、受信した入力に応答して、アクションをトリガーする機能を提供します。 アプリケーションは、受信した特定の入力に基づいて呼び出し元にメッセージを再生します。

if (parsedEvent is RecognizeCompleted recognizeCompleted) {
  var choiceResult = recognizeCompleted.RecognizeResult as ChoiceResult;
  var labelDetected = choiceResult?.Label;
  var phraseDetected = choiceResult?.RecognizedPhrase;

  // If choice is detected by phrase, choiceResult.RecognizedPhrase will have the phrase detected,  
  // If choice is detected using dtmf tone, phrase will be null  
  logger.LogInformation("Recognize completed succesfully, labelDetected={labelDetected}, phraseDetected={phraseDetected}", labelDetected, phraseDetected);

  var textToPlay = labelDetected.Equals(ConfirmChoiceLabel, StringComparison.OrdinalIgnoreCase) ? ConfirmedText : CancelText;

  await HandlePlayAsync(callMedia, textToPlay);
}

async Task HandlePlayAsync(CallMedia callConnectionMedia, string text) {
  // Play goodbye message 
  var GoodbyePlaySource = new TextSource(text) {
    VoiceName = "en-US-NancyNeural"
  };
  await callConnectionMedia.PlayToAllAsync(GoodbyePlaySource);
}

電話を切って記録を停止する

最後に、通話を終了する状況が整ったことが検出されたら、HangUpAsync メソッドを使用して通話を切ることができます。

if ((parsedEvent is PlayCompleted) || (parsedEvent is PlayFailed))
{
    logger.LogInformation($"Stop recording and terminating call.");
    callAutomationClient.GetCallRecording().Stop(recordingId);
    await callConnection.HangUpAsync(true);
}

コードの実行

VS Code でアプリケーションを実行するには、ターミナル ウィンドウを開き、次のコマンドを実行します。

dotnet run

ブラウザーで http://localhost:8080/swagger/index.html または開発トンネル URL を開きます。 トンネル URL は <YOUR DEV TUNNEL ENDPOINT>/swagger/index.html のようになります

前提条件

サンプル コード

GitHub からクイックスタート サンプル コードをダウンロードまたは複製します。

CallAutomation_OutboundCalling フォルダーに移動し、コード エディターでソリューションを開きます。

Azure DevTunnel をセットアップしてホストする

Azure DevTunnels は、インターネット上でホストされているローカル Web サービスを共有可能にする Azure サービスです。 DevTunnel コマンドを実行して、ローカル開発環境をパブリック インターネットに接続します。 次に、DevTunnels は、匿名アクセスが可能な永続的なエンドポイント URL を作成します。 Azure Communication Services では、このエンドポイントを使用して、Azure Communication Services Call Automation サービスからアプリケーションに通話イベントが通知されます。

devtunnel create --allow-anonymous
devtunnel port create -p MY_SPRINGAPP_PORT
devtunnel host

アプリケーションの構成を更新する

次に、/resources フォルダー内の application.yml ファイルを開き、次の値を構成します。

  • connectionstring: Azure Communications Service リソースの接続文字列。 Azure Communication Services 接続文字列は、こちらの手順を使用して確認できます。
  • basecallbackuri: DevTunnel ホストを初期化したら、その URI でこのフィールドを更新します。
  • callerphonenumber: 取得した Azure Communication Services の電話番号でこのフィールドを更新します。 この電話番号では E164 電話番号形式を使用する必要があります (例: +18881234567)
  • targetphonenumber: アプリケーションが使用する発信先の電話番号でフィールドを更新します。 この電話番号では E164 電話番号形式を使用する必要があります (例: +18881234567)
  • cognitiveServiceEndpoint: Azure AI サービス エンドポイントでフィールドを更新します。
  • targetTeamsUserId: (省略可能) 通話に追加する Microsoft Teams ユーザー ID でフィールドを更新します。 Graph API を使用した Teams ユーザー ID の取得に関するページを参照してください。
acs:
  connectionstring: <YOUR ACS CONNECTION STRING> 
  basecallbackuri: <YOUR DEV TUNNEL ENDPOINT> 
  callerphonenumber: <YOUR ACS PHONE NUMBER ex. "+1425XXXAAAA"> 
  targetphonenumber: <YOUR TARGET PHONE NUMBER ex. "+1425XXXAAAA"> 
  cognitiveServiceEndpoint: <YOUR COGNITIVE SERVICE ENDPOINT>
  targetTeamsUserId: <(OPTIONAL) YOUR TARGET TEAMS USER ID ex. "ab01bc12-d457-4995-a27b-c405ecfe4870">

発信通話を行い、メディアを再生する

Azure Communication Services から発信通話を行うために、このサンプルでは、application.yml ファイルで定義した targetphonenumber を使用し、createCallWithResponse API を使用して通話を作成します。

PhoneNumberIdentifier caller = new PhoneNumberIdentifier(appConfig.getCallerphonenumber());
PhoneNumberIdentifier target = new PhoneNumberIdentifier(appConfig.getTargetphonenumber());
CallInvite callInvite = new CallInvite(target, caller);
CreateCallOptions createCallOptions = new CreateCallOptions(callInvite, appConfig.getCallBackUri());
CallIntelligenceOptions callIntelligenceOptions = new CallIntelligenceOptions().setCognitiveServicesEndpoint(appConfig.getCognitiveServiceEndpoint());
createCallOptions = createCallOptions.setCallIntelligenceOptions(callIntelligenceOptions);
Response<CreateCallResult> result = client.createCallWithResponse(createCallOptions, Context.NONE);

(省略可能) 通話に Microsoft Teams ユーザーを追加する

addParticipant メソッドで MicrosoftTeamsUserIdentifier と Teams ユーザーの ID を使用して、Microsoft Teams ユーザーを通話に追加できます。まず、事前に必要な手順「Microsoft Teams ユーザーへの通話を可能にするための Azure Communication Services リソースの認可」を実行する必要があります。 必要に応じて、SourceDisplayName を渡して Teams ユーザーのトースト通知に表示されるテキストを制御することもできます。

client.getCallConnection(callConnectionId).addParticipant(
    new CallInvite(new MicrosoftTeamsUserIdentifier(targetTeamsUserId))
        .setSourceDisplayName("Jack (Contoso Tech Support)"));

通話の記録を開始する

Call Automation サービスを使用すると、音声通話とビデオ通話の記録を開始して保存することもできます。 Call Recording API のさまざまな機能の詳細については、こちらを参照してください。

ServerCallLocator serverCallLocator = new ServerCallLocator(
    client.getCallConnection(callConnectionId)
        .getCallProperties()
        .getServerCallId());
        
StartRecordingOptions startRecordingOptions = new StartRecordingOptions(serverCallLocator);

Response<RecordingStateResult> response = client.getCallRecording()
    .startWithResponse(startRecordingOptions, Context.NONE);

recordingId = response.getValue().getRecordingId();

通話イベントに応答する

このアプリケーションでは、前半で basecallbackuri を Call Automation Service に登録しました。 発生する通話イベントをサービスが通知するために使用するエンドポイントを URI が示します。 次に、イベントを反復処理して、アプリケーションが解釈する必要のある特定のイベントを検出することができます。 次のコードでは、CallConnected イベントに応答します。

List<CallAutomationEventBase> events = CallAutomationEventParser.parseEvents(reqBody);
for (CallAutomationEventBase event : events) {
    String callConnectionId = event.getCallConnectionId();
    if (event instanceof CallConnected) {
        log.info("CallConnected event received");
    }
    else if (event instanceof RecognizeCompleted) {
        log.info("Recognize Completed event received");
    }
}

ウェルカム メッセージを再生して認識する

TextSource を使用すると、合成してウェルカム メッセージに使用するテキストをサービスに提供できます。 CallConnected イベントが発生すると、Azure Communication Services Call Automation サービスによってこのメッセージが再生されます。

次に、テキストを CallMediaRecognizeChoiceOptions に渡して、StartRecognizingAsync を呼び出します。 これにより、呼び出し元が選択したオプションをアプリケーションで認識できるようになります。

var playSource = new TextSource().setText(content).setVoiceName("en-US-NancyNeural");

var recognizeOptions = new CallMediaRecognizeChoiceOptions(new PhoneNumberIdentifier(targetParticipant), getChoices())
  .setInterruptCallMediaOperation(false)
  .setInterruptPrompt(false)
  .setInitialSilenceTimeout(Duration.ofSeconds(10))
  .setPlayPrompt(playSource)
  .setOperationContext(context);

client.getCallConnection(callConnectionId)
  .getCallMedia()
  .startRecognizing(recognizeOptions);

private List < RecognitionChoice > getChoices() {
  var choices = Arrays.asList(
    new RecognitionChoice().setLabel(confirmLabel).setPhrases(Arrays.asList("Confirm", "First", "One")).setTone(DtmfTone.ONE),
    new RecognitionChoice().setLabel(cancelLabel).setPhrases(Arrays.asList("Cancel", "Second", "Two")).setTone(DtmfTone.TWO)
  );

  return choices;
}

選択イベントの処理

Azure Communication Services Call Automation はセットアップした Webhook に api/callbacks をトリガーし、RecognizeCompleted イベントが通知されます。 このイベントは、受信した入力に応答して、アクションをトリガーする機能を提供します。 アプリケーションは、受信した特定の入力に基づいて呼び出し元にメッセージを再生します。

else if (event instanceof RecognizeCompleted) {
  log.info("Recognize Completed event received");

  RecognizeCompleted acsEvent = (RecognizeCompleted) event;

  var choiceResult = (ChoiceResult) acsEvent.getRecognizeResult().get();

  String labelDetected = choiceResult.getLabel();

  String phraseDetected = choiceResult.getRecognizedPhrase();

  log.info("Recognition completed, labelDetected=" + labelDetected + ", phraseDetected=" + phraseDetected + ", context=" + event.getOperationContext());

  String textToPlay = labelDetected.equals(confirmLabel) ? confirmedText : cancelText;

  handlePlay(callConnectionId, textToPlay);
}

private void handlePlay(final String callConnectionId, String textToPlay) {
  var textPlay = new TextSource()
    .setText(textToPlay)
    .setVoiceName("en-US-NancyNeural");

  client.getCallConnection(callConnectionId)
    .getCallMedia()
    .playToAll(textPlay);
}

電話を切る

最後に、通話を終了する状況が整ったことが検出されたら、hangUp メソッドを使用して通話を切ることができます。

client.getCallConnection(callConnectionId).hangUp(true);

コードの実行

pom.xml ファイルが格納されているディレクトリに移動し、次の mvn コマンドを使用します。

  • アプリケーションをコンパイルする: mvn compile
  • パッケージをビルドする: mvn package
  • アプリを実行する: mvn exec:java

前提条件

サンプル コード

GitHub からクイックスタート サンプル コードをダウンロードまたは複製します。

CallAutomation_OutboundCalling フォルダーに移動し、コード エディターでソリューションを開きます。

環境をセットアップする

サンプル コードをダウンロードして、プロジェクト ディレクトリに移動し、必要な依存関係をインストールして開発環境をセットアップする npm コマンドを実行します。

npm install

Azure DevTunnel をセットアップしてホストする

Azure DevTunnels は、インターネット上でホストされているローカル Web サービスを共有可能にする Azure サービスです。 DevTunnel CLI コマンドを使用して、ローカル開発環境をパブリック インターネットに接続します。 このエンドポイントを使用して、Azure Communication Services Call Automation サービスからアプリケーションに通話イベントを通知します。

devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host

アプリケーションの構成を更新する

次に、次の値を使用して .env ファイルを更新します。

  • CONNECTION_STRING: Azure Communications Service リソースの接続文字列。 Azure Communication Services 接続文字列は、こちらの手順を使用して確認できます。
  • CALLBACK_URI: DevTunnel ホストを初期化したら、その URI でこのフィールドを更新します。
  • TARGET_PHONE_NUMBER: アプリケーションが使用する発信先の電話番号でフィールドを更新します。 この電話番号では E164 電話番号形式を使用する必要があります (例: +18881234567)
  • ACS_RESOURCE_PHONE_NUMBER: 取得した Azure Communication Services の電話番号でこのフィールドを更新します。 この電話番号では E164 電話番号形式を使用する必要があります (例: +18881234567)
  • COGNITIVE_SERVICES_ENDPOINT: Azure AI サービス エンドポイントでフィールドを更新します。
  • TARGET_TEAMS_USER_ID: (省略可能) 通話に追加する Microsoft Teams ユーザー ID でフィールドを更新します。 Graph API を使用した Teams ユーザー ID の取得に関するページを参照してください。
CONNECTION_STRING="<YOUR_CONNECTION_STRING>" 
ACS_RESOURCE_PHONE_NUMBER ="<YOUR_ACS_NUMBER>" 
TARGET_PHONE_NUMBER="<+1XXXXXXXXXX>" 
CALLBACK_URI="<VS_TUNNEL_URL>" 
COGNITIVE_SERVICES_ENDPOINT="<COGNITIVE_SERVICES_ENDPOINT>" 
TARGET_TEAMS_USER_ID="<TARGET_TEAMS_USER_ID>"

発信通話を行い、メディアを再生する

Azure Communication Services から発信通話を行うには、環境に提供した電話番号を使用します。 電話番号が E164 電話番号形式であることを確認します (例: +18881234567)

コードは、指定した target_phone_number を使用して発信通話を行い、その電話番号に通話を発信します。

const callInvite: CallInvite = {
	targetParticipant: callee,
	sourceCallIdNumber: {
		phoneNumber: process.env.ACS_RESOURCE_PHONE_NUMBER || "",
	},
};

const options: CreateCallOptions = {
	cognitiveServicesEndpoint: process.env.COGNITIVE_SERVICES_ENDPOINT
};

console.log("Placing outbound call...");
acsClient.createCall(callInvite, process.env.CALLBACK_URI + "/api/callbacks", options);

(省略可能) 通話に Microsoft Teams ユーザーを追加する

addParticipant メソッドで microsoftTeamsUserId プロパティを使用して、Microsoft Teams ユーザーを通話に追加できます。 まず、事前に必要な手順「Microsoft Teams ユーザーへの通話を可能にするための Azure Communication Services リソースの認可」を実行する必要があります。 必要に応じて、sourceDisplayName を渡して Teams ユーザーのトースト通知に表示されるテキストを制御することもできます。

await acsClient.getCallConnection(callConnectionId).addParticipant({
    targetParticipant: { microsoftTeamsUserId: process.env.TARGET_TEAMS_USER_ID },
    sourceDisplayName: "Jack (Contoso Tech Support)"
});

通話の記録を開始する

Call Automation サービスを使用すると、音声通話とビデオ通話の記録を開始して保存することもできます。 Call Recording API のさまざまな機能の詳細については、こちらを参照してください。

const callLocator: CallLocator = {
    id: serverCallId,
    kind: "serverCallLocator",
};

const recordingOptions: StartRecordingOptions = {
    callLocator: callLocator,
};

const response = await acsClient.getCallRecording().start(recordingOptions);

recordingId = response.recordingId;

通話イベントに応答する

このアプリケーションでは、前半で CALLBACK_URI を Call Automation Service に登録しました。 発生する通話イベントをサービスが通知するために使用するエンドポイントを URI が示します。 次に、イベントを反復処理して、アプリケーションが解釈する必要のある特定のイベントを検出することができます。 CallConnected イベントに応答して通知を受け取り、ダウンストリーム操作を開始します。 TextSource を使用すると、合成してウェルカム メッセージに使用するテキストをサービスに提供できます。 CallConnected イベントが発生すると、Azure Communication Services Call Automation サービスによってこのメッセージが再生されます。

次に、テキストを CallMediaRecognizeChoiceOptions に渡して、StartRecognizingAsync を呼び出します。 これにより、呼び出し元が選択したオプションをアプリケーションで認識できるようになります。

callConnectionId = eventData.callConnectionId;
serverCallId = eventData.serverCallId;
console.log("Call back event received, callConnectionId=%s, serverCallId=%s, eventType=%s", callConnectionId, serverCallId, event.type);
callConnection = acsClient.getCallConnection(callConnectionId);
const callMedia = callConnection.getCallMedia();

if (event.type === "Microsoft.Communication.CallConnected") {
 	console.log("Received CallConnected event");
 	await startRecording();
	await startRecognizing(callMedia, mainMenu, "");
}

async function startRecognizing(callMedia: CallMedia, textToPlay: string, context: string) {
	const playSource: TextSource = {
 		text: textToPlay,
 		voiceName: "en-US-NancyNeural",
 		kind: "textSource"
 	};

 	const recognizeOptions: CallMediaRecognizeChoiceOptions = {
 		choices: await getChoices(),
 		interruptPrompt: false,
 		initialSilenceTimeoutInSeconds: 10,
 		playPrompt: playSource,
 		operationContext: context,
 		kind: "callMediaRecognizeChoiceOptions"
 	};

 	await callMedia.startRecognizing(callee, recognizeOptions)
 }

選択イベントの処理

Azure Communication Services Call Automation はセットアップした Webhook に api/callbacks をトリガーし、RecognizeCompleted イベントが通知されます。 このイベントは、受信した入力に応答して、アクションをトリガーする機能を提供します。 アプリケーションは、受信した特定の入力に基づいて呼び出し元にメッセージを再生します。

else if (event.type === "Microsoft.Communication.RecognizeCompleted") { 
	if(eventData.recognitionType === "choices"){ 
        	console.log("Recognition completed, event=%s, resultInformation=%s",eventData, eventData.resultInformation); 
        	var context = eventData.operationContext; 
            	const labelDetected = eventData.choiceResult.label;  
            	const phraseDetected = eventData.choiceResult.recognizedPhrase; 
            	console.log("Recognition completed, labelDetected=%s, phraseDetected=%s, context=%s", labelDetected, phraseDetected, eventData.operationContext); 
            	const textToPlay = labelDetected === confirmLabel ? confirmText : cancelText;            
            	await handlePlay(callMedia, textToPlay); 
        } 
}  
 
async function handlePlay(callConnectionMedia:CallMedia, textContent:string){ 
	const play : TextSource = { text:textContent , voiceName: "en-US-NancyNeural", kind: "textSource"} 
	await callConnectionMedia.playToAll([play]); 
} 

電話を切る

最後に、通話を終了する状況が整ったことが検出されたら、hangUp() メソッドを使用して通話を切ることができます。

  await acsClient.getCallRecording().stop(recordingId);
  callConnection.hangUp(true);

コードの実行

アプリケーションを実行するには、ターミナル ウィンドウを開き、次のコマンドを実行します。

  npm run dev

前提条件

サンプル コード

GitHub からクイックスタート サンプル コードをダウンロードまたは複製します。

CallAutomation_OutboundCalling フォルダーに移動し、コード エディターでソリューションを開きます。

Python 環境をセットアップする

Python 環境を作成してアクティブ化し、次のコマンドを使用して必要なパッケージをインストールします。 パッケージの管理の詳細については、こちらを参照してください。

pip install -r requirements.txt

Azure DevTunnel をセットアップしてホストする

Azure DevTunnels は、インターネット上でホストされているローカル Web サービスを共有可能にする Azure サービスです。 コマンドを使用して、ローカル開発環境をパブリック インターネットに接続します。 匿名アクセスが可能な永続的なエンドポイント URL を DevTunnels が作成します。 このエンドポイントを使用して、Azure Communication Services Call Automation サービスからアプリケーションに通話イベントを通知します。

devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host

アプリケーションの構成を更新する

次に、次の値を使用して main.py ファイルを更新します。

  • ACS_CONNECTION_STRING: Azure Communications Service リソースの接続文字列。 Azure Communication Services 接続文字列は、こちらの手順を使用して確認できます。
  • CALLBACK_URI_HOST: DevTunnel ホストを初期化したら、その URI でこのフィールドを更新します。
  • TARGET_PHONE_NUMBER: アプリケーションが使用する発信先の電話番号でフィールドを更新します。 この電話番号では E164 電話番号形式を使用する必要があります (例: +18881234567)
  • ACS_PHONE_NUMBER: 取得した Azure Communication Services の電話番号でこのフィールドを更新します。 この電話番号では E164 電話番号形式を使用する必要があります (例: +18881234567)
  • COGNITIVE_SERVICES_ENDPOINT: Azure AI サービス エンドポイントでフィールドを更新します。
  • TARGET_TEAMS_USER_ID: (省略可能) 通話に追加する Microsoft Teams ユーザー ID でフィールドを更新します。 Graph API を使用した Teams ユーザー ID の取得に関するページを参照してください。
# Your ACS resource connection string 
ACS_CONNECTION_STRING = "<ACS_CONNECTION_STRING>" 

# Your ACS resource phone number will act as source number to start outbound call 
ACS_PHONE_NUMBER = "<ACS_PHONE_NUMBER>" 

# Target phone number you want to receive the call. 
TARGET_PHONE_NUMBER = "<TARGET_PHONE_NUMBER>" 

# Callback events URI to handle callback events. 
CALLBACK_URI_HOST = "<CALLBACK_URI_HOST_WITH_PROTOCOL>" 
CALLBACK_EVENTS_URI = CALLBACK_URI_HOST + "/api/callbacks" 

#Your Cognitive service endpoint 
COGNITIVE_SERVICES_ENDPOINT = "<COGNITIVE_SERVICES_ENDPOINT>" 

#(OPTIONAL) Your target Microsoft Teams user Id ex. "ab01bc12-d457-4995-a27b-c405ecfe4870"
TARGET_TEAMS_USER_ID = "<TARGET_TEAMS_USER_ID>"

発信通話を実行する

Azure Communication Services から発信通話を行うには、まず、通話の受信に使用する電話番号を指定します。 処理を簡単にするために、E164 電話番号形式の電話番号 (例: +18881234567) で target_phone_number を更新することができます。

指定した target_phone_number を使用して発信通話を行います。

target_participant = PhoneNumberIdentifier(TARGET_PHONE_NUMBER) 
source_caller = PhoneNumberIdentifier(ACS_PHONE_NUMBER) 
call_invite = CallInvite(target=target_participant, source_caller_id_number=source_caller) 
call_connection_properties = call_automation_client.create_call(call_invite, CALLBACK_EVENTS_URI, 
cognitive_services_endpoint=COGNITIVE_SERVICES_ENDPOINT) 
    app.logger.info("Created call with connection id: %s",
call_connection_properties.call_connection_id) 
return redirect("/") 

(省略可能) 通話に Microsoft Teams ユーザーを追加する

add_participant メソッドで MicrosoftTeamsUserIdentifier と Teams ユーザーの ID を使用して、Microsoft Teams ユーザーを通話に追加できます。まず、事前に必要な手順「Microsoft Teams ユーザーへの通話を可能にするための Azure Communication Services リソースの認可」を実行する必要があります。 必要に応じて、source_display_name を渡して Teams ユーザーのトースト通知に表示されるテキストを制御することもできます。

call_connection_client.add_participant(target_participant = CallInvite(
    target = MicrosoftTeamsUserIdentifier(user_id=TARGET_TEAMS_USER_ID),
    source_display_name = "Jack (Contoso Tech Support)"))

通話の記録を開始する

Call Automation サービスを使用すると、音声通話とビデオ通話の記録を開始して保存することもできます。 Call Recording API のさまざまな機能の詳細については、こちらを参照してください。

recording_properties = call_automation_client.start_recording(ServerCallLocator(event.data['serverCallId']))
recording_id = recording_properties.recording_id

通話イベントに応答する

このアプリケーションでは、前半で CALLBACK_URI_HOST を Call Automation Service に登録しました。 発生する通話イベントをサービスが通知するために使用するエンドポイントを URI が示します。 次に、イベントを反復処理して、アプリケーションが解釈する必要のある特定のイベントを検出することができます。 次のコードでは、CallConnected イベントに応答します。

@app.route('/api/callbacks', methods=['POST'])
def callback_events_handler():
    for event_dict in request.json:
        event = CloudEvent.from_dict(event_dict)
        if event.type == "Microsoft.Communication.CallConnected":
            # Handle Call Connected Event
            ...
            return Response(status=200)

ウェルカム メッセージを再生して認識する

TextSource を使用すると、合成してウェルカム メッセージに使用するテキストをサービスに提供できます。 CallConnected イベントが発生すると、Azure Communication Services Call Automation サービスによってこのメッセージが再生されます。

次に、テキストを CallMediaRecognizeChoiceOptions に渡して、StartRecognizingAsync を呼び出します。 これにより、呼び出し元が選択したオプションをアプリケーションで認識できるようになります。


get_media_recognize_choice_options( 
    call_connection_client=call_connection_client, 
    text_to_play=MainMenu,  
    target_participant=target_participant, 
    choices=get_choices(),context="") 

def get_media_recognize_choice_options(call_connection_client: CallConnectionClient, text_to_play: str, target_participant:str, choices: any, context: str): 
    play_source =  TextSource (text= text_to_play, voice_name= SpeechToTextVoice) 
    call_connection_client.start_recognizing_media( 
        input_type=RecognizeInputType.CHOICES, 

        target_participant=target_participant,
        choices=choices, 
        play_prompt=play_source, 
        interrupt_prompt=False, 
        initial_silence_timeout=10, 
        operation_context=context 
    ) 

def get_choices(): 
    choices = [ 
        RecognitionChoice(label = ConfirmChoiceLabel, phrases= ["Confirm", "First", "One"], tone = DtmfTone.ONE), 
        RecognitionChoice(label = CancelChoiceLabel, phrases= ["Cancel", "Second", "Two"], tone = DtmfTone.TWO) 
    ] 
return choices 

選択イベントの処理

Azure Communication Services Call Automation はセットアップした Webhook に api/callbacks をトリガーし、RecognizeCompleted イベントが通知されます。 このイベントは、受信した入力に応答して、アクションをトリガーする機能を提供します。 アプリケーションは、受信した特定の入力に基づいて呼び出し元にメッセージを再生します。

elif event.type == "Microsoft.Communication.RecognizeCompleted":
	app.logger.info("Recognize completed: data=%s", event.data)
if event.data['recognitionType'] == "choices":
	labelDetected = event.data['choiceResult']['label'];
phraseDetected = event.data['choiceResult']['recognizedPhrase'];
app.logger.info("Recognition completed, labelDetected=%s, phraseDetected=%s, context=%s", labelDetected, phraseDetected, event.data.get('operationContext'))
if labelDetected == ConfirmChoiceLabel:
	textToPlay = ConfirmedText
else:
	textToPlay = CancelText
handle_play(call_connection_client = call_connection_client, text_to_play = textToPlay)
def handle_play(call_connection_client: CallConnectionClient, text_to_play: str):
	play_source = TextSource(text = text_to_play, voice_name = SpeechToTextVoice)
call_connection_client.play_media_to_all(play_source)

電話を切る

最後に、通話を終了する状況が整ったことが検出されたら、hang_up() メソッドを使用して通話を切ることができます。 最後に、通話記録操作を安全に停止することもできます。

call_automation_client.stop_recording(recording_id)
call_connection_client.hang_up(is_for_everyone=True)

コードの実行

VS Code でアプリケーションを実行するには、ターミナル ウィンドウを開き、次のコマンドを実行します。

python main.py