Now that we’ve laid the foundations, let’s build a house. A ..um. chatbot house.. yeah.

LUIS entry point

Botframework has a special type of Dialog especially for interacting with LUIS; the imaginatively titled LuisDialog!

Create a new class that extends LuisDialog<object> and add the LuisModel attribute, adding in your Model Id and Subscription Key from LUIS; an easy way to get these values is to hit “PUBLISH” and “Publish web service” for your LUIS app:

Then check the URL and copy the SubscriptionKey and id (for your ModelId) values.

(You can get these values elsewhere within the LUIS pages, but this was the easiest method for me)

Now edit your MessagesController such that the conversation is now started using the static Conversation.SendAsync method, passing in the incoming message activity as the first param and your new dialog as the result of a function for the 2nd param:

The method signature needs to take an IDialogContext and a LuisResult and return a Task.

Assuming you’ve TRAINed and PUBLISHed your LUIS app, and you’ve got the Model, Subscription, and Intent attribute values entered correctly, then we can set a breakpoint in that empty method and start debugging.

Open up the bot emulator and enter a phrase that you know LUIS will map to your intent, e.g. “will it rain in London tomorrow?”

As per usual the message hits theMessagesController, but this time we start a Conversation with the RootLuisDialog.

Since you’ve got your LuisModel attribute set up this message will now be posted to your LUIS app’s endpoint.

The resulting json is used to route the response to a method; if the response from LUIS contains the intent local.weather and if I have a method with a matching LuisIntent attribute, then the json response will be mapped to a LuisResult and passed in as a parameter.

Let’s dig into the LuisResult a bit – I’ll ask “is it going to rain in bristol this weekend?”:

That’s our query – nice. There are our entities! How handy.

What else is in there?

Looks like we have the three intents as defined within the LUIS app:

local.news gets the lowest score..

Then None…

And local.weather gets the highest score – as it should do. Which is why the method that gets called is the one with a `LuisIntent` attribute configured with the value `local.weather`

No match?

You should always be sure to add in a method that will be called if LUIS fails to match the input to any intent. Use the attribute with an empty string if you haven’t set up a “catch all” in your LUIS app, and add on you “catch all” intent as well if you have one, e.g.