Integrate LUIS with a bot using the Bot Builder SDK for Node.js

This tutorial walks you through building a bot with the Bot Framework that's integrated with a LUIS app.

Prerequisite

Before you create the bot, follow the steps in Create an app to build the LUIS app that it uses.

The bot responds to intents from the HomeAutomation domain that are in the LUIS app. For each of these intents, the LUIS app provides an intent that maps to it. The bot provides a dialog that handles the intent that LUIS detects.

Intent Example utterance Bot functionality
HomeAutomation.TurnOn Turn on the lights. The bot invokes the TurnOnDialog when the HomeAutomation.TurnOn is detected. This dialog is where you'd invoke an IoT service to turn on a device and tell the user that the device has been turned on.
HomeAutomation.TurnOff Turn off the bedroom lights. The bot invokes the TurnOffDialog when the HomeAutomation.TurnOff is detected. This dialog where you'd invoke an IoT service to turn off a device and tell the user that the device has been turned off.

Create a Language Understanding bot with Bot Service

  1. In the Azure portal, select Create new resource in the menu blade and click See all.

    Create new resource

  2. In the search box, search for Web App Bot.

    Create new resource

  3. In the Bot Service blade, provide the required information, and click Create. This creates and deploys the bot service and LUIS app to Azure.

    • Set App name to your bot’s name. The name is used as the subdomain when your bot is deployed to the cloud (for example, mynotesbot.azurewebsites.net).
    • Select the subscription, resource group, App service plan, and location.
    • Select the Language understanding (Node.js) template for the Bot template field.

      Bot Service blade

    • Check the box to confirm to the terms of service.

  4. Confirm that the bot service has been deployed.

    • Click Notifications (the bell icon that is located along the top edge of the Azure portal). The notification will change from Deployment started to Deployment succeeded.
    • After the notification changes to Deployment succeeded, click Go to resource on that notification.

Try the default bot

Confirm that the bot has been deployed by checking the Notifications. The notifications will change from Deployment in progress... to Deployment succeeded. Click Go to resource button to open the bot's resources blade.

Once the bot is registered, click Test in Web Chat to open the Web Chat pane. Type "hello" in Web Chat.

Test the bot in Web Chat

The bot responds by saying "You have reached Greeting. You said: hello". This confirms that the bot has received your message and passed it to a default LUIS app that it created. This default LUIS app detected a Greeting intent. In the next step you'll connect the bot to the LUIS app you previously created instead of the default LUIS app.

Connect your LUIS app to the bot

Open Application Settings and edit the LuisAppId field to contain the application ID of your LUIS app.

Update the LUIS app ID in Azure

If you don't have the LUIS app ID, log in to the LUIS website using the same account you use to log in to Azure. Click on My apps.

  1. Find the LUIS app you previously created, that contains the intents and entites from the HomeAutomation domain.
  2. In the Settings page for the LUIS app, find and copy the app ID.
  3. If you haven't trained the app, click the Train button in the upper right to train your app.
  4. If you haven't published the app, click PUBLISH in the top navigation bar to open the Publish page. Click the Publish to production slot button.

Modify the bot code

Click Build and then click Open online code editor.

Open online code editor

In the code editor, open app.js. It contains the following code:

var restify = require('restify');
var builder = require('botbuilder');
var botbuilder_azure = require("botbuilder-azure");

// Setup Restify Server
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
   console.log('%s listening to %s', server.name, server.url); 
});

// Create chat connector for communicating with the Bot Framework Service
var connector = new builder.ChatConnector({
    appId: process.env.MicrosoftAppId,
    appPassword: process.env.MicrosoftAppPassword,
    openIdMetadata: process.env.BotOpenIdMetadata 
});

// Listen for messages from users 
server.post('/api/messages', connector.listen());

var tableName = 'botdata';
var azureTableClient = new botbuilder_azure.AzureTableClient(tableName, process.env['AzureWebJobsStorage']);
var tableStorage = new botbuilder_azure.AzureBotStorage({ gzipData: false }, azureTableClient);

// Create your bot with a function to receive messages from the user
var bot = new builder.UniversalBot(connector);
bot.set('storage', tableStorage);

// Make sure you add code to validate these fields
var luisAppId = process.env.LuisAppId;
var luisAPIKey = process.env.LuisAPIKey;
var luisAPIHostName = process.env.LuisAPIHostName || 'westus.api.cognitive.microsoft.com';

const LuisModelUrl = 'https://' + luisAPIHostName + '/luis/v2.0/apps/' + luisAppId + '&subscription-key=' + luisAPIKey;

// Main dialog with LUIS
var recognizer = new builder.LuisRecognizer(LuisModelUrl);
var intents = new builder.IntentDialog({ recognizers: [recognizer] })
.matches('Greeting', (session) => {
    session.send('You reached Greeting intent, you said \'%s\'.', session.message.text);
})
.matches('Help', (session) => {
    session.send('You reached Help intent, you said \'%s\'.', session.message.text);
})
.matches('Cancel', (session) => {
    session.send('You reached Cancel intent, you said \'%s\'.', session.message.text);
})
.onDefault((session) => {
    session.send('Sorry, I did not understand \'%s\'.', session.message.text);
});

bot.dialog('/', intents);

Add a default message handler

Remove this line of code.

var bot = new builder.UniversalBot(connector);

Replace it with the following code that creates the bot with a default message handler.

// Create your bot with a function to receive messages from the user
// This default message handler is invoked if the user's utterance doesn't
// match any intents handled by other dialogs.
var bot = new builder.UniversalBot(connector, function (session, args) {
    session.send('You reached the default message handler. You said \'%s\'.', session.message.text);
});

Add dialogs to handle the HomeAutomation intents

Find line of code that creates a LuisRecognizer.

// Create a recognizer that gets intents from LUIS
var recognizer = new builder.LuisRecognizer(LuisModelUrl);

Add this line of code right after it, to add the recognizer to the bot.

// Add the recognizer to the bot
bot.recognizer(recognizer); 

Delete the following code from the end of app.js in the code editor. You'll replace it with code for dialogs that handle the HomeAutomation.TurnOn and HomeAutomation.TurnOff intents.

var intents = new builder.IntentDialog({ recognizers: [recognizer] })
.matches('Greeting', (session) => {
    session.send('You reached Greeting intent, you said \'%s\'.', session.message.text);
})
.matches('Help', (session) => {
    session.send('You reached Help intent, you said \'%s\'.', session.message.text);
})
.matches('Cancel', (session) => {
    session.send('You reached Cancel intent, you said \'%s\'.', session.message.text);
})
.onDefault((session) => {
    session.send('Sorry, I did not understand \'%s\'.', session.message.text);
});

bot.dialog('/', intents);

Add a dialog that matches HomeAutomation.TurnOn

Copy the following code and add it to app.js.

bot.dialog('TurnOnDialog',
    (session, args) => {
        // Resolve and store any HomeAutomation.Device entity passed from LUIS.
        var intent = args.intent;
        var device = builder.EntityRecognizer.findEntity(intent.entities, 'HomeAutomation.Device');

        // Turn on a specific device if a device entity is detected by LUIS
        if (device) {
            session.send('Ok, turning on the %s.', device.entity);
            // Put your code here for calling the IoT web service that turns on a device
        } else {
            // Assuming turning on lights is the default
            session.send('Ok, turning on the lights');
            // Put your code here for calling the IoT web service that turns on a device
        }
        session.endDialog();
    }
).triggerAction({
    matches: 'HomeAutomation.TurnOn'
})

The matches option on the triggerAction attached to the dialog specifies the name of the intent. The recognizer runs each time the bot receives an utterance from the user. If the highest scoring intent that it detects matches a triggerAction bound to a dialog, the bot invokes that dialog.

Add a dialog that matches HomeAutomation.TurnOff

Copy the following code and add it to app.js.

bot.dialog('TurnOffDialog',
    (session, args) => {
        // Resolve and store any HomeAutomation.Device entity passed from LUIS.
        var intent = args.intent;
        var device = builder.EntityRecognizer.findEntity(intent.entities, 'HomeAutomation.Device');

        // Turn off a specific device if a device entity is detected by LUIS
        if (device) {
            session.send('Ok, turning off the %s.', device.entity);
            // Put your code here for calling the IoT web service that turns off a device
        } else {
            // Assuming turning off lights is the default
            session.send('Ok, turning off the lights');
            // Put your code here for calling the IoT web service that turns off a device
        }
        session.endDialog();
    }
).triggerAction({
    matches: 'HomeAutomation.TurnOff'
})

Test the bot

In the Azure Portal, click on Test in Web Chat to test the bot. Try type messages like "Turn on the lights", and "turn off my heater" to invoke the intents that you added to it. Test HomeAutomation bot in Web Chat

Tip

If you find that your bot doesn't always recognize the correct intent or entities, improve your LUIS app's performance by giving it more example utterances to train it. You can retrain your LUIS app without any modification to your bot's code. See Add example utterances and train and test your LUIS app.

Next steps

You can try to add other intents, like Help, Cancel, and Greeting, to the LUIS app. Then add dialogs for the new intents and and test them using the bot.