-2

Previously I was saving the UserData using the StateClient object but since this will be deprecated I have implemented a solution that saves the ConversationData in a private database. The UserData was set outside a dialog context using the botCredentials : `

var botCred = new MicrosoftAppCredentials(
                    BotConfiguration.Cfg.MicrosoftAppId,
                    BotConfiguration.Cfg.MicrosoftAppPassword);
                var stateClient = new StateClient(botCred);
                BotState botState = new BotState(stateClient);
                BotData botData = new BotData(eTag: "*");
                botData.SetProperty<string>("LastName", lastName);
                botData.SetProperty<string>("FirstName", firstName);
                stateClient.BotState.SetUserData("webchat", userId, botData);

The issue is that this was done in an external controller.

How can I achieve the same results but using my custom database for storage ?

Thank you

Sebastian
  • 617
  • 2
  • 10
  • 30

1 Answers1

0

I think you are asking how to read/write state data when you do not have access to the context object. In that case you would use something like the following code:

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
    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);

                userData.SetProperty("key 1", "value1");
                userData.SetProperty("key 2", "value2");

                await botDataStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None);
                await botDataStore.FlushAsync(key, CancellationToken.None);
            }
            await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
    }
}
D4RKCIDE
  • 3,439
  • 1
  • 18
  • 34
  • I do not have access to the activity object, when I want to save that data, I am in an external controller. What I want to do is to save the claims from the claims principal to the bot user data before the messagesController has been called for the first time. – Sebastian Mar 23 '18 at 20:30
  • Why can't you just do this in the messages controller? – D4RKCIDE Mar 23 '18 at 20:33
  • Because I am using a communication chanel in which I am doing the authentication. For the messagesController I am using the [botauthenticator] attribute, which autheticates the bot and here I do not have the previous claims, from the communiction channel. – Sebastian Mar 23 '18 at 21:54
  • So you are handling the authentication outside of the bot completely rather than inside the bot's chat dialog? – D4RKCIDE Mar 23 '18 at 23:22
  • Yes, indeed, and in the bot I do not have the claims for the logged in user. – Sebastian Mar 24 '18 at 07:40
  • This is not a directly supported scenario in bot framework. You could probably figure out a hack to make it work, but without the activity, I do not see a straightforward way to accomplish this. – D4RKCIDE Mar 26 '18 at 16:47