Call Automation は、REST API インターフェイスを使用してアクションの要求を受信し、要求が正常に送信されたかどうかを通知する応答を提供するものです。 呼び出しの非同期性のため、ほとんどのアクションには、アクションが正常に終了するか失敗したときにトリガーされる対応するイベントがあります。 この記事では、 SendDTMF や ContinuousDtmfRecognitionなど、呼び出し中に開発者が使用できるアクションについて説明します。 アクションには、特定のアクションを呼び出す方法に関するサンプル コードが付属しています。
Call Automation では、この記事に含まれていない通話と録音を管理するための他のアクションがサポートされています。
Note
現在、Call Automation と Microsoft Teams の相互運用はできません。 Teams ユーザーへの通話の発信やリダイレクト、通話オートメーションを使用した Teams ユーザーへの音声再生などのアクションはサポートされていません。
Prerequisites
- アクション イベント プログラミング モデルとイベント コールバックについて説明した Call Automation の 概念に 関する記事を参照してください。
- この記事で使用するや
CommunicationUserIdentifierなどのPhoneNumberIdentifierについて説明します。
-
通話オートメーションを使用して通話を制御および誘導する方法の詳細について説明します。この方法では、通話を処理する基本について説明します。
すべてのコード サンプルでは、clientは、次のように作成できるCallAutomationClient オブジェクトであり、callConnectionは、CallConnectionまたはAnswer応答から取得するCreateCall オブジェクトです。 アプリケーションが受け取るコールバック イベントから取得することもできます。
var callAutomationClient = new CallAutomationClient("<Azure Communication Services connection string>");
CallAutomationClient callAutomationClient = new CallAutomationClientBuilder()
.connectionString("<Azure Communication Services connection string>")
.buildClient();
callAutomationClient = new CallAutomationClient(("<Azure Communication Services connection string>");
call_automation_client = CallAutomationClient.from_connection_string((("<Azure Communication Services connection string>")
DTMF 送信
デュアルトーンマルチ周波数(DTMF)トーンを外部参加者に送信できます。 この機能は、既に通話中で、内線番号を持つ別の参加者を招待したり、対話型の音声応答メニューを使用したりする必要がある場合に便利です。
Note
この機能は、公衆交換電話網の外部参加者に対してのみサポートされ、一度に最大 18 トーンの送信をサポートします。
SendDtmfAsync メソッド
DTMF トーンの一覧を外部参加者に送信します。
var tones = new DtmfTone[] { DtmfTone.One, DtmfTone.Two, DtmfTone.Three, DtmfTone.Pound };
var sendDtmfTonesOptions = new SendDtmfTonesOptions(tones, new PhoneNumberIdentifier(calleePhonenumber))
{
OperationContext = "dtmfs-to-ivr"
};
var sendDtmfAsyncResult = await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia()
.SendDtmfTonesAsync(sendDtmfTonesOptions);
List<DtmfTone> tones = Arrays.asList(DtmfTone.ONE, DtmfTone.TWO, DtmfTone.THREE, DtmfTone.POUND);
SendDtmfTonesOptions options = new SendDtmfTonesOptions(tones, new PhoneNumberIdentifier(c2Target));
options.setOperationContext("dtmfs-to-ivr");
callAutomationClient.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.sendDtmfTonesWithResponse(options)
.block();
const tones = [DtmfTone.One, DtmfTone.Two, DtmfTone.Three];
const sendDtmfTonesOptions: SendDtmfTonesOptions = {
operationContext: "dtmfs-to-ivr"
};
const result: SendDtmfTonesResult = await callAutomationClient.getCallConnection(callConnectionId)
.getCallMedia()
.sendDtmfTones(tones, {
phoneNumber: c2Target
}, sendDtmfTonesOptions);
console.log("sendDtmfTones, result=%s", result);
tones = [DtmfTone.ONE, DtmfTone.TWO, DtmfTone.THREE]
result = call_automation_client.get_call_connection(call_connection_id).send_dtmf_tones(
tones = tones,
target_participant = PhoneNumberIdentifier(c2_target),
operation_context = "dtmfs-to-ivr")
app.logger.info("Send dtmf, result=%s", result)
アプリケーションがこれらの DTMF トーンを送信すると、イベント更新が届きます。
SendDtmfTonesCompleted および SendDtmfTonesFailed のイベントを使用してビジネス ロジックをアプリケーション内に作成して、次のステップを決めることができます。
SendDtmfTonesCompleted イベントの例:
if (acsEvent is SendDtmfTonesCompleted sendDtmfCompleted)
{
logger.LogInformation("Send DTMF succeeded, context={context}", sendDtmfCompleted.OperationContext);
}
if (acsEvent instanceof SendDtmfTonesCompleted) {
SendDtmfTonesCompleted event = (SendDtmfTonesCompleted) acsEvent;
log.info("Send dtmf succeeded: context=" + event.getOperationContext());
}
if (event.type === "Microsoft.Communication.SendDtmfTonesCompleted") {
console.log("Send dtmf succeeded: context=%s", eventData.operationContext);
}
if event.type == "Microsoft.Communication.SendDtmfTonesCompleted":
app.logger.info("Send dtmf succeeded: context=%s", event.data['operationContext']);
SendDtmfTonesFailed イベントの例:
if (acsEvent is SendDtmfTonesFailed sendDtmfFailed)
{
logger.LogInformation("Send dtmf failed: result={result}, context={context}",
sendDtmfFailed.ResultInformation?.Message, sendDtmfFailed.OperationContext);
}
if (acsEvent instanceof SendDtmfTonesFailed) {
SendDtmfTonesFailed event = (SendDtmfTonesFailed) acsEvent;
log.info("Send dtmf failed: result=" + event.getResultInformation().getMessage() + ", context="
+ event.getOperationContext());
}
if (event.type === "Microsoft.Communication.SendDtmfTonesFailed") {
console.log("sendDtmfTones failed: result=%s, context=%s",
eventData.resultInformation.message,
eventData.operationContext);
}
if event.type == "Microsoft.Communication.SendDtmfTonesFailed":
app.logger.info("Send dtmf failed: result=%s, context=%s", event.data['resultInformation']['message'], event.data['operationContext'])
継続的 DTMF 認識
継続的 DTMF トーンを通話全体で受け取るためのサブスクライブができます。 対象の参加者がキーパッドのキーを押すと、アプリケーションは DTMF トーンを受け取ります。 参加者がトーンを押すと、トーンがアプリケーションに 1 つずつ送信されます。
StartContinuousDtmfRecognitionAsync メソッド
参加者によって送信された DTMF トーンの検出を開始します。
await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia()
.StartContinuousDtmfRecognitionAsync(new PhoneNumberIdentifier(c2Target), "dtmf-reco-on-c2");
ContinuousDtmfRecognitionOptions options = new ContinuousDtmfRecognitionOptions(new PhoneNumberIdentifier(c2Target));
options.setOperationContext("dtmf-reco-on-c2");
callAutomationClient.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.startContinuousDtmfRecognitionWithResponse(options)
.block();
const continuousDtmfRecognitionOptions: ContinuousDtmfRecognitionOptions = {
operationContext: "dtmf-reco-on-c2"
};
await callAutomationclient.getCallConnection(callConnectionId)
.getCallMedia()
.startContinuousDtmfRecognition({
phoneNumber: c2Target
}, continuousDtmfRecognitionOptions);
call_automation_client.get_call_connection(
call_connection_id
).start_continuous_dtmf_recognition(
target_participant=PhoneNumberIdentifier(c2_target),
operation_context="dtmf-reco-on-c2",
)
app.logger.info("Started continuous DTMF recognition")
アプリケーションが参加者から DTMF トーンを受信することを望まない場合は、 StopContinuousDtmfRecognitionAsync メソッドを使用して、Azure Communication Services に DTMF トーンの検出を停止するように通知します。
StopContinuousDtmfRecognitionAsync
参加者から送信された DTMF トーンの検出を停止します。
var continuousDtmfRecognitionOptions = new ContinuousDtmfRecognitionOptions(new PhoneNumberIdentifier(callerPhonenumber))
{
OperationContext = "dtmf-reco-on-c2"
};
var startContinuousDtmfRecognitionAsyncResult = await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia()
.StartContinuousDtmfRecognitionAsync(continuousDtmfRecognitionOptions);
ContinuousDtmfRecognitionOptions options = new ContinuousDtmfRecognitionOptions(new PhoneNumberIdentifier(c2Target));
options.setOperationContext("dtmf-reco-on-c2");
callAutomationClient.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.stopContinuousDtmfRecognitionWithResponse(options)
.block();
const continuousDtmfRecognitionOptions: ContinuousDtmfRecognitionOptions = {
operationContext: "dtmf-reco-on-c2"
};
await callAutomationclient.getCallConnection(callConnectionId)
.getCallMedia()
.stopContinuousDtmfRecognition({
phoneNumber: c2Target
}, continuousDtmfRecognitionOptions);
call_automation_client.get_call_connection(call_connection_id).stop_continuous_dtmf_recognition(
target_participant=PhoneNumberIdentifier(c2_target),
operation_context="dtmf-reco-on-c2")
app.logger.info("Stopped continuous DTMF recognition")
アプリケーションがイベント更新を受信するのは、これらのアクションが成功したか失敗したときです。 これらのイベントを使用して、カスタム ビジネス ロジックを構築し、アプリケーションがこれらのイベント更新プログラムを受信するときに実行する必要がある次の手順を構成できます。
ContinuousDtmfRecognitionToneReceived イベント
正常に検出された DTMF トーンを処理する方法の例。
if (acsEvent is ContinuousDtmfRecognitionToneReceived continuousDtmfRecognitionToneReceived)
{
logger.LogInformation("Tone detected: sequenceId={sequenceId}, tone={tone}",
continuousDtmfRecognitionToneReceived.SequenceId,
continuousDtmfRecognitionToneReceived.Tone);
}
if (acsEvent instanceof ContinuousDtmfRecognitionToneReceived) {
ContinuousDtmfRecognitionToneReceived event = (ContinuousDtmfRecognitionToneReceived) acsEvent;
log.info("Tone detected: sequenceId=" + event.getSequenceId()
+ ", tone=" + event.getTone().convertToString()
+ ", context=" + event.getOperationContext());
}
if (event.type === "Microsoft.Communication.ContinuousDtmfRecognitionToneReceived") {
console.log("Tone detected: sequenceId=%s, tone=%s, context=%s",
eventData.sequenceId,
eventData.tone,
eventData.operationContext);
}
if event.type == "Microsoft.Communication.ContinuousDtmfRecognitionToneReceived":
app.logger.info("Tone detected: sequenceId=%s, tone=%s, context=%s",
event.data['sequenceId'],
event.data['tone'],
event.data['operationContext'])
Azure Communication Services は、SequenceId イベントの一部としてContinuousDtmfRecognitionToneReceivedを提供します。 アプリケーションでこれを使用して、参加者が DTMF トーンに入った順序を再構築できます。
ContinuousDtmfRecognitionFailed イベント
DTMF トーン検出が失敗した場合の処理の例。
if (acsEvent is ContinuousDtmfRecognitionToneFailed continuousDtmfRecognitionToneFailed)
{
logger.LogInformation("Start continuous DTMF recognition failed, result={result}, context={context}",
continuousDtmfRecognitionToneFailed.ResultInformation?.Message,
continuousDtmfRecognitionToneFailed.OperationContext);
}
if (acsEvent instanceof ContinuousDtmfRecognitionToneFailed) {
ContinuousDtmfRecognitionToneFailed event = (ContinuousDtmfRecognitionToneFailed) acsEvent;
log.info("Tone failed: result="+ event.getResultInformation().getMessage()
+ ", context=" + event.getOperationContext());
}
if (event.type === "Microsoft.Communication.ContinuousDtmfRecognitionToneFailed") {
console.log("Tone failed: result=%s, context=%s", eventData.resultInformation.message, eventData.operationContext);
}
if event.type == "Microsoft.Communication.ContinuousDtmfRecognitionToneFailed":
app.logger.info(
"Tone failed: result=%s, context=%s",
event.data["resultInformation"]["message"],
event.data["operationContext"],
)
ContinuousDtmfRecognitionStopped イベント
継続的な DTMF 認識が停止した場合の処理の例。 アプリケーションが StopContinuousDtmfRecognitionAsync イベントを呼び出したか、呼び出しが終了した可能性があります。
if (acsEvent is ContinuousDtmfRecognitionStopped continuousDtmfRecognitionStopped)
{
logger.LogInformation("Continuous DTMF recognition stopped, context={context}", continuousDtmfRecognitionStopped.OperationContext);
}
if (acsEvent instanceof ContinuousDtmfRecognitionStopped) {
ContinuousDtmfRecognitionStopped event = (ContinuousDtmfRecognitionStopped) acsEvent;
log.info("Tone stopped, context=" + event.getOperationContext());
}
if (event.type === "Microsoft.Communication.ContinuousDtmfRecognitionStopped") {
console.log("Tone stopped: context=%s", eventData.operationContext);
}
if event.type == "Microsoft.Communication.ContinuousDtmfRecognitionStopped":
app.logger.info("Tone stopped: context=%s", event.data["operationContext"])
Hold
保留アクションを使用すると、開発者は参加者とシステムまたはエージェント間の会話を一時停止できます。 この機能は、参加者を別のエージェントまたは部門に転送する必要があるシナリオや、エージェントが会話を続行する前にスーパーバイザーに相談する必要がある場合に役立ちます。 この間、保留中の参加者に音声を再生することを選択できます。
// Option 1: Hold without additional options
await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia().HoldAsync(c2Target);
/*
// Option 2: Hold with play source
PlaySource playSource = /* initialize playSource */;
await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia().HoldAsync(c2Target, playSource);
// Option 3: Hold with options
var holdOptions = new HoldOptions(target)
{
OperationCallbackUri = new Uri(""),
OperationContext = "holdcontext"
};
await callMedia.HoldAsync(holdOptions);
*/
// Option 1: Hold with options
PlaySource playSource = /* initialize playSource */;
HoldOptions holdOptions = new HoldOptions(target)
.setOperationCallbackUrl(appConfig.getBasecallbackuri())
.setPlaySource(playSource)
.setOperationContext("holdPstnParticipant");
client.getCallConnection(callConnectionId).getCallMedia().holdWithResponse(holdOptions, Context.NONE);
/*
// Option 2: Hold without additional options
client.getCallConnection(callConnectionId).getCallMedia().hold(target);
*/
// Option 1: Hold with options
const options = {
playSource: playSource,
operationContext: "holdUserContext",
operationCallbackUrl: "URL" // replace with actual callback URL
};
await callMedia.hold(targetuser, options);
/*
// Option 2: Hold without additional options
await callMedia.hold(targetuser);
*/
# Option 1: Hold without additional options
call_connection_client.hold(target_participant=PhoneNumberIdentifier(TARGET_PHONE_NUMBER))
'''
# Option 2: Hold with options
call_connection_client.hold(
target_participant=PhoneNumberIdentifier(TARGET_PHONE_NUMBER),
play_source=play_source,
operation_context="holdUserContext",
operation_callback_url="URL" # replace with actual callback URL
)
'''
Unhold
保留アクションを使用すると、開発者は以前に一時停止した、参加者とシステムまたはエージェント間の会話を再開できます。 参加者が保留から解除されると、システムやエージェントを再び聞くことができます。
var unHoldOptions = new UnholdOptions(target)
{
OperationContext = "UnHoldPstnParticipant"
};
// Option 1
var UnHoldParticipant = await callMedia.UnholdAsync(unHoldOptions);
/*
// Option 2
var UnHoldParticipant = await callMedia.UnholdAsync(target);
*/
// Option 1
client.getCallConnection(callConnectionId).getCallMedia().unholdWithResponse(target, "unholdPstnParticipant", Context.NONE);
/*
// Option 2
client.getCallConnection(callConnectionId).getCallMedia().unhold(target);
*/
const unholdOptions = {
operationContext: "unholdUserContext"
};
// Option 1
await callMedia.unhold(target);
/*
// Option 2
await callMedia.unhold(target, unholdOptions);
*/
# Option 1
call_connection_client.unhold(target_participant=PhoneNumberIdentifier(TARGET_PHONE_NUMBER))
'''
# Option 2
call_connection_client.unhold(target_participant=PhoneNumberIdentifier(TARGET_PHONE_NUMBER), operation_context="holdUserContext")
'''
オーディオ ストリーミング
オーディオ ストリーミングを使用すると、進行中の通話からリアルタイムのオーディオ ストリームをサブスクライブできます。 オーディオ ストリーミングの概要と、オーディオ ストリーミング コールバック イベントの詳細については、「 クイック スタート: サーバー側オーディオ ストリーミング」を参照してください。
リアルタイム文字起こし
リアルタイムの文字起こしを使用すると、進行中の通話の音声のライブ文字起こしにアクセスできます。 リアルタイム文字起こしの概要と、リアルタイム文字起こしコールバック イベントに関する情報の詳細については、「リアルタイム文字 起こしをアプリケーションに追加する」を参照してください。
次の表は、前の操作がまだ実行中またはキューに入っている場合に実行またはキューに入れられているメディア操作を示しています。
| 既存の操作 |
通話区間 |
Allowed |
Disallowed |
PlayToAll |
Main |
PlayToAll、 Recognize(Non-Group Call)、 PlayTo、 Recognize(Group Call)、 SendDTMF、 StartContinuousDtmfRecognition |
None |
Recognize(Non-Group Call) |
Main |
PlayToAll、 Recognize(Non-Group Call)、 PlayTo、 Recognize(Group Call)、 SendDTMF、 StartContinuousDtmfRecognition |
None |
PlayTo |
Sub |
PlayToAll、Recognize(Non-Group Call) |
PlayTo、 Recognize(Group Call)、 SendDTMF、 StartContinuousDtmfRecognition |
Recognize(Group Call) |
Sub |
PlayToAll、Recognize(Non-Group Call) |
PlayTo、 Recognize(Group Call)、 SendDTMF、 StartContinuousDtmfRecognition |
SendDTMF |
Sub |
PlayToAll、Recognize(Non-Group Call) |
PlayTo、 Recognize(Group Call)、 SendDTMF、 StartContinuousDtmfRecognition |
StartContinuousDtmfRecognition |
Sub |
PlayToAll、 Recognize(Non-Group Call)、PlayTo、 Recognize(Group Call)、 SendDTMF、 StartContinuousDtmfRecognition |
None |