How to fix next step navigation with oauth prompt

2019-06-14 04:48发布

问题:

I'm trying to implement authentication in BOT using OAuthPrompt in an WaterFallDialog class which contains 2 steps:

  1. Calls the OathPrompt which provides sign in button to provide credentials
  2. Gets the token, based on token retrieval success message is displayed and user is navigated to another dialog or else failure message is displayed with

user to re-prompt with login

Issue: I have to make user to navigate the user automatically to step#2 without any manual intervention upon successful validation.

Current Situation: I'm unable to do it as I have to type something to make user to navigate to step#2

Problem in: Emulator and Webchat channel

Language: C#

Bot SDK: V4

This is a new BOT i am trying to build as based on authentication i am displaying other options i.e. navigating user to another dialog for performing other options.

I have already tried using below in STEP#1:

stepContext.NextAsync()

This did not work, i had to eventually type something to navigate and more over it gave an exception invalid step index. I have also tried by providing the index number which also did not work along with Cancellation token

Expected Result: User to navigate automatically to step#2 upon successful authentication using OAUTH Prompt Actual Result: Not able to navigate it until typed anything

Adding code Below:

public class LoginDialog : WaterfallDialog
{
    public LoginDialog(string dialogId, IEnumerable<WaterfallStep> steps = null)
         : base(dialogId, steps)
    {
        AddStep(async (stepContext, cancellationToken) =>
        {
            await stepContext.Context.SendActivityAsync("Please login using below option in order to continue with other options, if already logged in type anything to continue...");

            await stepContext.BeginDialogAsync(EchoWithCounterBot.LoginPromptName, cancellationToken: cancellationToken); // This actually calls the  dialogue of OAuthPrompt whose name is is in EchoWithCounterBot.LoginPromptName.  

            return await stepContext.NextAsync(); // It comes here throws the error as explained above but also i have to type for it to navigate to below step
        });

        AddStep(async (stepContext, cancellationToken) =>
        {
            Tokenresponse = (TokenResponse)stepContext.Result;

            if (Tokenresponse != null)
            {

                await stepContext.Context.SendActivityAsync($"logged in successfully... ");


                return await stepContext.BeginDialogAsync(DisplayOptionsDialog.Id); //Here it goes To another dialogue class where options are displayed
            }
            else
            {
                await stepContext.Context.SendActivityAsync("Login was not successful, Please try again...", cancellationToken: cancellationToken);


                await stepContext.BeginDialogAsync(EchoWithCounterBot.LoginPromptName, cancellationToken: cancellationToken);
            }

            return await stepContext.EndDialogAsync();
        });
    }

    public static new string Id => "LoginDialog";

    public static LoginDialog Instance { get; } = new LoginDialog(Id);
}

回答1:

BeginDialogAsync or PromptAsync should always be the last call in a step, so you'll need to get rid of NextAsync. OAuthPrompt.BeginDialogAsync is special because you don't know if it's going to end the turn or not. If there's already an available token then it will return that token and automatically continue the calling dialog, which would be the next step in your case. If there's no token available then it will prompt the user to sign in, which needs to be the end of the turn. Clearly in that case it makes no sense to continue to the next step before giving the user a chance to sign in.

Other than that, your code should work. Please update both your Bot Builder packages and your Emulator to the latest versions (currently 4.4.3 for Bot Builder and 4.4.0 for Emulator). The Emulator should continue to the next step automatically when you sign in, but Web Chat will likely require the user to enter a magic code.

EDIT: If you are using a version of Emulator that does not handle automatic sign-ins correctly, you can configure Emulator to use a magic code instead in the settings.