Search code examples
c#botframework

How can I access Bot Framework ConversationData outside of a dialog like in messages controller?


In a dialog within my bot, I store a flag value in the ConversationData like so:

context.ConversationData.SetValue("SomeFlag", true);

Later, I need to check that flag in my MessagesController, before the message is dispatched to a dialog. As per this previous question I tried retrieving the ConversationData in via the StateClient like this:

public async Task<HttpResponseMessage> Post([FromBody] Activity incomingMessage)
{
    StateClient stateClient = incomingMessage.GetStateClient();
    BotData userData = await stateClient.BotState.GetConversationDataAsync(message.ChannelId, message.Conversation.Id);
    bool finishedQuote = userData.GetProperty<bool>("SomeFlag");
    //...
    // do conditional logic, then dispatch to a dialog as normal
}

However, at runtime, the userData variable holds a BotData object where userData.Data is null, and I'm unable to retrieve any stored flags via GetProperty. I don't see anything in the relevant documentation that helps shed light on this issue - what might I be doing wrong here? Is there something I'm misunderstanding?


Solution

  • The following should work for what you need:

    if (activity.Type == ActivityTypes.Message)
    {
    
        var message = activity as IMessageActivity;
        using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
        {
            var botDataStore = scope.Resolve<IBotDataStore<BotData>>();
            var key = Address.FromActivity(message);
    
            ConversationReference r = new ConversationReference();
            var userData = await botDataStore.LoadAsync(key, BotStoreType.BotUserData, CancellationToken.None);
    
            //you can get/set UserData, ConversationData, or PrivateConversationData like below
            //set state data
            userData.SetProperty("key 1", "value1");
            userData.SetProperty("key 2", "value2");
            //get state data
            userData.GetProperty<string>("key 1");
            userData.GetProperty<string>("key 2");
    
            await botDataStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None);
            await botDataStore.FlushAsync(key, CancellationToken.None);
        }
        await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
    }