1
votes

I am developing a bot using MS Bot framework in Node.JS. I am going through documentation on various ways of saving/retrieving state of user conversation with bot.

As per my understanding, for each bot, each user is a different conversation. For e.g. I have 2 bots, BOT-A & BOT-B. And a user with skype ID abc.skype access these bots. This user will be identified using a different conversationID & userID for each bot. I.e. for BOT-A the user's conversationID will be 'ABC' & for BOT-B the conversationID will be 'XYZ'. The userID field in session object will hold data which can identify the user, such as user's publicly visible name in the channel.

As per documentation (saving-state)

userData stores information globally for the user across all conversations.

  1. What is meant by globally here?
  2. What is meant by across all conversations?

conversationData stores information globally for a single conversation. This data is visible to everyone within the conversation so exercise with care when storing data to this property. It’s enabled by default and you can disable it using the bot's persistConversationData setting.

  1. What is meant by single conversation?
  2. Which data is visible to everyone? How the data is visible to everyone, when it is the bot which decides, what response to send as reply or each user message? And who is everyone?

privateConversationData stores information globally for a single conversation but it is private data specific to the current user. This data spans all dialogs so it’s useful for storing temporary state that you want cleaned up when the conversation ends.

dialogData persists information for a single dialog instance. This is essential for storing temporary information in between the steps of a waterfall in a dialog.

What is actual storage mechanism/location for saving state? By this I mean that if I save some data in session.userData and access it after a week for the same user, how come I get the same data. Where is the data saved actually?

What happens if I set persistUserData & persistConversationData to false? Does that mean userData & conversationData will not be persisted. If yes, then it essentially means that I cannot save data. Isn't it? Or does this mean something different?

Can anyone share any example where there are multiple users in same coversations? Or an example which demonstrates capabilities(pros & cons) of these various data saving methods.

Resources I referred:

https://docs.microsoft.com/en-us/bot-framework/nodejs/bot-builder-nodejs-state

2

2 Answers

3
votes

I understand the mix around these notions, it's a bit hard to manage when you haven't tried on several channels and looked at all the messages fields!

Some points about your initial statements:

This user will be identified using a different conversationID & userID for each bot

It's not totally true:

  • UserId: for some channels, userId can be the same for different bots, like SMS where userId is the phoneNumber. For others, it's changing between bots like Messenger where the userId is a Page-Scoped ID.
  • ConversationId: yes you cannot have the same conversationId for 2 users in 2 separate bots. BUT you will also have several conversationId for the same user in some channels. And in some channels where the bot can be in a group conversation, the conversationId is the same for every user.

The userID field in session object will hold data which can identify the user, such as user's publicly visible name in the channel.

It's User field, that contains Id (user key) and Name (publicly visible name).


Then for your questions:

userData stores information globally for the user across all conversations.

userData is consistent between all conversations... of a specific UserId, for a channel! It's not cross-channel as there is no Id which is cross-channel


conversationData stores information globally for a single conversation. This data is visible to everyone within the conversation so exercise with care when storing data to this property. It’s enabled by default and you can disable it using the bot's persistConversationData setting.

As I said, in some channel the bot can be in a group conversation so the conversationId is the same for every user and the information inside conversationData are the same for every user in the conversation

If you want to keep info about a specific user in this conversation, use privateConversationData (or userData if it must be kept more than in this conversation).

I think the documentation is quite clear about where to do what:

These four properties correspond to the four data storage containers that can be used to store data. Which properties you use to store data will depend upon the appropriate scope for the data you are storing, the nature of the data that you are storing, and how long you want the data to persist. For example, if you need to store user data that will be available across multiple conversations, consider using the userData property. If you need to temporarily store local variable values within the scope of a dialog, consider using the dialogData property. If you need to temporarily store data that must be accessible across multiple dialogs, consider using the conversationData property.


What is actual storage mechanism/location for saving state? By this I mean that if I save some data in session.userData and access it after a week for the same user, how come I get the same data. Where is the data saved actually?

You got the same data if you are in the same channel and got the same userId.

There were a storage provided for testing (hosted in the Bot Connector?) but it is not made for production and is deprecated. For the location of the data, you have to implement your own storage with CosmosDB or TableStorage: https://docs.microsoft.com/en-us/bot-framework/nodejs/bot-builder-nodejs-state


What happens if I set persistUserData & persistConversationData to false? Does that mean userData & conversationData will not be persisted.

Yes, not persisted when the conversation ends.

If yes, then it essentially means that I cannot save data. Isn't it? Or does this mean something different?

No, it means you will not be able to get this data again after the conversation, that's all.


Can anyone share any example where there are multiple users in same conversations? Or an example which demonstrates capabilities(pros & cons) of these various data saving methods.

=> Slack channel for example, with a bot deployed in a "channel" (not talking in private DM with the bot)!

You will see that ConversationId looks like Bxxxxxxxx:Txxxxxxxx:Cxxxxxxxx where Bxxxxxxxx is your bot's Slack's ID, Txxxxxxxx is your Slack's Team ID and Cxxxxxxxx is your current channel Slack's ID

Sample in one of my tests, when I look at the activity fields:

  • Conversation.Id= Bxxxxxxxx:Txxxxxxxx:Cxxxxxxxx,
  • Conversation.Name= general, (name of Slack's channel where I am using the bot)
  • From.Id= Uxxxxxxxx:Txxxxxxxx, (my Slack's user ID)
  • From.Name= nicolas, (my Slack's user name)
  • Recipient.Id= Bxxxxxxxx:Txxxxxxxx, (my bot's Slack's ID)
  • Recipient.Name= myBotName (my bot's Slack's name)
0
votes

I have a pager module like this.

var Paginator = function (items, limitItems) {
    this.currentPage = 1;
    this.nextPage = this.currentPage + 1;
    this.totalPage = Math.ceil(items.length / limitItems);
    this.count = 0;
    this.delimiter = this.count + limitItems;
    this.limitItems = limitItems;
}
Paginator.prototype.getItems = function (items) {
// My code
}
module.exports = Paginator;

I store the pager in session.dialogData.paginator. Theoretically this area should remain unchanged for the next step in the waterfall, however this is not what happens. After passing through builder.Prompts.confirm the Paginator.prototype.getItems method is lost. I conclude that the documentation is incorrect when stating that session.dialogData remains in the dialog.

So, where would this kind of information be? Thanks