Bot State Service will soon be retired on March 31st, 2018

Up until now, we have been providing a default state service for bots built using either the Node.js or .NET SDK’s. The state service is used to store and retrieve user and conversation data within the context of a conversation. Over the last several months as the bot framework has grown, we’ve been encouraging users to implement their own state storage for several reasons and benefits:

  • Improved latency – you won’t be relying on the connection of the default connector service
  • Direct control over your bot’s conversation state and customer data

Well, there’s now another reason that you’ll want to get up to date on handling bot state data, because soon the Bot Framework State service will no longer be supported.

Bot Framework State Service will cease operating on March 31st 2018

The Bot Framework State service will be deprecated on March 31st, 2018. This means that by default, bots registered with the Bot Framework will no longer be able to rely on the state service to send and retrieve conversation contextual conversation state information to and from their bots.

Previously, we published this article which provides a step-by-step walk-through to create a custom state store using Azure extensions. There’s also documentation which more formally describes the Bot Framework state service – what it is, and and how you can use it.

Documentation – Migrate your bot to Azure

State Data for .NET 

State Data for Node.js 

The underlying concepts behind creating and deploying a data store, connecting it to your bot, and leveraging the Azure extensions package to save conversation state data remains the same, however there are some small updates to the code that we need to make.

Azure Table Storage:

In Global.asax.cs

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        Conversation.UpdateContainer(
            builder =>
            {
                builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly()));

                // Bot Storage: register state storage for your bot
                // Default store: volatile in-memory store - Only for prototyping!
                // var store = new InMemoryDataStore();

                // This sample will use Azure Table Storage 
                var store = new TableBotDataStore(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);
          
                builder.Register(c => store)
                    .Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
                    .AsSelf()
                    .SingleInstance();                 
            });

        GlobalConfiguration.Configure(WebApiConfig.Register);
    }
}

Click here to learn more about Azure Table storage.

DocumentDB (CosmosDB):

In Global.asax.cs

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        Conversation.UpdateContainer(
            builder =>
            {
                builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly()));

                // Bot Storage: register state storage for your bot
                // Default store: volatile in-memory store - Only for prototyping!
                // var store = new InMemoryDataStore();

                var uri = new Uri(ConfigurationManager.AppSettings["DocumentDBUri"]);
                var key = ConfigurationManager.AppSettings["DocumentDBKey"];

                // this sample uses Azure DocumentDB (CosmosDB)
                var store = new DocumentDbBotDataStore(uri, key);

                builder.Register(c => store)
                    .Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
                    .AsSelf()
                    .SingleInstance();
            });
                
        GlobalConfiguration.Configure(WebApiConfig.Register);
    }
}

Click here to learn more about DocumentDB.

The primary changes to both code samples above relate to changes in the Autofac library for dependency injection. Everything else should remain the same.

Well what about for prototyping bots? Previously, many new bot users were relying on the default Bot Framework State service unknowingly, and aren’t aware of the state service until far later when they come across in issue which they’d need it, or they need access to their bot’s conversation state information. To address this, we’re providing a local memory storage solution so that you can still prototype new bots before releasing them to production.

Default state data will be stored in local memory

We’ve also recently updated many of the samples in the BotBuilder repo to reflect this. Similar to the changes noted above, let’s take a look at the Global.asx.cs file for the AlarmBot sample.

var store = new InMemoryDataStore();

// Other storage options
// var store = new TableBotDataStore("...DataStorageConnectionString..."); // requires Microsoft.BotBuilder.Azure Nuget package 
// var store = new DocumentDbBotDataStore("cosmos db uri", "cosmos db key"); // requires Microsoft.BotBuilder.Azure Nuget package 

builder.Register(c => store)
    .Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
    .AsSelf()
    .SingleInstance();

The InMemoryDataStore object provisioned by the Bot Builder SDK provides all of the work for your bot to save conversation state temporarily in your computer’s local memory. This memory will only be used when your bot is being run, and will automatically be cleared of all conversation state data when you close your bot application. This will allow both new and experienced bot developers to get started or prototype their bots before committing to a dedicated custom state store.

State data for Node.js

For Node.js bots, there’s nothing new you need to know to create your own state service. The above changes for bots built using the .NET SDK’s are due to changes with Autofac which had to be adapted, which isn’t something you need to consider for Node.js bots. To create a custom state store for Node.js bots, you can still refer to our docs for the following:

Custom state data using Azure Table for Node.js

Custom state data using CosmosDB for Node.js

Local memory storage for Node.js

Referring to app.js in the ‘first Run’ sample in the BotBuilder Node.js repo, we create a new instance of MemoryBotStorage called inMemoryStorage in our sample code below.

var builder = require('../../core/'); 

// Bot Storage: Here we register the state storage for your bot. 
// Default store: volatile in-memory store - Only for prototyping!
// We provide adapters for Azure Table, CosmosDb, SQL Azure, or you can implement your own!
// For samples and documentation, see: https://github.com/Microsoft/BotBuilder-Azure
var inMemoryStorage = new builder.MemoryBotStorage();

// Setup bot and root message handler
var connector = new builder.ConsoleConnector().listen();
var bot = new builder.UniversalBot(connector, function (session) {
    session.send("%s, I heard: %s", session.userData.name, session.message.text);
    session.send("Say 'help' or something else...");
}).set('storage', inMemoryStorage); // Register in memory storage;

We then use the .set method to configure local memory storage for your bot. This will behave in the same way as for .NET bots in the examples above. Bots configured this way will use your computer’s local memory to save your bot’s conversation state data while prototyping, which will automatically clear whenever you terminate your bot process.

Azure Service Bots

For bots deployed on the Azure Bot Service, existing customers will need to migrate the registration before March 31, 2018.  To do this, open your bot’s registration page, and click Migrate. (There will be a Migrate button for each bot that requires migration.) Please note that the migration is a non-destructive update with zero downtime and includes the option to roll back.

Summary

We’ve been encouraging bot developers using the Bot Framework to use their own custom state service for a while. The default Bot Framework State service was intended for prototyping purposes only, and not designed to accommodate production bots. The state service will be deprecated on March 31, 2018 and will no longer be supported. Bot developers moving forward will be able to prototype their bots using temporary local memory storage as described in this article. Creating your own custom state service for your bot provides multiple benefits including improved latency and direct control over your bot’s conversation state and contextual user conversation state information, and we’ve provided multiple resources to guide you to do so. We appreciate the feedback we’ve been receiving from the bot developer community, which has helped us a lot in improving the Bot Framework as a whole. We also hope that we can continue helping you – the bot developer community, create better and better bot experiences for your users.

Happy Making!

The Bot Framework Team.