Bot framework v4.0 how to execute the previous waterfall step in a dialog

后端 未结 3 1279
太阳男子
太阳男子 2020-12-11 02:31

I\'m trying to create a dialog in which I define multiple waterfall steps. In the context of this dialog, I need sometimes to go back to the previous waterfall step accordin

相关标签:
3条回答
  • 2020-12-11 02:46

    I'm not sure, if it's the right and efficient way to do it, but you can experiment with the State property of the context.ActiveDialog within your Task<DialogTurnResult> function.

    context.ActiveDialog.State["stepIndex"] = (int)context.ActiveDialog.State["stepIndex"] -2;
    
    0 讨论(0)
  • 2020-12-11 03:03

    Waterfall dialogs weren't designed with the idea of 'going backwards' to traverse them, though I can see the possible need to. The only solution I've found is to break your waterfall into smaller "mini" waterfalls, and nest them into one larger waterfall.

            // define and add waterfall dialogs (main)
            WaterfallStep[] welcomeDialogSteps = new WaterfallStep[]
            {
                MainDialogSteps.PresentMenuAsync,
                MainDialogSteps.ProcessInputAsync,
                MainDialogSteps.RepeatMenuAsync,
            };
    

    Then in MainDialogSteps.ProcessInputAsync:

            public static async Task<DialogTurnResult> ProcessInputAsync(
                WaterfallStepContext stepContext,
                CancellationToken cancellationToken)
            {
                var choice = (FoundChoice)stepContext.Result;
                var dialogId = Lists.WelcomeOptions[choice.Index].DialogName;
    
                return await stepContext.BeginDialogAsync(dialogId, null, cancellationToken);
            }
    

    This allows the users to start new dialogs still within the main dialog stack. One of my options I offered was a prompt of a list of phone numbers:

            WaterfallStep[] phoneChoiceDialogSteps = new WaterfallStep[]
            {
                PhoneChoicePromptSteps.PromptForPhoneAsync,
                PhoneChoicePromptSteps.ConfirmPhoneAsync,
                PhoneChoicePromptSteps.ProcessInputAsync,
            };
    
            Add(new WaterfallDialog(Dialogs.PhonePrompt, phoneChoiceDialogSteps));
    

    And finally, in the PhoneChoicePromptSteps.ProcessInputAsync, I allowed for the selection of 'no' from the confirm to ReplaceDialogAsync and effectivly reset this smaller waterfall, without effecting the rest of the overall waterfall:

     public static async Task<DialogTurnResult> ProcessInputAsync(
                WaterfallStepContext stepContext,
                CancellationToken cancellationToken)
            {
                if ((bool)stepContext.Result)
                {
                    await stepContext.Context.SendActivityAsync(
                        $"Calling {stepContext.Values[Outputs.PhoneNumber]}",
                        cancellationToken: cancellationToken);
                    return await stepContext.EndDialogAsync(null, cancellationToken);
                }
                else
                {
                    return await stepContext.ReplaceDialogAsync(Dialogs.PhonePrompt, null, cancellationToken);
                } 
            }
    

    0 讨论(0)
  • 2020-12-11 03:10

    You can use the option parameter in the method "ReplaceDialogAsync" and skip steps with the method "NextAsync".

    For example in my waterfall steps (defined in the constructor):

            AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
            {
                IntroStepAsync,
                ActStepAsync,
                FinalStepAsync
            }));
    
            // The initial child Dialog to run.
            InitialDialogId = nameof(WaterfallDialog);
    

    If you want pass to second step (in my case ActStepAsync) from the final step (FinalStepAsync) , when I going to replace the dialog I use the created a label in the Dialog:

    private const string FLAG = "MY_FLAG";
    

    When I invoke the method from final step I do this :

    return await stepContext.ReplaceDialogAsync(InitialDialogId, FLAG, cancellationToken);
    

    So I only need check the option in the first step if the context has the flag :

        // Use the text provided in FinalStepAsync or the default if it is the first time.
            var messageText = stepContext.Options?.ToString() ?? "welcome-message";
            if (messageText.Equals(FLAG_REPROMPT))
            {
                return await stepContext.NextAsync(null,cancellationToken);
            }
    

    Later this you are in the second step

    0 讨论(0)
提交回复
热议问题