Understanding Azure Bot State

When you chat with a bot built with Azure Bot Service, you will have to maintain user state. Example, the options that the user chose last time, or the usernames of all users in a conversation.

Conversation State Types

Azure Bot Service has 3 different states:

User State
This state is related to the user on a specific channel regardless how many conversation they have. So, if the user is chatting with a bot from Facebook channel and connected to the same bot in another conversation , any values saved in user state will be visible in both chats. This is useful in scenarios where you want to save an info about the user like the username or preference that will be used in all conversation for this user.

Conversation State
This state is scoped to the conversation only but not to each user. If you have 3 users chatting with the bot, any data saved in conversation state will be shared across all users. This is used in cases where the data saved is not related to a specific user such as statistics. If the user connected to another session with the bot, the info saved her will not be visible in the other conversation

Private Conversation State
Here, the framework manages the state for each user in each conversation. Imagine a scenario where the user is submitting a ticket. You want the ticket info to be scoped to this conversation only because they may be submitting another ticket with another conversation.

The state storage saves each data in a key/value store. The keys used for each state type is as below:

  • User Sate: {Activity.ChannelId}/users/{Activity.From.Id}#YourPropertyName
  • Conversation state: {Activity.ChannelId}/conversations/{Activity.Conversation.Id}#YourPropertyName
  • Private conversation: {Activity.ChannelId}/conversations/{Activity.Conversation.Id}/users/{Activity.From.Id}#YourPropertyName

Conversation Storage

By default, the state variables are stored in memory. But you can change that from the startup.cs. In the example below, I have configured it to use Azure Table storage to store the state, this makes it persistent. You can create your own state by inheriting from IStorage

Next, you configure which state types you want to use, in this example, I use the conversation state. To use the user state, you have to create an instance of UserState and add it as a singleton just like conversation state.

public void ConfigureServices(IServiceCollection services)
          //IStorage dataStore = new MemoryStorage(); 
          IStorage dataStore = new Microsoft.Bot.Builder.Azure.AzureBlobStorage("connection string", storageContainer);

          var conversationState = new ConversationState(dataStore);

State property accessors


Now, its time to use the state in our bot. To do that, you have to use a property accessor which allows you to read and update data to the state storage. Note that calling the GetAsync and SetAsync on the state accessor doesn’t actually save the state data in the storage system. You have to call the SaveChangesAsync as you can see from the sequence diagram above.

To understand more about state property accessors and how to use it to read and update data into bot state, go through this link


Azure Bot Service Overview

Today, I started learning Azure BOT Service, I will summarise each section into a blog post.

What is BOT?

A BOT is a modern way of user interaction. Instead of user clicking buttons and typing data in text fields, the user will be chatting or talking to an application that will understand the human language and respond accordingly.
This of course increase the human interaction with your site or application and also decrease the need for employees to handle user requests.
Imagine a user who wants to know about car insurance quote, instead of calling the insurance company, they can chat with the bot or even call it and ask them about the prices and the bot can respond as if it was a human or delegate the call to a human if it is not able to assist. This can save a lot for the company.

How BOT works?

Users interact with the BOT through a channel. A channel can be DirectLine like the case when you chat directly with the BOT from web site. It can be Facebook Messenger, Twitter, or any other popular social media platform.
The chat between users and BOT can be a text messages, a card that display graphic content to the user or a voice message or even an interactive form that ask the user to enter some information like SSN or Policy Number.
BOT can also use AI services such as Azure Congnitive Services to make it smarter.


BOT HTTP Communication

The communication between the BOT and Users/Channels take place through HTTP Post requests. When a user joins a conversation, an HTTP message is posted to the BOT service and the BOT just acknowledge the message with 200 OK response. Then, the BOT joins the conversation and again another HTTP Post message is sent to the channel and the channel replies back with a 200 Ok. These messages are called ConversationUpdate messages.
All these messages between the BOT and the channel are called activities. During the ConversationUpdate activity, you can check the members added or removed.
Once the connection is established, the messages send from the channel to the BOT are sent as an HTTP Post requests and the BOT replies back with a different HTTP Post not via response to the original HTTP Post request. So, as you can see from the image below, the Channel sent a Hi message, the BOT just echoed the message but it can send a different message. Then, the channel confirmed with a 200 Ok to the BOT and finally the BOT replies back to the original hi message with 200 Ok.
With the current version (4) it may not be very clear about the HTTP post messages but if you tried with the older version (3), it was very clear and when you create a new project you can clearly see an API controller called MessagesController and you can access it via /api/messages.

activity diagram

Defining Rounds

Humans talk one at a time, one talk and the others listen (At least this is what should happen 🙂 ).

activity processing stack

The important thing to note in the above image is the TurnContext
which holds information about whose turn and what data was sent (Typically JSON) and the middleware which holds some components that execute in order to do something with the activity received. After all middleware components finish execution, it passes the control to the Turn Handler which will execute the application logic that will decide the response that will be sent to the channel/user.
The middleware is executed on the incoming activity received from the channel and also on the outbound activity sent from the bot to the channel itself.