Implementing FormFlow for Microsoft Node.js BotBuilder SDK

The C# BotBuilder SDK supports a really cool thing call FormFlow. With this, you can write a C# class which is used as a base for a dynamically generated series of question/answer pairs, in order to fill the properties of this class. For instance, do you want to create a burger ordering bot? Just add a enum for BreadOptions, an enum for Toppings, a choice of SauceOptions etc. This is a really cool feature of the C# BotBuilder SDK which allows you to quickly develop a chatbot with predefined rules and flow. As the Node.js BotBuilder SDK lacks this functionality, I tried to replicate it since I needed it for a simple project I’m building. Meet formflowbotbuilder.

Usage

First, you need to create a new node.js project and install the required libraries.

npm init
npm install –save botbuilder
npm install –save formflowbotbuilder

C# SDK uses reflection to generate the question/answer pairs. In our implementation, we opted to use a JSON file to store these. Check out a sample, taken from library’s source code on GitHub. Let’s call it sample.json.

[
    {
        "id": "firstname",
        "prompt": "please enter a name",
        "response": "Your name is %s",
        "errorPrompt": "please enter a string of > 0 characters",
        "type": "text"
    },
    {
        "id": "language",
        "prompt": "please select a language",
        "response": "Your favorite programming language is %s",
        "errorPrompt": "please select one of the choices",
        "type": "choice",
        "choices": "JavaScript|TypeScript|CoffeeScript"
    },
    {
        "id": "email",
        "prompt": "please enter an email",
        "response": "Your email is %s",
        "errorPrompt": "please enter a valid email",
        "type": "email"
    },
    {
        "id": "url",
        "prompt": "please enter a website (starting with http:// or https://)",
        "response": "Your url is %s",
        "errorPrompt": "please enter a valid website",
        "type": "url"
    }
]

You can see that this is basically an array of various JSON objects, with each one containing necessary fields for our FormFlow implementation. These are

  • id: an id for our field. This will also be the name of the variable that will contain the answer of the user
  • prompt: the question to the user
  • response: the response that will be given to the user (to verify that the bot has gotten the correct response)
  • errorPrompt: a text to display to the user when he has given a wrong response (e.g. a wrong e-mail or URL)
  • type: this can take one of the following values
    • text: just any text is requested by the user
    • choice: this contains an array of choices, implementing the builder.Prompts.choice method
    • email: validates input against known email patterns
    • url: validates input agains known URL patterns
    • number: utilizes the
      builder.DialogAction.validatedPrompt(builder.PromptType.number) Dialog accepting numbers
    • time: utilizes the builder.DialogAction.validatedPrompt(builder.PromptType.number) Dialog accepting time (using chrono to parse it)

It’s important to pay special attention to the order of the questions in the JSON file. This is exactly the order that these questions will be presented to the user.

Finally, you have to write the code to use the library.

const builder = require('botbuilder');
const formflowbotbuilder = require('formflowbotbuilder');

const connector = new builder.ConsoleConnector().listen();
const bot = new builder.UniversalBot(connector);

//just a name for the dialog
const myDialogName = 'getFields';

formflowbotbuilder.executeFormFlow('./sample.json', bot, myDialogName).then(function (responses) {
    bot.dialog('/', [function (session) {
        session.beginDialog(myDialogName);
    },
    function (session, results) {
        //responses from the user are in results variable as well as in the responses callback argument
        session.send('results: ' + JSON.stringify(results));
    }]);
}).catch((error) => console.log(error));

We take it as granted that the dialogs generated by our library will be part of a bigger conversation between the bot and the user. This is why we give a custom name to the generated dialog tree. Then we call the Promisified executeFormFlow method, to execute our dynamically generated dialogs!

Check the code here on GitHub and here on npm.

Hope this helps,

Dimitris

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s