Providing help through DialogAction

One of the greatest advantages of the bot interface is it allows the user to type effectively whatever it is they want.

One of the greatest challenges of the bot interface is it allows the user to type effectively whatever it is they want.

We need to guide the user, and to make it easy for them to figure out what commands are available, and what information they’re able to send to the bot. There are a few ways that we can assist the user, including providing buttons and choices. But sometimes it’s just as easy as allowing the user to type help.

Adding a global commands

If you’re going to add a help command, you need to make sure the user can type it wherever they are, and trigger the block of code to inform the user what is available to them. Bot Framework allows you to do this by creating a DialogAction. But before we get into creating a DialogAction, let’s discuss the concept of dialogs and conversations in a bot.

Dialogs and conversations

Bots contain a hierarchy of conversations and dialogs, which you get to define.

A dialog is a collection of messages back and forth between the user and the bot to collect information and perform an action on their behalf. A dialog might be the appropriate messages to obtain the type of service the user is interested in, determine which location the user is referring to when asking for store information, or the time the user wants to make a reservation for.

A conversation is a collection of dialogs. The conversation might use a dialog to walk through the steps listed above - service type, location and time - to complete the process of creating an appointment. By using dialogs, you can simplify the bot’s code, and enable reuse.

We will talk more in future blog posts about how to manage dialogs, but for right now this will enable us to create a DialogAction.

What is a DialogAction?

At the end of the day a DialogAction is a global way of starting a dialog. Unlike a traditional dialog, where it will be started or stopped based on a flow you define, a DialogAction is started based on the user typing in a particular keyword, regardless of where in the flow the user currently is. DialogActions are perfect for adding commands such as help, cancel or representative.

Creating a DialogAction

You register a DialogAction by using the bot function beginDialogAction. beginDialogAction accepts three parameters, a name for the DialogAction, the name of the Dialog you wish to start, and a named parameter with the regular expression the bot should look for when starting the dialog.

1
2
3
4
5
6
7
8
9
bot.beginDialogAction('help', '/help', { matches: /^help/ });
bot.dialog('/help', [
(session) => {
// whatever you need the dialog to do,
// such as sending a list of available commands
session.endDialog('in help');
}
]);

The first line registers a DialogAction named help, calling a Dialog named help. The DialogAction will be launched when the user types anything that begins with the word help.

The next line registers a dialog, named help. This dialog is just like a normal dialog. You could prompt the user at this point for additional information about what they might like, query the message property from session to determine the full text of what the user typed in order to provide more specific help.

DialogAction flow

The next question is what happens when the help Dialog (what it’s called in our case) completes. When endDialog is called, where in the flow will the user be dropped? As it turns out, they’ll pick up right where they left off.

Imagine if we had the following bot:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const builder = require('botbuilder');
const connector = new builder.ConsoleConnector();
const bot = new builder.UniversalBot(connector);
const dialog = new builder.IntentDialog()
.matches(/^load$/i, [
(session) => {
builder.Prompts.text(session, 'Please enter the name');
},
(session, results) => {
session.endConversation(`You're looking for ${results.response}`);
}
])
.onDefault((session) => {
session.endConversation(`Hi there! I'm a GitHub bot. I can load user profile information if you send the command **load**.`);
});
bot.dialog('/', dialog);
bot.beginDialogAction('help', '/help', { matches: /^help/ });
bot.dialog('/help', [
(session) => {
session.endDialog('This bot allows you to load GitHub data.');
}
]);
connector.listen();

Notice we have have an IntentDialog built with a load “command”. This kicks of a simple waterfall dialog which will prompt the user for the name of the user they wish to load, and then echos it back. If you ran the bot, and sent the commands load, followed by help, you’d see the following flow:

1
2
3
4
5
6
7
8
9
User: load
Bot: Please enter the name
User: help
Bot: This bot allows you to load GitHub data.
Bot: Please enter the name
User: GeekTrainer
Bot: You're looking for GeekTrainer

Notice that after the help dialog completes the user is again prompted to enter the name, picking right up where you left off. This simplifies the injection of the global help command, as you don’t need to code in where the user left, and then returned. The Bot Framework handles that for you.

Summary

One of the biggest issues in creating a flow with a chat bot is the fact a user can say nearly anything, or could potentially get lost and not know what messages the bot is looking to receive. A DialogAction allows you to add global commands, such as help or cancel, which can create a more elegant flow to the dialog.