Cortana Integration In Universal Windows Platform Apps


This article is all about integrating Cortana (Virtual Voice-activated Personal Assistant) with our app.This means, if a user gives any instructions/asks question to Cortana related to our app anything an app can fulfil, Cortana communicates with our app and responds back to the user accordingly. To use Cortana, your device must have proper region set with the language pack installed, which Cortana understands.

Step 1 : Create Windows Universal Project

Open Visual Studio 2015 -> New Project -> Visual C# ->Windows -> Universal -> Blank App.

Create Windows Universal Project

Step 2 : Add Windows Runtime Component

Now, let's add Windows Runtime Component, which acts as a background AppService for this app and activates whenever the user asks anything to Cortana with the name of our app. We'll see it later.

Right click on solution -> Add new project -> Add Windows Runtime Component.

Add Windows Runtime Component

Step 3 : Add VCD file to project

Now, add a Voice Command Definition (VCD) file into our app, which we need to install on app launch.

A voice command is a single utterance with a specific intent, defined in a Voice Command Definition (VCD) file, directed at an installed app through Cortana.

A VCD file defines one or more voice commands, each with a unique intent.

CortanaUWPDemo -> Add ->New Item ->XML File,

Add VCD file to project

Copy paste the code, given below, in your VCD file.

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <VoiceCommands xmlns=" ">  
  3.     <!--For English US language-->  
  4.     <CommandSet xml:lang="en-us" Name="examplevcd">  
  5.         <AppName>Assistant</AppName>  
  6.         <Example>Ask your query to assistant regarding travels</Example>  
  7.         <Command Name="YourKeyword">  
  8.             <Example>I want to travel near areas</Example>  
  9.             <ListenFor>{UserCommand}</ListenFor>  
  10.             <Feedback>In progress...</Feedback>  
  11.             <VoiceCommandService Target="CortanaBackgroundTask" /> </Command>  
  12.         <PhraseTopic Label="UserCommand" Scenario="Natural Language"> </PhraseTopic>  
  13.     </CommandSet>  
  14.     <!--For English-India Language-->  
  15.     <CommandSet xml:lang="en-in" Name="examplevcd">  
  16.         <AppName>Assistant</AppName>  
  17.         <Example>Ask your query to assistant regarding travels</Example>  
  18.         <Command Name="YourKeyword">  
  19.             <Example>I want to travel near areas</Example>  
  20.             <ListenFor>{UserCommand}</ListenFor>  
  21.             <Feedback>In progress...</Feedback>  
  22.             <VoiceCommandService Target="CortanaBackgroundTask" /> </Command>  
  23.         <PhraseTopic Label="UserCommand" Scenario="Natural Language"> </PhraseTopic>  
  24.     </CommandSet>  
  25. </VoiceCommands>  
Here, I added multiple command sets for en-us and en-in., where:

AppName : Cortana will listen to the user only with this app name as a prefix of the sentence (Example :Assistant, I want to travel near areas.).
Feedback : Text shows to the user, while working on creating a user response after a user queries/asks something.
VoiceCommandService : The name of an app service, which activates on calling an AppName or CommandPrefix by the user.
PhraseTopic : You can add multiple phrases inside this PhraseTopic for better response and understandin of the user.

Step 4 : Install VCD file

Let's write a code in our app to install this VCD file.
  1. public async Task InstallVCD()   
  2. {  
  3.     try {  
  4.         StorageFile vcdStorageFile = await Package.Current.InstalledLocation.GetFileAsync(@ "VCD.xml");  
  5.         await Windows.ApplicationModel.VoiceCommands.VoiceCommandDefinitionManager.InstallCommandDefinitionsFromStorageFileAsync(vcdStorageFile);  
  6.     } catch (Exception ex) {}  
  7. }  
Call the method, shown above, from OnLaunched() of app.xaml.cs file.

Step 5 : Add reference of Windows Runtime Project

Now, we are done with making VCD file, installing VCD file from app, added a Runtime component into a solution. It's time to give reference of the background Service to our app.

CortanaUWPDemo -> References -> Right Click ->Add Reference -> Project -> Solution -> Check CortanaUWPDemoBgTask -> click OK.

Step 6 : Add Background task to Windows Runtime Project

Now, the reference of Background Service has been added into your UWP app. Now, we need to add BackgroundTask into Windows Runtime component project.

CortanaUWPDemoBgTask -> Add New item ->Class -> CortanaBackgroundTask implements a IBackgrountTask Interface
  1. public sealed class CortanaBackgroundTask: IBackgroundTask {  
  2.     public void Run(IBackgroundTaskInstance taskInstance) {}  
  3. }  
This background task(Run()) will be called on every voice command by the user.

Now, add some code for Voice Command Connection and get the text out of it. It is what the user said --  here is the updated code for the Background task.
  1. public sealed class CortanaBackgroundTask: IBackgroundTask   
  2. {  
  3.     BackgroundTaskDeferral serviceDeferral;  
  4.     VoiceCommandServiceConnection voiceServiceConnection;  
  5.     public async void Run(IBackgroundTaskInstance taskInstance) {  
  6.         serviceDeferral = taskInstance.GetDeferral();  
  7.         taskInstance.Canceled += OnTaskCanceled;  
  8.         var triggerDetails = taskInstance.TriggerDetails asAppServiceTriggerDetails;  
  9.         // This should match the uap:AppService and VoiceCommandService references from the  
  10.         // package manifest and VCD files, respectively. Make sure we've been launched by  
  11.         // a Cortana Voice Command.  
  12.         if (triggerDetails != null && triggerDetails.Name == "CortanaBackgroundTask") {  
  13.             try {  
  14.                 voiceServiceConnection = VoiceCommandServiceConnection.FromAppServiceTriggerDetails(triggerDetails);  
  15.                 voiceServiceConnection.VoiceCommandCompleted += OnVoiceCommandCompleted;  
  16.                 // GetVoiceCommandAsync establishes initial connection to Cortana, and must // be called prior to any  
  17.                 // messages sent to Cortana. Attempting to use // ReportSuccessAsync, ReportProgressAsync, etc  
  18.                 // prior to calling this will produce undefined behavior.  
  19.                 VoiceCommand voiceCommand = await voiceServiceConnection.GetVoiceCommandAsync();  
  20.                 var text = voiceCommand.SpeechRecognitionResult.Text;  
  21.                 if (text.Equals("I")) {  
  22.                     RespondTouser("Hi, How are your doing ?");  
  23.                 } else {  
  24.                     //Here you call up any api's to create a meaning full response to user/call // services like Bot/Luis etc... to create a meaningful response.  
  25.                     RespondTouser("You Said ," + text);  
  26.                 }  
  27.             } catch (Exception ex) {}  
  28.         }  
  29.     }  
  30.     private async void RespondTouser(string text) {  
  31.         var userMessage = new VoiceCommandUserMessage();  
  32.         string keepingTripToDestination = text; //How can i Help you?  
  33.         userMessage.DisplayMessage = userMessage.SpokenMessage = keepingTripToDestination;  
  34.         VoiceCommandResponse response = VoiceCommandResponse.CreateResponse(userMessage);  
  35.         await voiceServiceConnection.ReportSuccessAsync(response);  
  36.     }  
  37.     private void OnVoiceCommandCompleted(VoiceCommandServiceConnection sender, VoiceCommandCompletedEventArgs args) {  
  38.         if (this.serviceDeferral != null) {  
  39.             this.serviceDeferral.Complete();  
  40.         }  
  41.     }  
  42.     private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) {  
  43.         if (this.serviceDeferral != null) {  
  44.             this.serviceDeferral.Complete();  
  45.         }  
  46.     }  
  47. }  
Step 7 : Define AppService in Package Manifest file

Now, we are done with our Background app Service. Let our UWP app know about it.

Add the code, given below, in package.appmanifest file.
  1. <Extensions>  
  2.     <uap:Extension Category="windows.appService" EntryPoint="CortanaUWPDemoBgTask.CortanaBackgroundTask">  
  3.         <uap:AppService Name="CortanaBackgroundTask" /> </uap:Extension>  
  4.     <uap:Extension Category="windows.personalAssistantLaunch" />   
  5. </Extensions> 
Now, we are done with all the stuff. It's time to run our app. 

Output Video

Check out here : 1tsgENcMPk

Source Code

Download the full source code from here.