Saving State data with BotBuilder-Azure in Node.js


We’ve discussed strategies to store state data for bots in .NET, in this article we’ll demonstrate how to do the same for bots built using the Bot Builder SDK for Node.js. In this sample, we’ll be leveraging the botbuilder-azure npm module to save our conversation state data to Azure DocumentDB.

Initial Setup

Note: DocumentDB was recently rebranded to Azure Cosmos DB, click here for details

Use an existing Node.js bot, or create a new one. If you’ve never created a bot using the Node.js SDK before, you can click here to get started and familiarize yourself with the Bot Framework Node.js SDK.

Bot setup to use Azure DocumentDB

The full sample on Github can be found here.

Install the botbuilder-azure node module using npm per the following command:

npm install --save botbuilder-azure

Require the newly installed module in the bot application.

// app.js
...
var azure = require('botbuilder-azure'); 
...

Next we’ll configure the connection settings to connect to the Azure:

var documentDbOptions = {
    host: 'Your-Azure-DocumentDB-URI', 
    masterKey: 'Your-Azure-DocumentDB-Key', 
    database: 'botdocdb',   
    collection: 'botdata'
};

Note: If the database and collection does not exist in the Azure database, they will be automatically created for you.

The host and masterKey values can be found in the keys menu in your DocumentDB settings in the Azure portal, as shown below:

DocumentDB Access Info

Using the botbuilder-azure module, create two new objects to connect to the Azure database. First, create an instance of DocumentDBClient passing in the connection configuration settings (defined as documentDbOptions from above). Next, create and instance of AzureBotStorage passing in the DocumentDBClient object.

var docDbClient = new azure.DocumentDbClient(documentDbOptions);

var tableStorage = new azure.AzureBotStorage({ gzipData: false }, docDbClient);

The bot is now ready to connect to the Azure database, however we need to configure our dialog to save the conversation state data to the database instead of the default connector state service. Below is a simple echo dialog which we’ll use:

var bot = new builder.UniversalBot(connector, function (session) {
    session.send("You said: %s", session.message.text);
}).set('storage', tableStorage);

In the dialog, we use the session object and pass in the custom AzureBotStorage object we created, which will override the connection to the default connector service. Now we’re ready to run our bot locally and test it using the emulator.

Emulator

Note: To use the emulator, you’ll need to add the following environment setting in the .env file - process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;

Back in the Azure portal, we can check if our conversation state was successfully saved. Select ‘Data Explorer’ from the menu, this will allow you to query your database.

CosmosDB state saved

Looks like our conversation state data was successfully stored!

Why use a Custom State Client

Using the default state service, you are limited to using the bot state methods to manage state data.

Reasons to use custom state storage:

  • higher state API throughput (more control over performance)
  • lower-latency for geo-distrubtion
  • control over where the data is stored
  • access to the actual state data
  • store more than 32kb

Community mention

We’ve been receiving lots of cool submissions from the bot developer community. Since we’ve been dicussing state data recently, check out the following example for a neat Node.js implementation using MongoDB

MongoDB Implementation for Node.js custom state storage

Summary

Previously, we demonstrated how you can save your bot’s state data to an Azure database in .NET, leveraging the botbuilder-azure nuget package. Similarly, we released a botbuilder-azure node module to provide the same capability to bots built with the Node.js SDK.

For the complete sample from this post, click here to find it on Github.

Happy Making!

Matthew Shim from the Bot Framework team

References