Search code examples
botframework

Next step after PromptAsync is not called


I have this simple dialog, with 2 simple waterfall steps. The user sees "How may I help you today?" and when it answers, nothing happens. I can't get Validate to work.

Am I missing something? I'm using SDK 4.1.5.

public ComplaintsDialog() : base(nameof(ComplaintsDialog))
{
    var steps = new WaterfallStep[]
    {
        Ask,
        Validate
    };

    AddDialog(new WaterfallDialog("flow", steps));
    AddDialog(new TextPrompt("asking"));
}

private static async Task<DialogTurnResult> Ask(WaterfallStepContext sc, CancellationToken cancellationToken)
{
    return await sc.PromptAsync("asking", new PromptOptions { Prompt = new Activity { Text = "How may I help you today?", Type= ActivityTypes.Message}  }, cancellationToken);
}

private static async Task<DialogTurnResult> Validate(WaterfallStepContext sc, CancellationToken cancellationToken)
{
    var answer = sc.Result;
    await sc.Context.SendActivityAsync(answer.ToString());
    return await sc.EndDialogAsync();
}

}

UPDATE I tried to simplify the code, and this is how I currently call ComplaintsDialog directly from the main bot. It looks like the stack is always empty when it gets to await dc.ContinueDialogAsync();, so it's going into a loop and start ComplaintsDialog over and over again

public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken)
        {
            // Create dialog context.
            var dc = await _dialogs.CreateContextAsync(turnContext);

            switch (turnContext.Activity.Type)
            {
                case ActivityTypes.Message:

                    // Continue outstanding dialogs.
                    await dc.ContinueDialogAsync();

                    // Begin main dialog if no outstanding dialogs/ no one responded.
                    if (!dc.Context.Responded)
                    {
                        await dc.BeginDialogAsync(nameof(ComplaintsDialog));
                    }

                    break;

                case ActivityTypes.ConversationUpdate:
                    if (dc.Context.Activity.MembersAdded != null && dc.Context.Activity.MembersAdded.Any())
                    {
                        foreach (var newMember in dc.Context.Activity.MembersAdded)
                        {
                            if (newMember.Id != dc.Context.Activity.Recipient.Id)
                            {
                                await dc.BeginDialogAsync(nameof(WelcomeDialog));
                            }
                        }
                    }
                    break;                    
            }          
        }

Solution

  • The code example you provided looks like it should be working so the problem is probably elsewhere.

    My guess is that you are starting the ComplaintsDialog inside of a WaterfallStep (from another dialog) so make sure that you are calling the BeginDialogAsync method like this:

    return await stepContext.BeginDialogAsync(nameof(ComplaintsDialog));

    instead of:

    await stepContext.BeginDialogAsync(nameof(ComplaintsDialog));

    If this is not the error probably more information is necessary

    Update

    Your problem is on the OnTurnAsync method. You're not saving the new turn into the conversation state. The Message case on your switch should look like this:

    case ActivityTypes.Message:
    
       if (dc.ActiveDialog == null)
       {
          await dc.BeginDialogAsync(nameof(ComplaintsDialog), cancellationToken);
       }
       else
       {
          await dc.ContinueDialogAsync(cancellationToken);
       }
    
       await _accessors.ConversationState.SaveChangesAsync(turnContext);
    
       break;
    

    And your constructor:

    private readonly MyBotAccessors _accessors;
    public MyBot(MyBotAccessors accessors, ILoggerFactory loggerFactory)
    {
    
       ...       
    
       _accessors = accessors ?? throw new System.ArgumentNullException(nameof(accessors));
    
       ...
    
     }
    

    SaveChangesAsync documentation