Search code examples
c#entity-frameworkbotframework

How do I load user details from db into memory to personalize my bot


My bot is in a web application that requires user authentication using OAuth. When a user starts a chat session I would like to load the user details into memory to personalize dialogs. Below is the current way i am doing it, but would like advice from anyone that has better method.

private async Task OnMessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
    var name = GetUserDetails(result);

    var message = await result;

    string id = context.Activity.Id;


    string promptText = $"Hi {name}, before we start which product do you want to chat about today?";

    PromptDialog.Choice(
        context: context,
          resume: ChoiceReceivedAsync,
          options: (IEnumerable<SoftwareOptions>)Enum.GetValues(typeof(SoftwareOptions)),
          prompt: promptText,
          retry: "Sorry please select one of the options I listed thanks.",
          promptStyle: PromptStyle.Auto
          );
}

The idea is the GetUserDetails method loads the details like username, firstname, companyId etc. I can then call the user details from any dialog as needed when my bot responds to personalise the conversation.

private object GetUserDetails(IAwaitable<IMessageActivity> result)
{
    var db = new LicensingDbContext();

    string id = "John.Smith";
    var user = (from u in db.AspNetUsers
            where (u.UserName == id)
            select new UserDetails
            {
                FirstName = u.FirstName
            }).ToList();

    return user.First();
}

Solution

  • private async Task OnMessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> activity)
    { 
        var userProfile = await LoadUserData(context);
    
        string promptText = $"Hi {userProfile.FirstName}, before we start what product do you want to chat about today?";
    
        PromptDialog.Choice(
            context: context,
            resume: ChoiceReceivedAsync,
            options: (IEnumerable<SoftwareOptions>) Enum.GetValues(typeof(SoftwareOptions)),
            prompt: promptText,
            retry: "Sorry please select one of the options I listed thanks.",
            promptStyle: PromptStyle.Auto
        );
    }
    
    public async Task<UserProfile> LoadUserData(IDialogContext context)
    {
        LicenseDbContext db = new LicenseDbContext();
    
        var userProfile = (from u in db.AspNetUsers
            join c in db.Companies on u.CompanyID equals c.CompanyID
            where u.UserName == "john.smith"
            select new UserProfile()
            {
                UserName = u.UserName,
                FirstName = u.FirstName,
                CompanyId = u.CompanyID,
                ParentCompany = c.ParentCompanyID,
                }).Single();
        return userProfile;
    }