Teams bot conversation history confusion

Occasional Contributor

We are developing a teams tab + bot app. All in one. We send adaptive cards a few times a day to the user but are confused how bot conversations are stored. No matter what we remove they show up as we keep installing and iterating new teams app versions.

 

For example, we used to have this code

const adapter = new BotFrameworkAdapter(adapterOptions)

const memoryStorage = new MemoryStorage()

const conversationState = new ConversationState(memoryStorage)

const bot = new TeamsActivityService(conversationState)

 

We thought, oh great, we're using memory storage so if we remove it, reinstall the app for the user, everything will disappear but it doesn't, conversations get reloaded.

 

We now have something like this:

const adapter = new BotFrameworkAdapter(adapterOptions)

const bot = new TeamsActivityService()

...

adapter.continueConversation(conversationReference, async () => {

 bot.sendActivity()

})

 

export class TeamsActivityService extends TeamsActivityHandler {

  constructor() {

    super()

  }

 ...

}

 

We ultimately want to control conversation history and create a custom storage instead of MemoryStorage but we don't even understand how history is stored, controlled and populated. Without memory storage, it works fine, With it, it works fine. How do we control where it's coming from? How do we clear it? Please help

 

6 Replies
@soulglow-Thanks for reporting your issue.
We will investigate this issue and get back to you.

@soulglow -The Bot Framework provides a service for tracking the context of a conversation, called Bot Framework State. It enables you to store and retrieve data associated with a user, conversation or a specific user within the context of a conversation.

By default, Bot Framework uses the Bot Framework State to store conversation data. It is designed for prototyping, and is useful for development and testing environments. At the time of this writing, it has only a size limit of 32KB. Learn more about data management.

For production environments, it’s highly recommended to use a NoSQL database to store data as documents, such as Azure Cosmos DB. To customize your bot conversation data storage, you can use the Bot Builder SDK Azure Extensions. If you are developing your bot with Bot Builder SDK in C#, you have to edit the Global.asax file:

 

protected void Application_Start()
{
     // Adding DocumentDB endpoint and primary key
     var docDbServiceEndpoint = new Uri("<your documentDB endpoint>");
     var docDbKey = "<your documentDB key>";

    // Creating a data store based on DocumentDB
     var store = new DocumentDbBotDataStore(docDbServiceEndpoint, docDbKey);

    // Adding Azure dependencies to your bot (documentDB data store and Azure module)
     var builder = new ContainerBuilder();

    builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly()));           
    
     // Key_DataStore is the key for data store register with the container
     builder.Register(c => store)
         .Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
         .AsSelf()
         .SingleInstance();

    // After adding new dependencies, update the container
     builder.Update(Conversation.Container);

    GlobalConfiguration.Configure(WebApiConfig.Register);
}

 

If you run your bot and open your Cosmos DB service on Azure Portal, you can see all stored documents (clicking on Data Explorer).

Reference Document-1.Write directly to storage - Bot Service | Microsoft Learn
2.Bot conversation history with Azure Cosmos DB | Azure Blog and Updates | Microsoft Azure

@Sayali-MSFT thank you but we've seen these links before. A few follow-up questions:

1) we need an example in javascript/typescript if you have one

2) how come if we remove all traces of doing anything with storage, we still see the conversation history? this piece hasn't been answered. Are you saying it stores it in cosmosdb autotmatically? we don't want to store in cosmos, we want to write a custom one but need to understand how it works if we don't specify anything as we're seeing history without any code as mentioned in the original post. Thanks.

@soulglow -Here is one way, You can use the ConcurrentDictionary to add, retrieve, update, and remove items from a System.Collections.Concurrent.ConcurrentDictionary<TKey,TValue>. This collection class is a thread-safe implementation.

public ProactiveBot(ConcurrentDictionary<string, ConversationReference> conversationReferences, IConfiguration configuration)
        {
            _conversationReferences = conversationReferences;
            _configuration = configuration;
        }

        private void AddConversationReference(Activity activity)
        {
            var conversationReference = activity.GetConversationReference();
            _conversationReferences.AddOrUpdate(conversationReference.User.AadObjectId, conversationReference, (key, newValue) => conversationReference);
        }

 

Reference sample -1. Microsoft-Teams-Samples/ProactiveBot.cs at 94b4bf9aea97eff41a8bf787cfb3974104745306 · OfficeDev/Micr...
2.Microsoft-Teams-Samples/proactiveBot.js at 9906633fe8c90a1c48f36f30f28ce00cb94c89ed · OfficeDev/Micr...

For the second query, We are checking with the engineering team and get back to you.



Hi. So your examples are all using C#, we don't know it and as I mentioned we use typescript/javascript. We don't know how to apply them.

My main question is how the conversation history is stored. I don't understand the difference between your first reply which uses DocumentDbBotDataStore and your second example which uses a dictionary. What's the connection between these 2 examples? Again, we're not C# developers.

May be you can describe:
1) if we don't specify any memory storage or documentdb storage, how come conversations never disappear?
2) if we had to write a custom one, what would we need to do in typescript? can you explain step by step?
@soulglow - We are checking with the engineering team and get back to you.