Friday, July 15, 2016

Microsoft Bot Framework: Using LUIS

What is LUIS?

LUIS (Language Understanding Intelligent Service) is a free service to provide language understanding to applications. This means that when a user sends text to an application, that application can use LUIS to determine what the user said and what they want. Deciphering messages that users send is extremely useful in chat bots so developers do not have to figure out how to parse user messages. In this example we will use LUIS to help run a campsite and allow users to reserve and cancel reservations.

Creating a LUIS Application

Go to luis.ai and sign in or create an account. Then select "New App" -> "New Application." 


Enter in your application info.


How to use LUIS

LUIS has many great documents on how to use it in depth on its site. We will go over the basics here.

Intents

If any of you are Android developers, these intents are not too much different from Android intents. LUIS intents are simply actions that the user might wish to take. For this campsite application, the actions that the user might take are "Book a Campsite" and "Cancel a Reservation." We will create an intent for each of these actions by pressing the + icon next to Intents.


Enter in the name of the intent along with a sample message that could trigger the intent.


Press save, and we have a new intent! In the middle of our screen, something else shows up. 


This is an "Utterance." Utterances are messages that the user might send to your LUIS app. We can teach LUIS by reading some of these messages and telling LUIS which intent they belong to. This message is the phrase we wrote when creating our new intent. This message is obviously a user attempting to book a campsite, so we will tell LUIS that this phrase will result in the "Book Campsite" intent. Ensure the "Book Campsite" intent is selected in the drop down box and press the Submit button.

Next, we will create the Cancel Reservation intent.



Once we have also submitted the Cancel Reservation utterance, we can continue on. 

Entities

Entities are objects within messages that are important. When we are writing the Book Campsite intent, we could say that certain entities could be present in the message. These could be things like DateTimes for the reservation start date and reservation end date. We are not going to be using entities in this tutorial for simplicity. There are plenty of guides on how to use entities available on the LUIS help docs.

Publishing our LUIS application

We will be running our LUIS application with Microsoft Azure, so a subscription is needed. First, we want to get a cognitive services key on azure. Go to your azure portal at portal.azure.com. Press "Browse" -> "Cognitive Services accounts." 


We will then have to create a new account with the "Add" button.



Enter in the name of your new account, then set the API type as a LUIS application.



West US is the only location currently available. Choose the free pricing tier, create a resource group if needed, and accept the terms and conditions.





After it is created, there are keys generated in the settings as seen below. Copy one of these keys.




Next, go back to your LUIS application. Open your app settings by pressing the App Settings button on the top left of the screen.



Finally, enter your subscription key as shown below:


Connecting your LUIS app to your Bot

Finally, it is time to get all of this connected with your bot. Microsoft has made this easy by creating a class LuisDialog<T> that you can derive from.

We will be creating a new class called CampsiteLuisDialog that inherits from LuisDialog.

Notice a few things in this class. First, it has a LuisModel attribute. This attribute lets the class connect with you LUIS. Enter your LUIS app id and subscription key from Azure here. They should match your App Settings in your LUIS app.

Next, we will create callback methods for LUIS intents. For each intent in LUIS, we need a corresponding method in this class. For example, here is a method for Book Campsite.

Notice the attribute LuisIntent on this method. That means that this method corresponds to the LUIS intent of "Book Campsite."

Finally, we need to launch the CampingLuisDialog for any users who communicate with our bot.

Let's edit our POST in MessagesController to return a new CampingLuisDialog for any messages arriving at our bot.


The main part of the code above is the line

Conversation.SendAsync(activity, () => new CampingLuisDialog());

This takes the activity sent to us, and returns a new CampingLuisDialog to the user. This dialog then becomes the main contact with the user instead of MessagesController. The user's message is then sent to LUIS, and the corresponding intent callback method on our LuisDialog is called. Once we know what the user wants, we can respond however we want!

Here is a diagram of how the messages are sent for the first message the user sends.



Once the Dialog has been created, it is where all new messages from the user are sent until the dialog is closed. The next messages from the user will get sent directly to the dialog instead of getting routed through the MessagesController.



The important part of this is using context.Wait(MessageReceived) at the end of your LUIS callback. This tells the dialog to wait for a new message and to handle that message as well.

Microsoft Bot Framework: Uploading to Azure

Setting up Azure

Uploading your app to Azure is incredibly simple. To begin, right click on your project in visual studio and select "Publish."


Your can then either select a Web App or an API app. I will be creating a Web App for this tutorial.

 

You will then have to select an Azure subscription. You will need to create a new Web App, so select the "New" button.

 

Select a web app name. This will be the domain name for your bot. You can then create a new app service plan, resource group, region, and database if you need one.


Once this is finished, everything should be automatically created for you. The next page should show some of this generated info such as your username, password, and site name.


Once that is finished, hit the "Publish" button, and you're done!

Using your bot in Azure

Using a bot in Azure takes a bit more effort than simply uploading it. The first thing that needs to be done is to create a new bot in the Microsoft Bot Directory. This can be found here: https://dev.botframework.com/bots. After signing in with your Microsoft ID, select "Register a Bot."



After filling in the required information about the bot, the app must be configured. The messaging endpoint will be the url of your bot in azure, followed by "api/messages."  In my case, this was "https://thatconferencebot.azurewebsites.net/api/messages." Click Create Microsoft App ID and password.

IMPORTANT: Use https in your address instead of http. Using http will result in a 401 error when trying to communicate with your bot.



This will create a new App Id for your bot.


Select "Generate a password to continue." Save this password somewhere secure since it will never be shown again. Also note your App ID since you will need it later. The remaining fields with an asterisk also need to be filled in. The URLs don't have to be real until you publish your app. For now, you can enter in any URL in fields such as "Privacy Statement" and "Terms of Use." 


Select "Register." This should finish the registration of the bot and display a page showing an overview of the bot. 

After this, the newly created App ID and Password must be entered in the bot's Web.config. Add the values in as shown below:


After this is done, re-publish the bot as done before. All of the information should already be saved, so pressed the "Publish" button should automatically upload the new bot.

Once the new bot is uploaded, return to the bot directory with the newly created bot. On the bottom left of the screen is a button labeled "Test."


Pressing this button will verify that the connection between the bot connector and the bot running in Azure works correctly. If everything is set up correctly, a messaging saying "endpoint authorization succeeded" should display.

Testing the bot in Azure

Using the Bot Framework Emulator with your bot in azure takes a bit more work. Replacing the "Bot URL" with the url of a bot in azure will result in an error message:


Fortunately, this error message is very useful. It says to download a tool called ngrok found here and run it with "ngrok http -host-header=rewrite 9000." Simply download the exe file, open a command promp, and run that same command.


After running this command, ngrok should display a url that forwards to your port 9000.


Copy this url and paste it into your emulator.


After doing this, the error should disappear from the emulator. Now all you have to do is enter your app id and password on the right side of the emulator. If everything was done correctly, no errors should show up in any of the boxes.


Everything should now work exactly like before, except it is now running in Azure! Now you can integrate your bot into channels like Slack, Twilio, and more. 

Microsoft Bot Framework: Getting Started

Required Software:

1) Visual Studio 2015
2) Bot builder template - save the zip to your Visual Studio 2015 templates directory (%USERPROFILE%\Documents\Visual Studio 2015\Templates\ProjectTemplates\Visual C#\)

Creating your app

Create your app by going to File->New->Project in Visual Studio. Select Bot Application.



Let's take a look at some of the code that comes with the template. The interesting part is going to be in MessagesController.cs:
You'll notice that this looks very similar to an ASP.NET WebApi project -- that's because it is. This is a WebApi Controller with a simple POST method. The post takes an Activity object and return an HttpResponseMessage.

This Activity object is simply the message that the user is sending to the bot. The message that the user is sending is contained in the Text property. You will also notice that there is a check on activity.Type. We'll get more into this later, but this is simply a check as to whether this message is a message from the user, or a system message (such as an alert that the user is typing).

The next line of code creates a ConnectorClient. This is an object representing the connection between the bot and a particular user. This connection can hold multiple conversations, each consisting of multiple activities.

Once we have the user's message and the connection, a reply is generated for the user. This reply simply returns a string containing the user's message and the length of that message. This reply is generated with "activity.CreateReply()," and it is sent back to the user via "connector.Conversations.ReplyToActivityAsync()."

Let's get this application running and test it out. Launch the application using your browser of choice. I am using Google Chrome for this example.



The browser window should look similar to this:


Note the port used at the end of the url. After the bot is running, we want to connect a chat client to it. The easiest way to test it is to use the Microsoft Bot Emulator. Change the "Bot Url" value to use the port that your bot is running on. In this case, mine was running on 3979. The full url should be "http://localhost:XXXX/api/messages."



Once this is finished, type a message at the bottom of the emulator, and send it to your bot!
You should quickly get a response.



When you send the message, you can see the json on the right side. Note that this json can be hard to see sometimes since it is quickly replaced by the reply.





















Notice that this json is the same Activity object that we use in the POST method in MessagesController.cs. The Type and Text are easily visible.





















Now we have a fully working bot! Move on to uploading your app to Azure, or integrate luis into your bot.