Chat Bot Using Microsoft Bot Framework With LUIS - Part Two

In previous articles, I have explained how to create and configure a LUIS app. In this article, we will discuss how to integrate this app in Bot application created using Microsoft Bot Framework.

We are going to build a bot which will reply as per the intents which we have added in the previous article.

Highlights of the article

  • Publish app
  • Consume LUIS app to extract intents and entities. You can pull code from here.

Prerequisite

Publish LUIS app

Click on ‘Publish App’ option in left side bar menu. It will show the following page.

Here, you can choose Endpoint Key. Select purchased key. If you have not purchased any key, then select Bootstrap key, which is for experimental purpose.
 
In ‘Publish Settings’, you can select Endpoint slots as Staging or Production. If you select it as Staging, it will be available over http but you can’t access it though chat bot app. For our development, select it as Production.

We can enable verbose flag and Bing spell check if required. You can select time zone as per requirement.

Microsoft Bot Framework
Under ‘Add Key Association’, we can add key required for BingSpellChecker, if enabled above.
 
Click on Train >> Publish.
Microsoft Bot Framework

It will show success message and Endpoint url to access service over HTTP.

Microsoft Bot Framework

https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/{{app_id}}?subscription-key={{subscription_key}}&timezoneOffset=0&verbose=true&spellCheck=false&q=

To test output of service, I hit the above url with different values for parameter ‘q’.

q=Hi, Output - top scoring intent – Greet.Welcome

  1. {  
  2.     "query""hi",  
  3.     "topScoringIntent": {  
  4.         "intent""Greet.Welcome",  
  5.         "score": 0.792347133  
  6.     },  
  7. }  
q=Bye, Output: top scoring intent – Greet.Farewell
  1. {  
  2.     "query""bye",  
  3.     "topScoringIntent": {  
  4.         "intent""Greet.Farewell",  
  5.         "score": 0.455509841  
  6.     },  
  7. }  
q=Search Amit, Output: top scoring intent – Search.People, entity – Amit, type – Person.Name
  1. {  
  2.     "query""Search Amit",  
  3.     "topScoringIntent": {  
  4.         "intent""Search.People",  
  5.         "score": 0.500412941  
  6.     },  
  7.  
Perfect! Our app is able to extract right intent and entity. Now, we will setup bot application.

If you are ready with prerequisites for development with bot framework, then let’s create new dialog in Dialog folder as IntelligentDialog and new Controller as IntelligentController.

Microsoft Bot Framework

IntelligentController.cs

I have updated Post( ) method to invoke IntelligentDialog with parameter activity.

  1. public async Task < HttpResponseMessage > Post([FromBody] Activity activity) {  
  2.     if (activity.Type == ActivityTypes.Message) {  
  3.         await Conversation.SendAsync(activity, () => new Dialogs.IntelligentDialog(activity));  
  4.     } else {  
  5.         HandleSystemMessage(activity);  
  6.     }  
  7.     var response = Request.CreateResponse(HttpStatusCode.OK);  
  8.     return response;  
  9. }  

IntelligentDialog.cs

  1. [Serializable]  
  2. [LuisModel(Constants.LUIS_EMPLOYEE_HELPER_APP_ID, Constants.LUIS_SUBSCRIPTION_KEY)]  
  3. public class IntelligentDialog: LuisDialog < object > {  
  4.     private string userName;  
  5.     private DateTime msgReceivedDate;  
  6.     public IntelligentDialog(Activity activity) {  
  7.         userName = activity.From.Name;  
  8.         msgReceivedDate = activity.Timestamp ? ? DateTime.Now;  
  9.     }  
  10.     [LuisIntent("")]  
  11.     [LuisIntent("none")]  
  12.     [LuisIntent("None")]  
  13.     public async Task None(IDialogContext context, LuisResult luisResult) { ...  
  14.     }  
  15.     [LuisIntent("Greet.Welcome")]  
  16.     public async Task GreetWelcome(IDialogContext context, LuisResult luisResult) { ...  
  17.     }  
  18.     [LuisIntent("Greet.Farewell")]  
  19.     public async Task GreetFarewell(IDialogContext context, LuisResult luisResult) { ...  
  20.     }  
  21.     [LuisIntent("Search.People")]  
  22.     public async Task SearchPeople(IDialogContext context, LuisResult luisResult) { ...  
  23.     }  
  24. }  

We need to inherit IntelligentDialog from LuisDialog<object> to use LUIS intelligence. After inheritance, to integrate LUIS app we need to specify attribute LuisModel with LUIS app ID and your subscription key, for IntelligentDialog class. You can get these values from HTTP endpoint url.

I have added two private properties username and msgReceivedDate to IntelligentDialog class. Initialize those properties in its constructor (shown below). We are going to use these properties while communicating with user.

I have added methods for each Intent specified in LUIS app. To invoke those methods when intent matches, we need to specify LuisIntent attribute for each method with intent name as parameter.

For chat text from user ‘Hello Employee Helper’, intent will be matched with ‘Greet.Welcome’ and ‘GreetWelcome( )’ method will be invoked.

  1. [LuisIntent("Greet.Welcome")]  
  2. public async Task GreetWelcome(IDialogContext context, LuisResult luisResult) {  
  3.     string response = string.Empty;  
  4.     if (this.msgReceivedDate.ToString("tt") == "AM") {  
  5.         response = $ "Good morning, {userName}. :)";  
  6.     } else {  
  7.         response = $ "Hey {userName}. :)";  
  8.     }  
  9.     await context.PostAsync(response);  
  10.     context.Wait(this.MessageReceived);  
  11. }  

For chat text from user ‘Thanks dude, talk to you later’, intent will be matched with ‘Greet.Farewell’ and ‘GreetFarewell( )’ method will be invoked. In this method, we are sending response on the basis of ‘AM’ or ‘PM’ of msgReceivedDate.

  1. [LuisIntent("Greet.Farewell")]  
  2. public async Task GreetFarewell(IDialogContext context, LuisResult luisResult) {  
  3.     string response = string.Empty;  
  4.     if (this.msgReceivedDate.ToString("tt") == "AM") {  
  5.         response = $ "Good bye, {userName}.. Have a nice day. :)";  
  6.     } else {  
  7.         response = $ "b'bye {userName}, Take care.";  
  8.     }  
  9.     await context.PostAsync(response);  
  10.     context.Wait(this.MessageReceived);  
  11. }  

For chat text ‘Could you please find Akshay’ from user, intent will be matched with ‘Search.People’ and ‘SearchPeople( )’ method will be invoked. In this method, we check whether Entity ‘Person.Name’ is present in LuisResult. With TryFindEntity employee name is extracted from result.

  1. [LuisIntent("Search.People")]  
  2. public async Task SearchPeople(IDialogContext context, LuisResult luisResult) {  
  3.     EntityRecommendation employeeName;  
  4.     string name = string.Empty;  
  5.     if (luisResult.TryFindEntity("Person.Name", out employeeName)) {  
  6.         name = employeeName.Entity;  
  7.     }  
  8.     await context.PostAsync($ "You have searched for {name}");  
  9.     context.Wait(this.MessageReceived);  
  10. }  

Hit F5 to test a bot application. It will host an application with IIS Express and open browser. To understand the control flow, insert breakpoints in Post( ) method of IntelligentController and each method of IntelligentDialog.

Now launch bot emulator app. Put URL as 'http://localhost:{{port no. from browser url}}/api/intelligent' to connect emulator with bot application. Keep App ID and App Password blank, click on connect.

Keep teaching (more intents to your LUIS app) and keep chatting!

Microsoft Bot Framework


Similar Articles