Creating a bot using Microsoft Bot Framework in Node and TypeScript
If you have been following my posts over the last couple of months, I mentioned that I have been working on a chat bot to further my Node knowledge.
I am happy to say my chat bot is finally finished (well for now anyway): themeparks-bot answers questions about theme parks worldwide such as rides, park opening hours and wait times.
themeparks-bot was built using Microsoft Bot Framework with Node and TypeScript; and given what I know now I thought I would put a bot starter project together and discuss some of the key parts.
Choosing a web framework
When getting started with Microsoft Bot Framework, you need to choose a web framework to use. The Bot Builder samples I looked at either use express or restify.
I chose to use express since I had previous experience with it, but to be honest it doesn’t really matter which web framework you use; since it is only used in a small part of the bot to create an API endpoint.
Use libraries to structure dialogs
Bots in Microsoft Bot Framework are made up of dialogs, akin to screens in single page applications, each containing separate logic and ideally responsible for a single purpose such as asking a question to a user.
Initially when developing dialogs you might end up with something like this (taken from the Bot Framework documentation):
As you add more dialogs this file will get rather large and also, is doing multiple things i.e. creating the bot and defining the dialogs.
A better approach is to use libraries; these aren’t mentioned in the Bot Framework documentation but if you look at BotBuilder reference bot sample they are discussed in detail. The advantage of using libraries is that they separate concerns and enable dialog reuse across projects.
The simplified sample below is taken from the bot starter project which shows how to create a library and connect it to the bot.
Creating a first run dialog
As part of a good user experience, a bot should have a first run experience in order that a user knows how to interact with it.
There are different ways of doing this as detailed here, but dependent on channels (e.g. Facebook Messenger) some methods may not be supported.
A universal first run dialog is as follows:
The onFindAction function ensures that this dialog is the first one to be invoked, when the bot hasn’t seen this user before.
Creating a global dialog
As a user interacts with a bot, it should provide the ability for a user to ask for help at any time. This is in order that a user can find out what to do next or what they can ask.
Implementing a help dialog can be done using a global dialog; this is shown below.
Creating a prompt
If you need input from a user, the botbuilder module contains many built-in prompts which can be configured to meet whatever requirements you have.
An example is asking a user to choose their favorite colour from a list of options:
The choice prompt allows a user to make a selection using either the ordered number of the choice or the actual choice value. Also the prompt will automatically ask the user to retry if they enter a choice which doesn’t match any in the list.
Use a storage service for state
At some point a bot will need to persist state such as remembering that it has seen a user before.
This requires bot storage to be configured; by default Microsoft Bot Framework uses in-memory storage however this is only intended for testing. Therefore for production, one of the supported storage mechanisms i.e. Cosmos DB, Table Storage or SQL needs to be used.
The starter project uses Table Storage and the set up is shown below:
The bot storage is configured this way in order that during development in-memory storage is used whereas in production, table storage is used. That way the Table Storage account doesn’t get filled up with development/test data.
Use dotenv for configuration
There are a number of configuration settings used throughout the bot such as Table Storage credentials, LUIS endpoint and Microsoft App credentials.
These are set at development time using dotenv as described in an earlier post.
Triggering a dialog using Language Understanding (LUIS)
LUIS allows a user to chat using natural language and have a bot identify their intent and map it to a dialog to invoke.
First of all you need to create a LUIS application, which is detailed in the documentation. Once you have created a LUIS application, you need to configure the bot’s recognizer and specify the matching intent for a dialog; this is shown below.
For example, the getFavourite dialog’s triggerAction corresponds to the name of an intent in LUIS, which is invoked when a user says something like “what’s my favourite colour”.
You have reached the end :) I hope this post and my bot starter project was helpful.