使用「辨識」動作收集使用者輸入

本指南將協助您開始透過 Azure 通訊服務通話自動化 SDK 來辨識參與者所提供的 DTMF 輸入。

必要條件

針對 AI 功能

技術規格

下列參數可用來自訂 Recognize 函式:

參數 類型 預設值 (如果未指定) 描述 必要或選用
Prompt

(如需播放動作的詳細資料,請參閱本操作指南)
FileSource、TextSource 未設定 這會是您想要在辨識輸入之前播放的訊息。 選擇性
InterToneTimeout TimeSpan 2 秒

最小值:1 秒
最大值:60 秒
Azure 通訊服務等候來電者按下另一個數字的秒數限制 (數字間逾時)。 選擇性
InitialSegmentationSilenceTimeoutInSeconds 整數 0.5 秒 辨識動作將輸入視為逾時之前等待輸入的時間長度。 請於此處深入了解。 選擇性
RecognizeInputsType 列舉 dtmf 辨識的輸入類型。 選項為 dtmf、choices、speech 和 speechordtmf。 必要
InitialSilenceTimeout TimeSpan 5 秒鐘

最小值:0 秒
最大值:300 秒 (DTMF)
最大值:20 秒 (Choices)
最大值:20 秒 (Speech)
初始無聲逾時會調整在辨識嘗試結束於「無相符項」結果之前,在片語之前允許多少非語音音訊。 請於此處深入了解。 選擇性
MaxTonesToCollect 整數 無預設值

最小值​1
開發人員預期參與者輸入的數字數目。 必要
StopTones IEnumeration<DtmfTone> 未設定 參與者可以按下以逸出批次 DTMF 事件的數字。 選擇性
InterruptPrompt Bool True 如果參與者按下數字,就能夠中斷 playMessage。 選擇性
InterruptCallMediaOperation Bool True 如果設定此旗標,則會中斷目前的通話媒體作業。 例如,如果正在播放任何音訊,則會中斷該作業並起始辨識。 選擇性
OperationContext String 未設定 開發人員可以傳遞中間動作的字串,適合讓開發人員儲存他們所接收事件的相關內容。 選擇性
片語 String 未設定 與標籤相關聯的片語清單,如果聽到其中任何一個片語,就會視為成功的辨識。 必要
語氣 String 未設定 使用者決定按數字而不是使用語音時所辨識的音調。 選擇性
標籤 String 未設定 辨識的關鍵值。 必要
語言 String En-us 用於辨識語音的語言。 選擇性
EndSilenceTimeout TimeSpan 0.5 秒 說話者的最後暫停,用來偵測產生為語音的最終結果。 選擇性

注意

在 dtmf 和 speech 都位於 recognizeInputsType 的情況下,辨識動作會對收到的第一個輸入類型執行,也就是如果使用者先按下鍵盤號碼,辨識動作就會將其視為 dtmf 事件,並繼續接聽 dtmf 音調。 如果使用者先說話,則辨識動作會將其視為語音辨識,並接聽語音輸入。

建立新的 C# 應用程式

在作業系統的主控台視窗中,使用 dotnet 命令建立新的 Web 應用程式。

dotnet new web -n MyApplication

安裝 NuGet 封裝

如果您尚未取得 NuGet 套件,可以從這裡取得。

建立通話

這時您應該已熟悉開始通話。如果您需要深入了解如何撥打電話,請遵循我們的快速入門。 您也可以使用這裡提供的程式碼片段來了解如何接聽來電。

var callAutomationClient = new CallAutomationClient("<Azure Communication Services connection string>");

var answerCallOptions = new AnswerCallOptions("<Incoming call context once call is connected>", new Uri("<https://sample-callback-uri>"))  
{  
    CallIntelligenceOptions = new CallIntelligenceOptions() { CognitiveServicesEndpoint = new Uri("<Azure Cognitive Services Endpoint>") } 
};  

var answerCallResult = await callAutomationClient.AnswerCallAsync(answerCallOptions); 

呼叫辨識動作

當應用程式接聽來電時,您可以提供有關辨識參與者輸入和播放提示的資訊。

DTMF

var maxTonesToCollect = 3;
String textToPlay = "Welcome to Contoso, please enter 3 DTMF.";
var playSource = new TextSource(textToPlay, "en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeDtmfOptions(targetParticipant, maxTonesToCollect) {
  InitialSilenceTimeout = TimeSpan.FromSeconds(30),
    Prompt = playSource,
    InterToneTimeout = TimeSpan.FromSeconds(5),
    InterruptPrompt = true,
    StopTones = new DtmfTone[] {
      DtmfTone.Pound
    },
};
var recognizeResult = await callAutomationClient.GetCallConnection(callConnectionId)
  .GetCallMedia()
  .StartRecognizingAsync(recognizeOptions);

對於語音轉換文字流程,通話自動化辨識動作也支援使用自訂語音模型。 若您要建置的應用程式需要接聽複雜的文字,但預設的語音轉換文字模型可能無法理解時,自訂語音模型之類的功能可能有其效用;例如,當您為遠距醫療產業建置應用程式,而您的虛擬專員必須能夠辨識醫療詞彙時,就是如此。 您可以在這裏深入了解如何建立和部署自訂語音模型。

語音轉換文字選項

var choices = 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
  }
};
String textToPlay = "Hello, This is a reminder for your appointment at 2 PM, Say Confirm to confirm your appointment or Cancel to cancel the appointment. Thank you!";

var playSource = new TextSource(textToPlay, "en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeChoiceOptions(targetParticipant, choices) {
  InterruptPrompt = true,
    InitialSilenceTimeout = TimeSpan.FromSeconds(30),
    Prompt = playSource,
    OperationContext = "AppointmentReminderMenu",
    //Only add the SpeechModelEndpointId if you have a custom speech model you would like to use
    SpeechModelEndpointId = "YourCustomSpeechModelEndpointId"
};
var recognizeResult = await callAutomationClient.GetCallConnection(callConnectionId)
  .GetCallMedia()
  .StartRecognizingAsync(recognizeOptions);

語音轉換文字

String textToPlay = "Hi, how can I help you today?";
var playSource = new TextSource(textToPlay, "en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeSpeechOptions(targetParticipant) {
  Prompt = playSource,
    EndSilenceTimeout = TimeSpan.FromMilliseconds(1000),
    OperationContext = "OpenQuestionSpeech",
    //Only add the SpeechModelEndpointId if you have a custom speech model you would like to use
    SpeechModelEndpointId = "YourCustomSpeechModelEndpointId"
};
var recognizeResult = await callAutomationClient.GetCallConnection(callConnectionId)
  .GetCallMedia()
  .StartRecognizingAsync(recognizeOptions);

語音轉換文字或 DTMF

var maxTonesToCollect = 1; 
String textToPlay = "Hi, how can I help you today, you can press 0 to speak to an agent?"; 
var playSource = new TextSource(textToPlay, "en-US-ElizabethNeural"); 
var recognizeOptions = new CallMediaRecognizeSpeechOrDtmfOptions(targetParticipant, maxTonesToCollect) 
{ 
    Prompt = playSource, 
    EndSilenceTimeout = TimeSpan.FromMilliseconds(1000), 
    InitialSilenceTimeout = TimeSpan.FromSeconds(30), 
    InterruptPrompt = true, 
    OperationContext = "OpenQuestionSpeechOrDtmf",
    //Only add the SpeechModelEndpointId if you have a custom speech model you would like to use
    SpeechModelEndpointId = "YourCustomSpeechModelEndpointId" 
}; 
var recognizeResult = await callAutomationClient.GetCallConnection(callConnectionId) 
    .GetCallMedia() 
    .StartRecognizingAsync(recognizeOptions); 

注意

若未設定參數,則會在可行時套用預設值。

接收辨識事件更新

開發人員可以在他們為通話註冊的 Webhook 回呼上訂閱 RecognizeCompletedRecognizeFailed 事件,以在其應用程式中建立商務邏輯,而在發生上述其中一個事件時判斷後續步驟。

如何還原序列化 RecognizeCompleted 事件的範例:

if (acsEvent is RecognizeCompleted recognizeCompleted) 
{ 
    switch (recognizeCompleted.RecognizeResult) 
    { 
        case DtmfResult dtmfResult: 
            //Take action for Recognition through DTMF 
            var tones = dtmfResult.Tones; 
            logger.LogInformation("Recognize completed succesfully, tones={tones}", tones); 
            break; 
        case ChoiceResult choiceResult: 
            // Take action for Recognition through Choices 
            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);
            break; 
        case SpeechResult speechResult: 
            // Take action for Recognition through Choices 
            var text = speechResult.Speech; 
            logger.LogInformation("Recognize completed succesfully, text={text}", text); 
            break; 
        default: 
            logger.LogInformation("Recognize completed succesfully, recognizeResult={recognizeResult}", recognizeCompleted.RecognizeResult); 
            break; 
    } 
} 

如何還原序列化 RecognizeFailed 事件的範例:

if (acsEvent is RecognizeFailed recognizeFailed) 
{ 
    if (MediaEventReasonCode.RecognizeInitialSilenceTimedOut.Equals(recognizeFailed.ReasonCode)) 
    { 
        // Take action for time out 
        logger.LogInformation("Recognition failed: initial silencev time out"); 
    } 
    else if (MediaEventReasonCode.RecognizeSpeechOptionNotMatched.Equals(recognizeFailed.ReasonCode)) 
    { 
        // Take action for option not matched 
        logger.LogInformation("Recognition failed: speech option not matched"); 
    } 
    else if (MediaEventReasonCode.RecognizeIncorrectToneDetected.Equals(recognizeFailed.ReasonCode)) 
    { 
        // Take action for incorrect tone 
        logger.LogInformation("Recognition failed: incorrect tone detected"); 
    } 
    else 
    { 
        logger.LogInformation("Recognition failed, result={result}, context={context}", recognizeFailed.ResultInformation?.Message, recognizeFailed.OperationContext); 
    } 
} 

如何還原序列化 RecognizeCanceled 事件的範例:

if (acsEvent is RecognizeCanceled { OperationContext: "AppointmentReminderMenu" })
        {
            logger.LogInformation($"RecognizeCanceled event received for call connection id: {@event.CallConnectionId}");
            //Take action on recognize canceled operation
           await callConnection.HangUpAsync(forEveryone: true);
        }

必要條件

針對 AI 功能

技術規格

下列參數可用來自訂 Recognize 函式:

參數 類型 預設值 (如果未指定) 描述 必要或選用
Prompt

(如需播放動作的詳細資料,請參閱本操作指南)
FileSource、TextSource 未設定 這會是您想要在辨識輸入之前播放的訊息。 選擇性
InterToneTimeout TimeSpan 2 秒

最小值:1 秒
最大值:60 秒
Azure 通訊服務等候來電者按下另一個數字的秒數限制 (數字間逾時)。 選擇性
InitialSegmentationSilenceTimeoutInSeconds 整數 0.5 秒 辨識動作將輸入視為逾時之前等待輸入的時間長度。 請於此處深入了解。 選擇性
RecognizeInputsType 列舉 dtmf 辨識的輸入類型。 選項為 dtmf、choices、speech 和 speechordtmf。 必要
InitialSilenceTimeout TimeSpan 5 秒鐘

最小值:0 秒
最大值:300 秒 (DTMF)
最大值:20 秒 (Choices)
最大值:20 秒 (Speech)
初始無聲逾時會調整在辨識嘗試結束於「無相符項」結果之前,在片語之前允許多少非語音音訊。 請於此處深入了解。 選擇性
MaxTonesToCollect 整數 無預設值

最小值​1
開發人員預期參與者輸入的數字數目。 必要
StopTones IEnumeration<DtmfTone> 未設定 參與者可以按下以逸出批次 DTMF 事件的數字。 選擇性
InterruptPrompt Bool True 如果參與者按下數字,就能夠中斷 playMessage。 選擇性
InterruptCallMediaOperation Bool True 如果設定此旗標,則會中斷目前的通話媒體作業。 例如,如果正在播放任何音訊,則會中斷該作業並起始辨識。 選擇性
OperationContext String 未設定 開發人員可以傳遞中間動作的字串,適合讓開發人員儲存他們所接收事件的相關內容。 選擇性
片語 String 未設定 與標籤相關聯的片語清單,如果聽到其中任何一個片語,就會視為成功的辨識。 必要
語氣 String 未設定 使用者決定按數字而不是使用語音時所辨識的音調。 選擇性
標籤 String 未設定 辨識的關鍵值。 必要
語言 String En-us 用於辨識語音的語言。 選擇性
EndSilenceTimeout TimeSpan 0.5 秒 說話者的最後暫停,用來偵測產生為語音的最終結果。 選擇性

注意

在 dtmf 和 speech 都位於 recognizeInputsType 的情況下,辨識動作會對收到的第一個輸入類型執行,也就是如果使用者先按下鍵盤號碼,辨識動作就會將其視為 dtmf 事件,並繼續接聽 dtmf 音調。 如果使用者先說話,則辨識動作會將其視為語音辨識,並接聽語音輸入。

建立新的 Java 應用程式

在您的終端機或命令視窗中,瀏覽至您想要在其中建立 JAVA 應用程式的目錄。 執行 mvn 命令以從 maven-archetype-quickstart 範本產生 Java 專案。

mvn archetype:generate -DgroupId=com.communication.quickstart -DartifactId=communication-quickstart -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false

mvn 命令會建立與 artifactId 引數相同名稱的目錄。 在此目錄底下,src/main/java 目錄包含專案原始程式碼,src/test/java 目錄則包含測試來源。

您會發現 'generate' 步驟建立了與 artifactId 同名的目錄。 在此目錄底下,src/main/java 目錄包含原始程式碼,src/test/java 目錄包含測試,而 pom.xml 檔案則是專案的「專案物件模型」(簡稱 POM)。

將應用程式的 POM 檔案更新為使用 JAVA 8 或更高版本。

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

新增套件參考

在您的 POM 檔案中新增專案的以下參考

azure-communication-callautomation

<dependency>
  <groupId>com.azure</groupId>
  <artifactId>azure-communication-callautomation</artifactId>
  <version>1.0.0</version>
</dependency>

建立通話

這時您應該已熟悉開始通話。如果您需要深入了解如何撥打電話,請遵循我們的快速入門。 您也可以使用這裡提供的程式碼片段來了解如何接聽來電。

CallIntelligenceOptions callIntelligenceOptions = new CallIntelligenceOptions().setCognitiveServicesEndpoint("https://sample-cognitive-service-resource.cognitiveservices.azure.com/"); 
answerCallOptions = new AnswerCallOptions("<Incoming call context>", "<https://sample-callback-uri>").setCallIntelligenceOptions(callIntelligenceOptions); 
Response < AnswerCallResult > answerCallResult = callAutomationClient
  .answerCallWithResponse(answerCallOptions)
  .block();

呼叫辨識動作

當應用程式接聽來電時,您可以提供有關辨識參與者輸入和播放提示的資訊。

DTMF

var maxTonesToCollect = 3;
String textToPlay = "Welcome to Contoso, please enter 3 DTMF.";
var playSource = new TextSource() 
    .setText(textToPlay) 
    .setVoiceName("en-US-ElizabethNeural");

var recognizeOptions = new CallMediaRecognizeDtmfOptions(targetParticipant, maxTonesToCollect) 
    .setInitialSilenceTimeout(Duration.ofSeconds(30)) 
    .setPlayPrompt(playSource) 
    .setInterToneTimeout(Duration.ofSeconds(5)) 
    .setInterruptPrompt(true) 
    .setStopTones(Arrays.asList(DtmfTone.POUND));

var recognizeResponse = callAutomationClient.getCallConnectionAsync(callConnectionId) 
    .getCallMediaAsync() 
    .startRecognizingWithResponse(recognizeOptions) 
    .block(); 

log.info("Start recognizing result: " + recognizeResponse.getStatusCode()); 

對於語音轉換文字流程,通話自動化辨識動作也支援使用自訂語音模型。 若您要建置的應用程式需要接聽複雜的文字,但預設的語音轉換文字模型可能無法理解時,自訂語音模型之類的功能可能有其效用;例如,當您為遠距醫療產業建置應用程式,而您的虛擬專員必須能夠辨識醫療詞彙時,就是如此。 您可以在這裏深入了解如何建立和部署自訂語音模型。

語音轉換文字選項

var choices = Arrays.asList(
  new RecognitionChoice()
  .setLabel("Confirm")
  .setPhrases(Arrays.asList("Confirm", "First", "One"))
  .setTone(DtmfTone.ONE),
  new RecognitionChoice()
  .setLabel("Cancel")
  .setPhrases(Arrays.asList("Cancel", "Second", "Two"))
  .setTone(DtmfTone.TWO)
);

String textToPlay = "Hello, This is a reminder for your appointment at 2 PM, Say Confirm to confirm your appointment or Cancel to cancel the appointment. Thank you!";
var playSource = new TextSource()
  .setText(textToPlay)
  .setVoiceName("en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeChoiceOptions(targetParticipant, choices)
  .setInterruptPrompt(true)
  .setInitialSilenceTimeout(Duration.ofSeconds(30))
  .setPlayPrompt(playSource)
  .setOperationContext("AppointmentReminderMenu")
  //Only add the SpeechRecognitionModelEndpointId if you have a custom speech model you would like to use
  .setSpeechRecognitionModelEndpointId("YourCustomSpeechModelEndpointID"); 
var recognizeResponse = callAutomationClient.getCallConnectionAsync(callConnectionId)
  .getCallMediaAsync()
  .startRecognizingWithResponse(recognizeOptions)
  .block();

語音轉換文字

String textToPlay = "Hi, how can I help you today?"; 
var playSource = new TextSource() 
    .setText(textToPlay) 
    .setVoiceName("en-US-ElizabethNeural"); 
var recognizeOptions = new CallMediaRecognizeSpeechOptions(targetParticipant, Duration.ofMillis(1000)) 
    .setPlayPrompt(playSource) 
    .setOperationContext("OpenQuestionSpeech")
    //Only add the SpeechRecognitionModelEndpointId if you have a custom speech model you would like to use
    .setSpeechRecognitionModelEndpointId("YourCustomSpeechModelEndpointID");  
var recognizeResponse = callAutomationClient.getCallConnectionAsync(callConnectionId) 
    .getCallMediaAsync() 
    .startRecognizingWithResponse(recognizeOptions) 
    .block(); 

語音轉換文字或 DTMF

var maxTonesToCollect = 1; 
String textToPlay = "Hi, how can I help you today, you can press 0 to speak to an agent?"; 
var playSource = new TextSource() 
    .setText(textToPlay) 
    .setVoiceName("en-US-ElizabethNeural"); 
var recognizeOptions = new CallMediaRecognizeSpeechOrDtmfOptions(targetParticipant, maxTonesToCollect, Duration.ofMillis(1000)) 
    .setPlayPrompt(playSource) 
    .setInitialSilenceTimeout(Duration.ofSeconds(30)) 
    .setInterruptPrompt(true) 
    .setOperationContext("OpenQuestionSpeechOrDtmf")
    //Only add the SpeechRecognitionModelEndpointId if you have a custom speech model you would like to use
    .setSpeechRecognitionModelEndpointId("YourCustomSpeechModelEndpointID");  
var recognizeResponse = callAutomationClient.getCallConnectionAsync(callConnectionId) 
    .getCallMediaAsync() 
    .startRecognizingWithResponse(recognizeOptions) 
    .block(); 

注意

若未設定參數,則會在可行時套用預設值。

接收辨識事件更新

開發人員可以在已註冊的 Webhook 回呼上訂閱 RecognizeCompletedRecognizeFailed 事件。 此回呼可與應用程式中的商務邏輯搭配使用,以判斷其中一個事件發生時的後續步驟。

如何還原序列化 RecognizeCompleted 事件的範例:

if (acsEvent instanceof RecognizeCompleted) { 
    RecognizeCompleted event = (RecognizeCompleted) acsEvent; 
    RecognizeResult recognizeResult = event.getRecognizeResult().get(); 
    if (recognizeResult instanceof DtmfResult) { 
        // Take action on collect tones 
        DtmfResult dtmfResult = (DtmfResult) recognizeResult; 
        List<DtmfTone> tones = dtmfResult.getTones(); 
        log.info("Recognition completed, tones=" + tones + ", context=" + event.getOperationContext()); 
    } else if (recognizeResult instanceof ChoiceResult) { 
        ChoiceResult collectChoiceResult = (ChoiceResult) recognizeResult; 
        String labelDetected = collectChoiceResult.getLabel(); 
        String phraseDetected = collectChoiceResult.getRecognizedPhrase(); 
        log.info("Recognition completed, labelDetected=" + labelDetected + ", phraseDetected=" + phraseDetected + ", context=" + event.getOperationContext()); 
    } else if (recognizeResult instanceof SpeechResult) { 
        SpeechResult speechResult = (SpeechResult) recognizeResult; 
        String text = speechResult.getSpeech(); 
        log.info("Recognition completed, text=" + text + ", context=" + event.getOperationContext()); 
    } else { 
        log.info("Recognition completed, result=" + recognizeResult + ", context=" + event.getOperationContext()); 
    } 
} 

如何還原序列化 RecognizeFailed 事件的範例:

if (acsEvent instanceof RecognizeFailed) { 
    RecognizeFailed event = (RecognizeFailed) acsEvent; 
    if (ReasonCode.Recognize.INITIAL_SILENCE_TIMEOUT.equals(event.getReasonCode())) { 
        // Take action for time out 
        log.info("Recognition failed: initial silence time out"); 
    } else if (ReasonCode.Recognize.SPEECH_OPTION_NOT_MATCHED.equals(event.getReasonCode())) { 
        // Take action for option not matched 
        log.info("Recognition failed: speech option not matched"); 
    } else if (ReasonCode.Recognize.DMTF_OPTION_MATCHED.equals(event.getReasonCode())) { 
        // Take action for incorrect tone 
        log.info("Recognition failed: incorrect tone detected"); 
    } else { 
        log.info("Recognition failed, result=" + event.getResultInformation().getMessage() + ", context=" + event.getOperationContext()); 
    } 
} 

如何還原序列化 RecognizeCanceled 事件的範例:

if (acsEvent instanceof RecognizeCanceled) { 
    RecognizeCanceled event = (RecognizeCanceled) acsEvent; 
    log.info("Recognition canceled, context=" + event.getOperationContext()); 
}

必要條件

針對 AI 功能

技術規格

下列參數可用來自訂 Recognize 函式:

參數 類型 預設值 (如果未指定) 描述 必要或選用
Prompt

(如需播放動作的詳細資料,請參閱本操作指南)
FileSource、TextSource 未設定 這會是您想要在辨識輸入之前播放的訊息。 選擇性
InterToneTimeout TimeSpan 2 秒

最小值:1 秒
最大值:60 秒
Azure 通訊服務等候來電者按下另一個數字的秒數限制 (數字間逾時)。 選擇性
InitialSegmentationSilenceTimeoutInSeconds 整數 0.5 秒 辨識動作將輸入視為逾時之前等待輸入的時間長度。 請於此處深入了解。 選擇性
RecognizeInputsType 列舉 dtmf 辨識的輸入類型。 選項為 dtmf、choices、speech 和 speechordtmf。 必要
InitialSilenceTimeout TimeSpan 5 秒鐘

最小值:0 秒
最大值:300 秒 (DTMF)
最大值:20 秒 (Choices)
最大值:20 秒 (Speech)
初始無聲逾時會調整在辨識嘗試結束於「無相符項」結果之前,在片語之前允許多少非語音音訊。 請於此處深入了解。 選擇性
MaxTonesToCollect 整數 無預設值

最小值​1
開發人員預期參與者輸入的數字數目。 必要
StopTones IEnumeration<DtmfTone> 未設定 參與者可以按下以逸出批次 DTMF 事件的數字。 選擇性
InterruptPrompt Bool True 如果參與者按下數字,就能夠中斷 playMessage。 選擇性
InterruptCallMediaOperation Bool True 如果設定此旗標,則會中斷目前的通話媒體作業。 例如,如果正在播放任何音訊,則會中斷該作業並起始辨識。 選擇性
OperationContext String 未設定 開發人員可以傳遞中間動作的字串,適合讓開發人員儲存他們所接收事件的相關內容。 選擇性
片語 String 未設定 與標籤相關聯的片語清單,如果聽到其中任何一個片語,就會視為成功的辨識。 必要
語氣 String 未設定 使用者決定按數字而不是使用語音時所辨識的音調。 選擇性
標籤 String 未設定 辨識的關鍵值。 必要
語言 String En-us 用於辨識語音的語言。 選擇性
EndSilenceTimeout TimeSpan 0.5 秒 說話者的最後暫停,用來偵測產生為語音的最終結果。 選擇性

注意

在 dtmf 和 speech 都位於 recognizeInputsType 的情況下,辨識動作會對收到的第一個輸入類型執行,也就是如果使用者先按下鍵盤號碼,辨識動作就會將其視為 dtmf 事件,並繼續接聽 dtmf 音調。 如果使用者先說話,則辨識動作會將其視為語音辨識,並接聽語音輸入。

建立新的 JavaScript 應用程式

在您的專案目錄中建立新的 JavaScript 應用程式。 使用下列命令初始化新的 Node.js 專案。 這會為您的專案建立 package.json 檔案,用來管理專案的相依性。

npm init -y

安裝 Azure 通訊服務通話自動化套件

npm install @azure/communication-call-automation

例如,在您的專案目錄中建立新的 JavaScript 檔案,將其命名為 app.js。 您會在此檔案中撰寫 JavaScript 程式碼。 搭配使用 Node.js 與下列命令執行您的應用程式。 這會執行您已撰寫的 JavaScript 程式碼。

node app.js

建立通話

這時您應該已熟悉開始通話。如果您需要深入了解如何撥打電話,請遵循我們的快速入門。 在本快速入門中,我們會建立撥出電話。

呼叫辨識動作

當應用程式接聽來電時,您可以提供有關辨識參與者輸入和播放提示的資訊。

DTMF

const maxTonesToCollect = 3; 
const textToPlay = "Welcome to Contoso, please enter 3 DTMF."; 
const playSource: TextSource = { text: textToPlay, voiceName: "en-US-ElizabethNeural", kind: "textSource" }; 
const recognizeOptions: CallMediaRecognizeDtmfOptions = { 
    maxTonesToCollect: maxTonesToCollect, 
    initialSilenceTimeoutInSeconds: 30, 
    playPrompt: playSource, 
    interToneTimeoutInSeconds: 5, 
    interruptPrompt: true, 
    stopDtmfTones: [ DtmfTone.Pound ], 
    kind: "callMediaRecognizeDtmfOptions" 
}; 

await callAutomationClient.getCallConnection(callConnectionId) 
    .getCallMedia() 
    .startRecognizing(targetParticipant, recognizeOptions); 

對於語音轉換文字流程,通話自動化辨識動作也支援使用自訂語音模型。 若您要建置的應用程式需要接聽複雜的文字,但預設的語音轉換文字模型可能無法理解時,自訂語音模型之類的功能可能有其效用;例如,當您為遠距醫療產業建置應用程式,而您的虛擬專員必須能夠辨識醫療詞彙時,就是如此。 您可以在這裏深入了解如何建立和部署自訂語音模型。

語音轉換文字選項

const choices = [ 
    {  
        label: "Confirm", 
        phrases: [ "Confirm", "First", "One" ], 
        tone: DtmfTone.One 
    }, 
    { 
        label: "Cancel", 
        phrases: [ "Cancel", "Second", "Two" ], 
        tone: DtmfTone.Two 
    } 
]; 

const textToPlay = "Hello, This is a reminder for your appointment at 2 PM, Say Confirm to confirm your appointment or Cancel to cancel the appointment. Thank you!"; 
const playSource: TextSource = { text: textToPlay, voiceName: "en-US-ElizabethNeural", kind: "textSource" }; 
const recognizeOptions: CallMediaRecognizeChoiceOptions = { 
    choices: choices, 
    interruptPrompt: true, 
    initialSilenceTimeoutInSeconds: 30, 
    playPrompt: playSource, 
    operationContext: "AppointmentReminderMenu", 
    kind: "callMediaRecognizeChoiceOptions",
    //Only add the speechRecognitionModelEndpointId if you have a custom speech model you would like to use
    speechRecognitionModelEndpointId: "YourCustomSpeechEndpointId"
}; 

await callAutomationClient.getCallConnection(callConnectionId) 
    .getCallMedia() 
    .startRecognizing(targetParticipant, recognizeOptions); 

語音轉換文字

const textToPlay = "Hi, how can I help you today?"; 
const playSource: TextSource = { text: textToPlay, voiceName: "en-US-ElizabethNeural", kind: "textSource" }; 
const recognizeOptions: CallMediaRecognizeSpeechOptions = { 
    endSilenceTimeoutInSeconds: 1, 
    playPrompt: playSource, 
    operationContext: "OpenQuestionSpeech", 
    kind: "callMediaRecognizeSpeechOptions",
    //Only add the speechRecognitionModelEndpointId if you have a custom speech model you would like to use
    speechRecognitionModelEndpointId: "YourCustomSpeechEndpointId"
}; 

await callAutomationClient.getCallConnection(callConnectionId) 
    .getCallMedia() 
    .startRecognizing(targetParticipant, recognizeOptions); 

語音轉換文字或 DTMF

const maxTonesToCollect = 1; 
const textToPlay = "Hi, how can I help you today, you can press 0 to speak to an agent?"; 
const playSource: TextSource = { text: textToPlay, voiceName: "en-US-ElizabethNeural", kind: "textSource" }; 
const recognizeOptions: CallMediaRecognizeSpeechOrDtmfOptions = { 
    maxTonesToCollect: maxTonesToCollect, 
    endSilenceTimeoutInSeconds: 1, 
    playPrompt: playSource, 
    initialSilenceTimeoutInSeconds: 30, 
    interruptPrompt: true, 
    operationContext: "OpenQuestionSpeechOrDtmf", 
    kind: "callMediaRecognizeSpeechOrDtmfOptions",
    //Only add the speechRecognitionModelEndpointId if you have a custom speech model you would like to use
    speechRecognitionModelEndpointId: "YourCustomSpeechEndpointId"
}; 

await callAutomationClient.getCallConnection(callConnectionId) 
    .getCallMedia() 
    .startRecognizing(targetParticipant, recognizeOptions); 

注意

若未設定參數,則會在可行時套用預設值。

接收辨識事件更新

開發人員可以在他們為通話註冊的 Webhook 回呼上訂閱 RecognizeCompletedRecognizeFailed 事件,以在其應用程式中建立商務邏輯,而在發生上述其中一個事件時判斷後續步驟。

如何還原序列化 RecognizeCompleted 事件的範例:

if (event.type === "Microsoft.Communication.RecognizeCompleted") { 
    if (eventData.recognitionType === "dtmf") { 
        const tones = eventData.dtmfResult.tones; 
        console.log("Recognition completed, tones=%s, context=%s", tones, eventData.operationContext); 
    } else if (eventData.recognitionType === "choices") { 
        const labelDetected = eventData.choiceResult.label; 
        const phraseDetected = eventData.choiceResult.recognizedPhrase; 
        console.log("Recognition completed, labelDetected=%s, phraseDetected=%s, context=%s", labelDetected, phraseDetected, eventData.operationContext); 
    } else if (eventData.recognitionType === "speech") { 
        const text = eventData.speechResult.speech; 
        console.log("Recognition completed, text=%s, context=%s", text, eventData.operationContext); 
    } else { 
        console.log("Recognition completed: data=%s", JSON.stringify(eventData, null, 2)); 
    } 
} 

如何還原序列化 RecognizeFailed 事件的範例:

if (event.type === "Microsoft.Communication.RecognizeFailed") {
    console.log("Recognize failed: data=%s", JSON.stringify(eventData, null, 2));
}

如何還原序列化 RecognizeCanceled 事件的範例:

if (event.type === "Microsoft.Communication.RecognizeCanceled") {
    console.log("Recognize canceled, context=%s", eventData.operationContext);
}

必要條件

針對 AI 功能

技術規格

下列參數可用來自訂 Recognize 函式:

參數 類型 預設值 (如果未指定) 描述 必要或選用
Prompt

(如需播放動作的詳細資料,請參閱本操作指南)
FileSource、TextSource 未設定 這會是您想要在辨識輸入之前播放的訊息。 選擇性
InterToneTimeout TimeSpan 2 秒

最小值:1 秒
最大值:60 秒
Azure 通訊服務等候來電者按下另一個數字的秒數限制 (數字間逾時)。 選擇性
InitialSegmentationSilenceTimeoutInSeconds 整數 0.5 秒 辨識動作將輸入視為逾時之前等待輸入的時間長度。 請於此處深入了解。 選擇性
RecognizeInputsType 列舉 dtmf 辨識的輸入類型。 選項為 dtmf、choices、speech 和 speechordtmf。 必要
InitialSilenceTimeout TimeSpan 5 秒鐘

最小值:0 秒
最大值:300 秒 (DTMF)
最大值:20 秒 (Choices)
最大值:20 秒 (Speech)
初始無聲逾時會調整在辨識嘗試結束於「無相符項」結果之前,在片語之前允許多少非語音音訊。 請於此處深入了解。 選擇性
MaxTonesToCollect 整數 無預設值

最小值​1
開發人員預期參與者輸入的數字數目。 必要
StopTones IEnumeration<DtmfTone> 未設定 參與者可以按下以逸出批次 DTMF 事件的數字。 選擇性
InterruptPrompt Bool True 如果參與者按下數字,就能夠中斷 playMessage。 選擇性
InterruptCallMediaOperation Bool True 如果設定此旗標,則會中斷目前的通話媒體作業。 例如,如果正在播放任何音訊,則會中斷該作業並起始辨識。 選擇性
OperationContext String 未設定 開發人員可以傳遞中間動作的字串,適合讓開發人員儲存他們所接收事件的相關內容。 選擇性
片語 String 未設定 與標籤相關聯的片語清單,如果聽到其中任何一個片語,就會視為成功的辨識。 必要
語氣 String 未設定 使用者決定按數字而不是使用語音時所辨識的音調。 選擇性
標籤 String 未設定 辨識的關鍵值。 必要
語言 String En-us 用於辨識語音的語言。 選擇性
EndSilenceTimeout TimeSpan 0.5 秒 說話者的最後暫停,用來偵測產生為語音的最終結果。 選擇性

注意

在 dtmf 和 speech 都位於 recognizeInputsType 的情況下,辨識動作會對收到的第一個輸入類型執行,也就是如果使用者先按下鍵盤號碼,辨識動作就會將其視為 dtmf 事件,並繼續接聽 dtmf 音調。 如果使用者先說話,則辨識動作會將其視為語音辨識,並接聽語音輸入。

建立新的 Python 應用程式

為您的專案設定 Python 虛擬環境

python -m venv play-audio-app

啟動虛擬環境

在 Windows 上,請使用下列命令:

.\ play-audio-quickstart \Scripts\activate

在 Unix 上,請使用下列命令:

source play-audio-quickstart /bin/activate

安裝 Azure 通訊服務通話自動化套件

pip install azure-communication-callautomation

例如,在您的專案目錄中建立應用程式檔案,將其命名為 app.py。 您會在此檔案中撰寫 Python 程式碼。

搭配使用 Python 與下列命令執行您的應用程式。 這會執行您已撰寫的 Python 程式碼。

python app.py

建立通話

這時您應該已熟悉開始通話。如果您需要深入了解如何撥打電話,請遵循我們的快速入門。 在本快速入門中,我們會建立撥出電話。

呼叫辨識動作

當應用程式接聽來電時,您可以提供有關辨識參與者輸入和播放提示的資訊。

DTMF

max_tones_to_collect = 3 
text_to_play = "Welcome to Contoso, please enter 3 DTMF." 
play_source = TextSource(text=text_to_play, voice_name="en-US-ElizabethNeural") 
call_automation_client.get_call_connection(call_connection_id).start_recognizing_media( 
    dtmf_max_tones_to_collect=max_tones_to_collect, 
    input_type=RecognizeInputType.DTMF, 
    target_participant=target_participant, 
    initial_silence_timeout=30, 
    play_prompt=play_source, 
    dtmf_inter_tone_timeout=5, 
    interrupt_prompt=True, 
    dtmf_stop_tones=[ DtmfTone.Pound ]) 

對於語音轉換文字流程,通話自動化辨識動作也支援使用自訂語音模型。 若您要建置的應用程式需要接聽複雜的文字,但預設的語音轉換文字模型可能無法理解時,自訂語音模型之類的功能可能有其效用;例如,當您為遠距醫療產業建置應用程式,而您的虛擬專員必須能夠辨識醫療詞彙時,就是如此。 您可以在這裏深入了解如何建立和部署自訂語音模型。

語音轉換文字選項

choices = [ 
    RecognitionChoice( 
        label="Confirm", 
        phrases=[ "Confirm", "First", "One" ], 
        tone=DtmfTone.ONE 
    ), 
    RecognitionChoice( 
        label="Cancel", 
        phrases=[ "Cancel", "Second", "Two" ], 
        tone=DtmfTone.TWO 
    ) 
] 
text_to_play = "Hello, This is a reminder for your appointment at 2 PM, Say Confirm to confirm your appointment or Cancel to cancel the appointment. Thank you!" 
play_source = TextSource(text=text_to_play, voice_name="en-US-ElizabethNeural") 
call_automation_client.get_call_connection(call_connection_id).start_recognizing_media( 
    input_type=RecognizeInputType.CHOICES, 
    target_participant=target_participant, 
    choices=choices, 
    interrupt_prompt=True, 
    initial_silence_timeout=30, 
    play_prompt=play_source, 
    operation_context="AppointmentReminderMenu",
    # Only add the speech_recognition_model_endpoint_id if you have a custom speech model you would like to use
    speech_recognition_model_endpoint_id="YourCustomSpeechModelEndpointId")  

語音轉換文字

text_to_play = "Hi, how can I help you today?" 
play_source = TextSource(text=text_to_play, voice_name="en-US-ElizabethNeural") 
call_automation_client.get_call_connection(call_connection_id).start_recognizing_media( 
    input_type=RecognizeInputType.SPEECH, 
    target_participant=target_participant, 
    end_silence_timeout=1, 
    play_prompt=play_source, 
    operation_context="OpenQuestionSpeech",
    # Only add the speech_recognition_model_endpoint_id if you have a custom speech model you would like to use
    speech_recognition_model_endpoint_id="YourCustomSpeechModelEndpointId") 

語音轉換文字或 DTMF

max_tones_to_collect = 1 
text_to_play = "Hi, how can I help you today, you can also press 0 to speak to an agent." 
play_source = TextSource(text=text_to_play, voice_name="en-US-ElizabethNeural") 
call_automation_client.get_call_connection(call_connection_id).start_recognizing_media( 
    dtmf_max_tones_to_collect=max_tones_to_collect, 
    input_type=RecognizeInputType.SPEECH_OR_DTMF, 
    target_participant=target_participant, 
    end_silence_timeout=1, 
    play_prompt=play_source, 
    initial_silence_timeout=30, 
    interrupt_prompt=True, 
    operation_context="OpenQuestionSpeechOrDtmf",
    # Only add the speech_recognition_model_endpoint_id if you have a custom speech model you would like to use
    speech_recognition_model_endpoint_id="YourCustomSpeechModelEndpointId")  
app.logger.info("Start recognizing") 

注意

若未設定參數,則會在可行時套用預設值。

接收辨識事件更新

開發人員可以在他們為通話註冊的 Webhook 回呼上訂閱 RecognizeCompletedRecognizeFailed 事件,以在其應用程式中建立商務邏輯,而在發生上述其中一個事件時判斷後續步驟。

如何還原序列化 RecognizeCompleted 事件的範例:

if event.type == "Microsoft.Communication.RecognizeCompleted": 
    app.logger.info("Recognize completed: data=%s", event.data) 
    if event.data['recognitionType'] == "dtmf": 
        tones = event.data['dtmfResult']['tones'] 
        app.logger.info("Recognition completed, tones=%s, context=%s", tones, event.data.get('operationContext')) 
    elif 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')); 
    elif event.data['recognitionType'] == "speech": 
        text = event.data['speechResult']['speech']; 
        app.logger.info("Recognition completed, text=%s, context=%s", text, event.data.get('operationContext')); 
    else: 
        app.logger.info("Recognition completed: data=%s", event.data); 

如何還原序列化 RecognizeFailed 事件的範例:

if event.type == "Microsoft.Communication.RecognizeFailed": 
    app.logger.info("Recognize failed: data=%s", event.data); 

如何還原序列化 RecognizeCanceled 事件的範例:

if event.type == "Microsoft.Communication.RecognizeCanceled":
    # Handle the RecognizeCanceled event according to your application logic

事件代碼

狀態 代碼 子代碼 訊息
RecognizeCompleted 200 8531 動作已完成,收到的位數上限。
RecognizeCompleted 200 8514 偵測到停止音調時完成的動作。
RecognizeCompleted 400 8508 動作失敗,作業已取消。
RecognizeCompleted 400 8532 動作失敗,已達到數字間無回應逾時。
RecognizeCanceled 400 8508 動作失敗,作業已取消。
RecognizeFailed 400 8510 動作失敗,已達到初始無聲逾時。
RecognizeFailed 500 8511 動作失敗,嘗試播放提示時發生失敗。
RecognizeFailed 500 8512 未知內部伺服器錯誤。
RecognizeFailed 400 8510 動作失敗,已達到初始無回應逾時
RecognizeFailed 400 8532 動作失敗,已達到數字間無回應逾時。
RecognizeFailed 400 8565 動作失敗,對 Azure AI 服務的要求不正確。 檢查輸入參數。
辨識失敗 400 8565 動作失敗,對 Azure AI 服務的要求不正確。 無法處理提供的承載,請檢查播放來源輸入
RecognizeFailed 401 8565 動作失敗,Azure AI 服務驗證錯誤。
RecognizeFailed 403 8565 動作失敗,對 Azure AI 服務的要求遭禁止,要求所使用的免費訂用帳戶已用盡配額。
RecognizeFailed 429 8565 動作失敗,要求已超過 Azure AI 服務訂用帳戶允許的並行要求數目。
RecognizeFailed 408 8565 動作失敗,對 Azure AI 服務的要求已逾時。
RecognizeFailed 500 8511 動作失敗,嘗試播放提示時發生失敗。
RecognizeFailed 500 8512 未知內部伺服器錯誤。

已知的限制

  • 不支援頻內 DTMF,請改用 RFC 2833 DTMF。
  • 文字轉換語音的文字提示最多支援 400 個字元,如果您的提示超出此長度,建議對文字轉換語音型播放動作使用 SSML。
  • 針對超過語音服務配額限制的案例,您可以依照這裡所述的步驟,要求提高此限制。

清除資源

如果您想要清除並移除通訊服務訂用帳戶,您可以刪除資源或資源群組。 刪除資源群組也會刪除與其相關聯的任何其他資源。 深入了解如何清除資源

後續步驟