Proposed Pull Request Change

title description services author ms.service ms.subservice ms.date ms.topic ms.author
include file C# recognize ai action how-to azure-communication-services Kunaal azure-communication-services azure-communication-services 02/15/2023 include file kpunjabi
📄 Document Links
GitHub View on GitHub Microsoft Learn View on Microsoft Learn
⚠ Content Truncation Detected
The generated rewrite appears to be incomplete.
Original lines: -
Output lines: -
Ratio: -
Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
+0 -0
+0 -0
--- title: include file description: C# recognize ai action how-to services: azure-communication-services author: Kunaal ms.service: azure-communication-services ms.subservice: azure-communication-services ms.date: 02/15/2023 ms.topic: include ms.topic: include file ms.author: kpunjabi --- ## Prerequisites - Azure account with an active subscription, for details see [Create an account for free.](https://azure.microsoft.com/pricing/purchase-options/azure-account?cid=msft_learn) - Azure Communication Services resource. See [Create an Azure Communication Services resource](../../../quickstarts/create-communication-resource.md?tabs=windows&pivots=platform-azp). Note the connection string for this resource. - Create a new web service application using the [Call Automation SDK](../../../quickstarts/call-automation/callflows-for-customer-interactions.md). - The latest [.NET library](https://dotnet.microsoft.com/download/dotnet-core) for your operating system. - Obtain the NuGet package from the [Azure SDK Dev Feed](https://github.com/Azure/azure-sdk-for-net/blob/main/CONTRIBUTING.md#nuget-package-dev-feed). - Create and connect [Foundry Tools to your Azure Communication Services resource](../../../concepts/call-automation/azure-communication-services-azure-cognitive-services-integration.md). - Create a [custom subdomain](../../../../../articles/cognitive-services/cognitive-services-custom-subdomains.md) for your Azure AI services resource. ## Technical specifications The following parameters are available to customize the Recognize function: | Parameter | Type|Default (if not specified) | Description | Required or Optional | | ------- |--| ------------------------ | --------- | ------------------ | | Prompt <br/><br/> *(for details on Play action, refer to [this how-to guide](../play-ai-action.md))* | FileSource, TextSource | Not set |This will be the message you wish to play before recognizing input. | Optional | | InterToneTimeout | TimeSpan | 2 seconds <br/><br/>**Min:** 1 second <br/>**Max:** 60 seconds | Limit in seconds that Azure Communication Services will wait for the caller to press another digit (inter-digit timeout). | Optional | | InitialSegmentationSilenceTimeoutInSeconds | Integer | 0.5 seconds | How long recognize action will wait for input before considering it a timeout. [Read more here](../../../../../articles/cognitive-services/Speech-Service/how-to-recognize-speech.md). | Optional | | RecognizeInputsType | Enum | dtmf | Type of input that will be recognized. Options will be dtmf, choices, speech and speechordtmf. | Required | | InitialSilenceTimeout | TimeSpan | 5 seconds<br/><br/>**Min:** 0 seconds <br/>**Max:** 300 seconds (DTMF) <br/>**Max:** 20 seconds (Choices) <br/>**Max:** 20 seconds (Speech)| Initial silence timeout adjusts how much non-speech audio is allowed before a phrase before the recognition attempt ends in a "no match" result. [Read more here](../../../../../articles/cognitive-services/Speech-Service/how-to-recognize-speech.md). | Optional | | MaxTonesToCollect | Integer | No default<br/><br/>**Min:** 1|Number of digits a developer expects as input from the participant.| Required | | StopTones |IEnumeration\<DtmfTone\> | Not set | The digit participants can press to escape out of a batch DTMF event. | Optional | | InterruptPrompt | Bool | True | If the participant has the ability to interrupt the playMessage by pressing a digit. | Optional | | InterruptCallMediaOperation | Bool | True | If this flag is set it will interrupt the current call media operation. For example if any audio is being played it will interrupt that operation and initiate recognize. | Optional | | OperationContext | String | Not set | String that developers can pass mid action, useful for allowing developers to store context about the events they receive. | Optional | | Phrases | String | Not set | List of phrases that associate to the label, if any of these are heard it will be considered a successful recognition. | Required | | Tone | String | Not set | The tone to recognize if user decides to press a number instead of using speech. | Optional | | Label | String | Not set | The key value for recognition. | Required | | Language | String | En-us | The language that will be used for recognizing speech. | Optional | | EndSilenceTimeout| TimeSpan | 0.5 seconds | The final pause of the speaker used to detect the final result that gets generated as speech. | Optional | >[!NOTE] >In situations where both dtmf and speech are in the recognizeInputsType, the recognize action will action on the first input type received, i.e. if the user presses a keypad number first then the recognize action will consider it a dtmf event and continue listening for dtmf tones. If the user speaks first then the recognize action will consider it a speech recognition and listen for voice input. ## Create a new C# application In the console window of your operating system, use the `dotnet` command to create a new web application. ```console dotnet new web -n MyApplication ``` ## Install the NuGet package During the preview phase, the NuGet package can be obtained by configuring your package manager to use the Azure SDK Dev Feed from [here](https://github.com/Azure/azure-sdk-for-net/blob/main/CONTRIBUTING.md#nuget-package-dev-feed). ## Establish a call By this point you should be familiar with starting calls, if you need to learn more about how to start a call view our [quickstart](../../../quickstarts/call-automation/callflows-for-customer-interactions.md). In this instance, we'll answer an incoming call. ``` csharp 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>")) { AzureCognitiveServicesEndpointUrl = new Uri("https://sample-cognitive-service-resource.cognitiveservices.azure.com/") // for Speech-To-Text (choices) }; var answerCallResult = await callAutomationClient.AnswerCallAsync(answerCallOptions); ``` ## Call the recognize action When your application answers the call, you can provide information about recognizing participant input and playing a prompt. ### DTMF ``` csharp var targetParticipant = new PhoneNumberIdentifier("+1XXXXXXXXXXX"); var recognizeOptions = new CallMediaRecognizeDtmfOptions(targetParticipant, maxTonesToCollect) { InterruptCallMediaOperation = true, InitialSilenceTimeout = TimeSpan.FromSeconds(30), Prompt = new FileSource(new System.Uri("file://path/to/file")), InterToneTimeout = TimeSpan.FromSeconds(5), InterruptPrompt = true, StopTones = new DtmfTone[] { DtmfTone.Pound }, }; await _callConnection.GetCallMedia().StartRecognizingAsync(recognizeOptions).ConfigureAwait(false); ``` **Note:** If parameters aren't set, the defaults will be applied where possible. ### Speech-To-Text (Choices) ``` csharp var choices = new List<RecognizeChoice> { new RecognizeChoice("Confirm", new List<string> { "Confirm", "First", "One"}) { Tone = DtmfTone.One }, new RecognizeChoice("Cancel", new List<string> { "Cancel", "Second", "Two"}) { Tone = DtmfTone.Two } }; var targetParticipant = new PhoneNumberIdentifier("+1XXXXXXXXXXX"); var playSource = new TextSource("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 recognizeOptions = new CallMediaRecognizeChoiceOptions( targetParticipant: targetParticipant, recognizeChoices: choices) { InterruptPrompt = true, InitialSilenceTimeout = TimeSpan.FromSeconds(5), Prompt = playSource, OperationContext = "AppointmentReminderMenu" }; var response = await _callConnection .GetCallMedia() .StartRecognizingAsync(recognizeOptions) .ConfigureAwait(false); ``` ### Speech-To-Text ``` csharp var prompt = “Hi, how can I help you today?” var ssml = <speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="{locale}">" + $ "<voice name=\"{voiceName}\">" + $ "<mstts:express-as style="{expression}">{payload}</mstts:express-as><s />" + "</voice>" + "</speak>"; var greetingPrompt = new SsmlSource(ssml) { PlaySourceId = "playSourceId" }; var recognizeOptions = new CallMediaRecognizeSpeechOptions( targetParticipant: targetParticipant) { InterruptCallMediaOperation = true, InterruptPrompt = false, Prompt = greetingPrompt, EndSilenceTimeoutInMS = TimeSpan.FromMilliseconds(1000), OperationContext = “OpenQuestionSpeech” }; await callConnectionMedia.StartRecognizingAsync(recognizeOptions) ``` **Note:** If parameters aren't set, the defaults will be applied where possible. ## Receiving recognize event updates Developers can subscribe to the *RecognizeCompleted* and *RecognizeFailed* events on the webhook callback they registered for the call to create business logic in their application for determining next steps when one of the previously mentioned events occurs. ### Example of how you can deserialize the *RecognizeCompleted* event: ``` csharp if (@event is RecognizeCompleted { OperationContext: "AppointmentReminderMenu" }) { logger.LogInformation($"RecognizeCompleted event received for call connection id: {@event.CallConnectionId}"); var recognizeCompletedEvent = (RecognizeCompleted)@event; string labelDetected = null; string phraseDetected = null; switch (recognizeCompletedEvent.RecognizeResult) { // Take action for Recognition through Choices case ChoiceResult choiceResult: labelDetected = choiceResult.Label; 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 break; //Take action for Recognition through DTMF case DtmfResult dtmfResult: var tones = dtmfResult.Tones; break; //Take action for Recognition through Speech case SpeechResult speechResult: var address = ((SpeechResult)((RecognizeCompletedEventData) @event).RecognizeResult).Speech; default: logger.LogError($"Unexpected recognize event result identified for connection id: {@event.CallConnectionId}"); break; } } ``` ### Example of how you can deserialize the *RecognizeFailed* event: ``` csharp if (@event is RecognizeFailed { OperationContext: "AppointmentReminderMenu" }) { logger.LogInformation($"RecognizeFailed event received for call connection id: {@event.CallConnectionId}"); var recognizeFailedEvent = (RecognizeFailed)@event; // Check for time out, and then take action like play audio if (ReasonCode.RecognizeInitialSilenceTimedOut.Equals(recognizeFailedEvent.ReasonCode)) { logger.LogInformation($"Recognition timed out for call connection id: {@event.CallConnectionId}"); var playSource = new TextSource("No input received and recognition timed out, Disconnecting the call. Thank you!"); //Play audio for time out await callConnectionMedia.PlayToAllAsync(playSource, new PlayOptions { OperationContext = "ResponseToChoice", Loop = false }); } //Check for invalid speech or tone detection and take action like playing audio if (ReasonCode.RecognizeSpeechOptionNotMatched.Equals(recognizeFailedEvent.ReasonCode) || ReasonCode.RecognizeIncorrectToneDetected.Equals(recognizeFailedEvent.ReasonCode)) { logger.LogInformation($"Recognition failed for invalid speech or incorrect tone detected, connection id: {@event.CallConnectionId}"); var playSource = new TextSource("Invalid speech phrase detected, Disconnecting the call. Thank you!"); //Play text prompt for speech option not matched await callConnectionMedia.PlayToAllAsync(playSource, new PlayOptions { OperationContext = "ResponseToChoice", Loop = false }); } } ``` ### Example of how you can deserialize the *RecognizeCanceled* event: ``` csharp if (@event 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); } ```
Success! Branch created successfully. Create Pull Request on GitHub
Error: