An Interactive Bot Application With LUIS Using Microsoft Bot Framework

Introduction

In my previous two articles I have explained how can we create a bot application. In this article I will explain you how can we create our bot application more interactive for our user.s In this article I will use one of the Microsoft Cognitive Services that is LUIS.
 
My Previous  Articles on Bot Framework
Note: Here I am giving My Project link because In this article I will use  Real Time Bot Project Using Microsoft Bot Framework article and I will add LUIS in this project.
 
What is LUIS ?

According to luis.ai, LUIS is a Language Understanding Intelligent Service, which offers a  fast and effective way of adding language understanding to applications. With LUIS, you can use pre-existing, world-class, pre-built models from Bing and Cortana whenever they suit your purposes and when you need specialized models, LUIS guides you through the process of quickly building them. LUIS is a part of Microsoft Cognitive Service.
 
Let's Understand LUIS with an example

Example 1:

Suppose I search in my Windows 10 PC or Windows phone through Cortana like "Where am I," then I will get a map and my current location. However I am not saying to Cortana to search for location, I am just saying "Where am I", And cortana is understanding what am I looking for and this is happening because of LUIS.

 
 
Example 2: Suppose I search like Email to contact@sourabhsomani.com then cortana recognizes my command using LUIS and give me result like as follows:

 
 
So in above examples you can see there is more interaction.
 
Let's look at my previous example

In my previous article I created a Real Time Bot Application where I was searching for stock price by stock symbol like as following figure.

 
In the above figure you can see that message is not more conversational I am just sending input as msft and getting result but for our users it will not be more interactive.
 
In this article I will explain to you how can we make our Bot more interactive. Like my input will be "What about msft" or "What is the price of orcl stock", Like as following figure:

 
The above conversation is more interactive, and this can be done by using LUIS.
 
Let's create application step by step

Step 1:
Firstly open visual studio, and create a bot application with any name. Follow following steps to create an Bot application:
  1. File > New > Project or just Press CTRL + SHIFT + N.

  2. Now for Visual C# template select Bot Application then give the name of the application and then click OK button to create the application.


Step 2: Now go to LUIS Website, then login in to your account or register there. Then After create new application. 

 
Step 3: Now one dialog box will be open; provide Application Name, Description, and Application Culture and then click on Add App Button.

 
 
I have created my app by name StockApp.
 
Step 4: Now edit your application by clicking on Edit button.

 
Step 5: 

On the left-hand panel, you will see an option to add entities. So quickly add an Entity with Name StockSymbol. Follow following figure to add an entity.



What is Entity: 

An entity is a keyword for which we will search like in our example entity is msft that is nothing but an Stock Symbol so I have given my entity name StockSymbol.
 
Step 6: 

On the left-hand panel, you will see an option to Add Intents. So le'ts Quickly add Some intents. Give the name of the intents and example of utterance and Save.

 
 
I have added two intents StockPrice  and StockPrice2.

What is Intents? : 

Intent means just what we desire and what is our intention so my intention is I would like to ask to my Bot "what about msft" or "what is the price of msft stock".

What are utterances: 

How will I search  will be my statements. So I have added 4-5 statements. But after 4-5 LUIS will automatically detect what we want. 
 
Step 7: Now add some utterances like as following. 

 

Here you have to define StockSymbol, After doing this for 4-5 LUIS will automatically detect what is our entity.

Note: Don't forget to add entity by clicking on entity and submiting it after defining entity. 
 
Step 8: Publish your application by clicking on publish button.

 
Step 9: Now one dialog box will open search there for your query.

 
 
Step 10: Hit Enter and you will get JSON format result.

 
Step 11: 

Now again flip to visual studio and create class file for this JSON result. I am addinga  few of the classes for this JOSN result. Class code is given below in figure.

 
 
Well I have just generated this class code using JSON. By Copy and Paste JSON as Classes. Learn How can you paste JSON as Classes.
 
Step 12: 

Now Create a class in your project with any name. I am giving Name as YahooBot, Which class Yahoo Finance API to get Stock Information, I am writing the following code inside it.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Net;  
  5. using System.Threading.Tasks;  
  6. using System.Web;  
  7.   
  8. namespace StockBot2  
  9. {  
  10.     public class YahooBot  
  11.     {  
  12.         public static async Task<double?> GetStockRateAsync(string StockSymbol)  
  13.         {  
  14.             try  
  15.             {  
  16.                 string ServiceURL = $"http://finance.yahoo.com/d/quotes.csv?s={StockSymbol}&f=sl1d1nd";  
  17.                 string ResultInCSV;  
  18.                 using (WebClient client = new WebClient())  
  19.                 {  
  20.                     ResultInCSV = await client.DownloadStringTaskAsync(ServiceURL).ConfigureAwait(false);  
  21.                 }  
  22.                 var FirstLine = ResultInCSV.Split('\n')[0];  
  23.                 var Price = FirstLine.Split(',')[1];  
  24.                 if (Price != null && Price.Length >= 0)  
  25.                 {  
  26.                     double result;  
  27.                     if (double.TryParse(Price, out result))  
  28.                     {  
  29.                         return result;  
  30.                     }  
  31.                 }  
  32.                 return null;  
  33.             }  
  34.             catch (WebException ex)  
  35.             {  
  36.                 //handle your exception here  
  37.                 throw ex;  
  38.             }  
  39.         }  
  40.     }  
  41. }  
In the above code you can see a function that is GetStockRateAsync, which takes a StockSymbol as a parameter. I am calling Yahoo Finance API, where I will pass that symbol and that will return a CSV file of stock market rate, and I am splitting CSV File by commas because CSV File means Comma Separated Value. So, I am splitting by comma(,) and getting current price of that stock. Then I am converting it into double because of course our stock rate will be in double and returning current price.
 
Step 13: Now in MessagesController create a class that will call this above function., so I am creating a GetStock function in My MessageController class.
  1. private async Task<string> GetStock(string StockSymbol)  
  2. {  
  3.     double? dblStockValue = await YahooBot.GetStockRateAsync(StockSymbol);  
  4.     if(dblStockValue==null)  
  5.     {  
  6.         return string.Format("This \"{0}\" is not an valid stock symbol",StockSymbol);  
  7.     }  
  8.     else  
  9.     {  
  10.         return string.Format("Stock Price of {0} is {1}",StockSymbol,dblStockValue);  
  11.     }  
  12. }  
In above code you can see I am calling my GetStockRateAsync function that will return a nullable double. I am checking whether that stock value is null or not. According to stock value I am returning appropriate string.
 
Step 14: As we know we like to interact via LUIS so I am creating one more method in MessagesController with name GetEntityFromLUIS.
  1. private static async Task<StockLUIS> GetEntityFromLUIS(string Query)  
  2. {  
  3.     Query = Uri.EscapeDataString(Query);  
  4.     StockLUIS Data = new StockLUIS();  
  5.     using (HttpClient client=new HttpClient())  
  6.     {  
  7.         string RequestURI = "https://api.projectoxford.ai/luis/v1/application?id=7f626790-38d6-4143-9d46-fe85c56a9016&subscription-key=09f80de609fa4698ab4fe5249321d165&q=" + Query;  
  8.         HttpResponseMessage msg = await client.GetAsync(RequestURI);  
  9.   
  10.         if (msg.IsSuccessStatusCode)  
  11.         {  
  12.             var JsonDataResponse = await msg.Content.ReadAsStringAsync();  
  13.             Data = JsonConvert.DeserializeObject<StockLUIS>(JsonDataResponse);  
  14.         }  
  15.     }  
  16.     return Data;  
  17. }  
Above code will take query from us and process query using LUIS Service and return StockLUIS class object, That is nothing but JSON data as a class format.
 
Step 15: Now write following code in Post Action of Message Controller. 
  1. public async Task<Message> Post([FromBody]Message message)  
  2. {  
  3.     if (message.Type == "Message")  
  4.     {  
  5.         string StockRateString;  
  6.         StockLUIS StLUIS = await GetEntityFromLUIS(message.Text);  
  7.         if(StLUIS.intents.Count()>0)  
  8.         {  
  9.             switch(StLUIS.intents[0].intent)  
  10.             {  
  11.                 case "StockPrice":  
  12.                     StockRateString = await GetStock(StLUIS.entities[0].entity);  
  13.                     break;  
  14.                 case "StockPrice2":  
  15.                     StockRateString = await GetStock(StLUIS.entities[0].entity);  
  16.                     break;  
  17.                 default:  
  18.                     StockRateString = "Sorry, I am not getting you...";  
  19.                     break;  
  20.             }  
  21.         }  
  22.         else  
  23.         {  
  24.             StockRateString = "Sorry, I am not getting you...";  
  25.         }  
  26.   
  27.         // return our reply to the user  
  28.         return message.CreateReplyMessage(StockRateString);  
  29.     }  
  30.     else  
  31.     {  
  32.         return HandleSystemMessage(message);  
  33.     }  
  34. }  
Above code takes message from Bot User and sends message to LUIS now LUIS will process the message if the message will be identify then send StockLUIS class Object. Now if data will be identified then it will check intents and whatever entity will return LUIS service that will be pass to Yahoo Web Service and we will get string as a result that will be pass to client. If no Intent will be there then we will tell to our client that "Sorry, I am Not Getting You...".
 
Step 16: Now run this project in Emulator.
 
Output: If we send wrong query to LUIS then Output will be as follows,

 
If we query with invalid stock symbol then output will be as follows,

 
Query with valid query and valid stock symbol:  
 
 
 
Suppose in above figure I Forget to provide stock there then also LUIS will give me the accurate result.

 
Conclusion:
  • In this article we have created an interactive Bot Application with LUIS using Microsoft Bot Framework. 
  • We learn about LUIS and its power.
  • We have seen how LUIS helps in powerful interactive Conversation.
Read more articles on Machine Learning: