Search code examples
c#.netoauthbotframework

OAuthPrompt Waterfall needs to begin twice to let RouteAsync be called more than once


I'm trying to authorize a user with the built in OAuthPrompt. I've combined the virtual assistant template with BotBuilder-Samples\samples\csharp_dotnetcore\46.teams-auth as I will be using the Teams channel for my bot ultimately. My problem occurs based on where in the code I attempt to authorize the user. I've tried two places:

Before showing this, I feel WaterfallDialog is a relevant piece. I am using the Waterfall dialog in the 46.teams-auth minus two steps.:

AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
{
      PromptStepAsync,
      LoginStepAsync,
}));
  1. RouteAsync

    protected override async Task RouteAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
    {
        var OAuthResult = await dc.BeginDialogAsync(nameof(WaterfallDialog));
        if (OAuthResult.Result == null)
        {
            await dc.Context.SendActivityAsync(MessageFactory.Text("Please press the Login button."), cancellationToken);
        }
        else
        {
              // ... regular route stuff, like luis check etc
        }
    }
    

This runs the prompt and I am able to log in, but RouteAsync never gets called again.

  1. OnInterruptDialogAsync

    var OAuthResult = await dc.BeginDialogAsync(nameof(WaterfallDialog));
    if (OAuthResult.Result == null)
    {
        await dc.Context.SendActivityAsync(MessageFactory.Text("Please press the Login button."), cancellationToken);
        return InterruptionAction.StartedDialog;
    }
    else
    {
        return InterruptionAction.NoAction;
    }
    

This allows my user to log in and then interact with the LUIS portion of the RouteAsync method (which checks if a user is logged in every time before running any LUIS methods). The issue with this one is that because it is in the OnInterruptDialogAsync method when I start the bot in the emulator two threads run through this method and the user gets prompted twice. I've tried to make it so that dc.BeginDialogAsync(..) only gets called once by checking if the dc.ActiveDialog is not OAuthPrompt before calling it, but this only prompts the user once and then never allows them to log in.

I've also tried to set the InitialDialogId = nameof(WaterfallDialog) within MainDialog.cs's constructor, but this makes it so the user is never prompted.

Any help with this is appreciated. I'm also open to sharing my project but not in a public place. Thank you.


Solution

  • This is fixed by going into bot framework emulator settings (the gear at the bottom left), and under User Settings making sure that Use a sign-in verification code for OAuthCards is ticked.