Machine LearningWhile attending the 2017 Microsoft Build Conference in Seattle, I realized a lot of the technical focus was in the Artificial Intelligence (AI) space. Topics ranged from Machine Learning to Cognitive Services to Bot technology. In this post, I'm going to expand on concepts I learned at Build and walk through the steps to building a simple bot. The core purpose of this bot will be to allow users to order a frozen yogurt (froyo) as you would at Sweet Frog or a similar establishment.

What is a Bot?

A Bot is an application that allows users to interact with it in a conversational way. Bots can respond to text, user actions (such as clicking a button), or even voice commands using a language recognition platform such as LUIS. Bots can also respond via these communication methods and they also support rich content via text cards, images, carousels, and many other dynamic content cards. Bot Framework is a powerful tool that helps application developers implement this conversation in a meaningful way.

Getting Started

In order to build your Bot, you will first need to have Visual Studio 2017 installed. The Bot Framework will work with Visual Studio 2017 Community Edition so you can build your bots for free. You will then need to download the Bot Application template. After downloading the zip file, you simply copy it to your Visual Studio 2017 project templates directory. The directory is located here:

%USERPROFILE%\Documents\Visual Studio 2017\Templates\ProjectTemplates\Visual C#\

You are now ready to begin.

Building your Bot

To begin building your Bot, open Visual Studio and select File -> New Project. Under the Visual C# templates at the bottom, you will see a new project type called "Bot Application." Select this, specify a name for your project, and the location for your project and click OK.

New Project

This will create an ASP.NET MVC project that includes all necessary references to the BotBuilder SDK. A bot application is essentially just an ASP.NET MVC application that is designed to handle the interaction between the end user and the bot. At this point, you could actually run the application and test it with the bot emulator. I'll go ahead and show you how to do that now, and then you can get back to building your Froyo bot.

Testing Your Bot With The Emulator

Microsoft provides a handy utility tool to test your bot out so that you don't have to deploy your bot anywhere while you are still developing it. The bot emulator runs on your local machine and emulates a bot channel. After downloading the installer, double-click on it to install the emulator, then run the newly installed botframework-emulator. You should see an app that looks a lot like this.

bot emulator

Next, you'll need to start your bot application. You can do this by pressing F5 in Visual Studio or by clicking the Debug -> Start Debugging menu. You should see a screen that looks something like this.

running bot

Now that the app is running, copy the url from the browser and paste it into the bot emulator. Make sure to append /api/messages to the end of the url as this is what the bot framework is expecting. After pasting this in you can click the Connect button.

connect to bot

You are now ready to chat with your bot. Enter in some text to box and hit enter. The bot will respond with a message telling you what text you entered and it will give you a character count. While it is pretty cool that is all you need to do to get a bot up and running, this isn't very interesting and doesn't really provide much value. Let's go ahead and change your bot so that you can order your Froyo.

Implementing Our Froyo Ordering Bot

Ordering Froyo is a somewhat complex thing and requires multiple steps in order to build the perfect frozen treat. You want to prompt the user for various things such as size, flavor, and toppings. The Bot Framework provides a great tool for collecting data in a sequential fashion and that is FormFlow. FormFlow automatically generates the dialogs that are necessary to manage a guided conversation. What makes this cool is that you have the ability to customize this conversation as little or as much as you want.

You'll start off by right-clicking on the project and adding a class called FroyoOrder.cs. You'll need to mark the class as Serializable so that the bot can be stateless. You'll need to include Microsoft.Bot.Builder.FormFlow in your using statements. Add the following method to your FroyoOrder class:

public static IForm BuildForm()
	{
		return new FormBuilder()
			.Message("Welcome to my Froyo Order bot!")
			.Build();
	}

This will display a message to welcome the user to your bot and will begin the process of prompting the user to order their Froyo. You will now define some enumerations to represent our various combinations of frozen yogurts and toppings. Place the following code inside of your namespace.

public enum SizeOptions
	{
		Small, Medium, Large, ExtraLarge
	}
public enum FlavorOptions
	{
		Vanilla, Chocolate, Strawberry, Mint, Coconut, Mango, Espresso, TaroRoot, CookiesAndCream,
		Plain, Raspberry, Blueberry, CakeBatter, BirthdayCake, Cheesecake, Cinnamon
	}
public enum ToppingOptions
	{
		ChocolateChips, Strawberries, Raspberries, WhippedCream, Pecans, GummyWorms, GrahmCrackerCrumbs, Fudge,
		Butterfinger, HeathBar, Sprinkles, Caramel, StrawberrySyrup, KitKat, Bananas, Cookies, CookieDough, Nerds,
		Peanuts, Cashews, Almonds, Cherries
	}

These enumerations define our size options, our yogurt flavor options, and our topping options. Now you need to associate these options with our FroyoOrder class. Inside of the class you'll add properties for each field you'd like to capture. Add the following code inside the class.

public SizeOptions? Size;
public FlavorOptions? Flavor;
public List Toppings;

It's important to keep in mind that the options are prompted in the order they are specified. So, in your bot, you will be prompted for size, then flavor, and finally what toppings. Also, to keep things simple, you will only allow one size, one flavor, but multiple toppings.

Now that you have defined your form, you can add it to the controller so that you can actually call your form. First you'll need to add Microsoft.Bot.Builder.FormFlow to your using statements. Then inside of the MessageController, add the following method.

internal static IDialog MakeRootDialog()
	{
		return Chain.From(() => FormDialog.FromForm(FroyoOrder.BuildForm));
	}

This method actually creates an IDialog instance of your form and returns it. Then update the following line.

await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());

With this:

await Conversation.SendAsync(activity, MakeRootDialog);

Now your bot application is ready for testing. Start the web project in debug mode and go back to the emulator and click the new conversation button. Enter in some text such as "hi" to begin chatting with your Froyo bot. You will be prompted with a size selection option. You can either click on one of the buttons or type in the actual size you would like.

choose a size

After this, you will be prompted for your flavor. Just as with size, you can click or type in the flavor you want.

choose a flavor

You will then be prompted for the toppings you'd like. You'll notice that there is a difference in this next screen. With the size and flavor prompts, you were given boxes that we can click to choose those options. With toppings, there is a numbered list of toppings that are displayed. If you'll recall when we defined our FroyoOrder class, the Toppings property was a List. This means that you can select more than one topping, so the interface is different. In this prompt, you can either type out the numbers you'd want, separated by commas, or the actual names of the toppings separated by commas.

choose toppings

After you select your toppings, you will be prompted to confirm your order. By entering "yes", the process will be completed and by entering "no", you will be given a chance to go back and change your previous options.

confirm order

What is really great about this is that you were able to provide a mechanism for prompting your user to go through and build something rather complex, like a frozen yogurt with toppings, with very little code. The Bot Framework and FormFlow took care of all the hard work of chaining the prompts together and responding to the user feedback.

Registering your Bot

Now that you have a working bot that is running locally, the next step is to register your bot. You can do this by going to https://dev.botframework.com and signing in with your Microsoft Account. After logging in, click on "My Bots" from the menu. You will be greeted with a screen that looks like this.

new bot

Click on the Register button to begin registering your new bot. Enter in a Display name. This is the name that displays in channels and directories and can be changed later. Then enter a Bot handle. This is used in the url for your bot. It can be alphanumeric and underscore only. Next, enter a long description. This is your bot's long description which may appear in channels and directories.

basic info

After entering your bot's basic information, scroll down to the configuration section. For the time being, just enter in a placeholder value for the messaging endpoint. Next, click on the "Create Microsoft App ID and password" button to generate a new app id and password.

config info

This will launch a new window with your App ID. Copy your App ID and then click the Generate an app password to continue. A modal will pop up with your app password. It is very important that you copy this here as this is the only chance you'll have to copy it. After you are done, click on the "Finish and go back to Bot Framework" button.

app password

Your App ID should be filled in under the configuration section. Scroll to the bottom and click the check box to agree to the terms and conditions and click the "Register" button to register your chat bot.

Now that your bot is registered, you must go back to your application and update the configuration to use the App ID and password that were generated during this process. In the web.config file, there are two appSettings; MicrosoftAppId, and MicrosoftAppPassword. The first will be the App ID from your bot, and the second will be the password that was generated. You can go ahead and update your web.config with these values, or if you are deploying your bot to Azure, you can configure it through Azure so that your settings are not in source control. For the purposes of this post, my application will be deployed to Azure. I am not covering how you do that in this blog post though.

After you have registered your bot, updated your bot application with the App ID and password, and deployed your code you are ready for testing. You should now be on a screen that looks like this.

registered bot

You'll notice that you are already connected to the Skype and Web Chat channels. Taking a step back, channels are just different platforms that your bot is available to run on. By default, registering your bot with the bot framework gives you the Skype and Web Chat channels. Other channels that are available are Bing, Cortana, Facebook, and Slack just to name a few. There are other channels that you can run your bot in. To test your bot to make sure it is working, you can click the Test button in the top right corner. A chat window will open and you can test your bot live the same way you did with the emulator.

Conclusion

As you can see, the Bot Framework is an easy to use, yet incredibly powerful tool for building intelligent bots to interact with your customers. While creating a bot can be very easy, there is a lot of work in service mapping, intent and sentiment detection, and increased focus on UX as the "time to frustration" decreases with fewer visual cues. These are all things you should keep in mind as you design your bots. Microsoft's bot framework documentation has a section dedicated to designing your bot.

This blog post covered a very simple use case of using a FormFlow to collect information for making a frozen yogurt order. In future posts, I'd like to cover some more advanced scenarios and incorporate some natural language processing.

Source code for this post can be found on GitHub.