/* */

Working with Prompt Dialogs in Bot Framework

Our first bot built with Bot Framework didn’t handle much user input. LUIS was able to recognize the text and start the dialog, but what if you want your bot to ask the user for input? That’s where prompt dialogs kick in. There are several of these dialogs available for you to use to manage conversation flow and each of them will render differently on several channels. Let’s see how these prompt dialogs work!

Prompt dialogs

Bot framework has a couple of prompt dialogs built in that you can work with.

Prompt dialog Description
Text Asks the user to enter a string of text.
Confirm Asks the user for confirmation.
Number Asks the user to enter a number.
Choice Asks the user to choose from a list of options.
Attachment Asks the user to upload an image or video.

Text

The simplest prompt dialog is the Text, where you ask the user for a string of text.


[LuisIntent("OrderFood")]
public async Task OrderFood(IDialogContext context, LuisResult result)
{
    PromptDialog.Text(context, ResumeAfterOrderFoodClarification, "What food do you want to order?");
}

private async Task ResumeAfterOrderFoodClarification(IDialogContext context, IAwaitable<string> result)
{
    var food = await result;
    await context.PostAsync($"I see you want to order {food}.");
}

Confirm

The Confirm dialog asks the user for confirmation to execute an action to make sure the bot doesn’t make wrong assumptions. Because Bot Framework only works with English, we can’t change the confirmation question from Yes/No to other text.


[LuisIntent("OrderFood")]
public async Task OrderFood(IDialogContext context, LuisResult result)
{
    PromptDialog.Confirm(context, ResumeAfterOrderFoodConfirmation, "Are you sure you want to order food?");
}

private async Task ResumeAfterOrderFoodConfirmation(IDialogContext context, IAwaitable<bool> result)
{
    var confirmation = await result;
    await context.PostAsync(confirmation ? "You do want to order." : "You don't want to order.");
}

Number

If you want a numeric value from the user, use the Number-dialog to do so. Use the overloads from this method to handle incorrect user input.


[LuisIntent("OrderFood")]
public async Task OrderFood(IDialogContext context, LuisResult result)
{
    PromptDialog.Number(context, ResumeAfterOrderFoodAmountClarification, "How many orders to you want to place?");
}

private async Task ResumeAfterOrderFoodAmountClarification(IDialogContext context, IAwaitable<long> result)
{
    var amount = await result;
    await context.PostAsync($"You want to place {amount} orders.");
}

Choice

One very powerful Prompt Dialog is the Choice, forcing the user to make a selection of the choices to easily manage conversation flow. Just like with Number, use the overloads to handle incorrect user input. You can do this with string-based input, but I think the cleanest way to do this is by using an enum and using the descriptions. This will make it more type-safe.

Also note you can also pass along a PromptStyle parameter. With this, you can specify the style on how the choice will be displayed for the user. By default, the PromptStyle.Auto is selected, which selects the style automatically based on the channel and number of options.


private enum Selection
{
    Hamburger, Pizza, Hotdog
}

[LuisIntent("OrderFood")]
public async Task OrderFood(IDialogContext context, LuisResult result)
{
    var options = new Selection[] { Selection.Hamburger, Selection.Pizza, Selection.Hotdog };
    var descriptions = new string[] { "Big Hamburger", "Cheesy Pizza", "Delicious Hotdog" };
    PromptDialog.Choice<Selection>(context, ResumeAfterOrderSelectionClarification,
        options, "Which selection do you want?", descriptions: descriptions );
}

private async Task ResumeAfterOrderSelectionClarification(IDialogContext context, IAwaitable<Selection> result)
{
    var selection = await result;
    await context.PostAsync($"I see you want to order a {selection}.");
}

Attachment

The last Prompt Dialog is a special one. Using Attachment, you’re able to process images or video within your bot. You can process it’s Content as you wish and since you can send multiple attachments in one message, you can process them in the same method.


[LuisIntent("OrderFood")]
public async Task OrderFood(IDialogContext context, LuisResult result)
{
    PromptDialog.Attachment(context, ResumeAfterAttachmentClarification, "How should your order look like?");
}

private async Task ResumeAfterAttachmentClarification(IDialogContext context, IAwaitable<IEnumerable<Attachment>> result)
{
    var orders = await result;
    foreach(var order in orders)
    {
        await context.PostAsync($"You've sent me a file with type '{order.ContentType}', I'll see what I can do!");
    }
}

In my next article, I’ll dive into an awesome combination of image processing using the Cognitive Services!

Conclusion

These prompt dialogs are great to guide your user in your conversational UI and manage your conversational flow. It’s fairly easy to use and is very powerful! Each of the Channels will render these options differently, but they work across all of them. Let me know what you think in the comments or on Twitter.

Want to learn more about this subject?
Join my “Weaving Cognitive and Azure Services“-presentation at TechDaysNL 2017!

9 comments On Working with Prompt Dialogs in Bot Framework

  • Hello, can you post entire project containing this Prompt example. I was tried on my device but on first time when i am sending message it shows all prompts in sequence.

  • Hello Marco,
    Is it possible to Localize PromptDialog.Choice & PromptDialog.Confirm? because in my case when the local language i.e. Spanish is selected the bot continues the conversation while PromptDialog.Confirm for any other language fails to reply. i can provide more information if you want.

  • Awesome post , congrats ! It works well on Skype, however on my web chat app embed the buttons becomes text. Could you help to figure it out please ?

    • I don’t know what you’re exactly bumping into, so feel free to contact me or hit me up on Twitter with a sample so I’ll be able to help you out. Looking forward!

  • I have tried below code. but it’s not working for me what are the intents need to be added.

    private enum Selection
    {
    Hamburger, Pizza, Hotdog
    }

    [LuisIntent(“OrderFood”)]
    public async Task OrderFood(IDialogContext context, LuisResult result)
    {
    var options = new Selection[] { Selection.Hamburger, Selection.Pizza, Selection.Hotdog };
    var descriptions = new string[] { “Big Hamburger”, “Cheesy Pizza”, “Delicious Hotdog” };
    PromptDialog.Choice(context, ResumeAfterOrderSelectionClarification,
    options, “Which selection do you want?”, descriptions: descriptions );
    }

    private async Task ResumeAfterOrderSelectionClarification(IDialogContext context, IAwaitable result)
    {
    var selection = await result;
    await context.PostAsync($”I see you want to order a {selection}.”);
    }

  • Hi Marco. Thank you for this wonderful post. Could you please write a article/blog on how to save the conversation of Bot and User data in SQL Database? This would be like a Chat Transcript

  • Hi Macro,

    Thanks for the post, however i am getting error as below,
    can you please help
    Exception: Operation returned an invalid status code ‘MethodNotAllowed’

    Bot attached:
    at Microsoft.Bot.Connector.BotState.d__8.MoveNext()

    — End

Leave a reply:

Your email address will not be published.

Site Footer