Search code examples
c#botframework

Bot Framework - Wait for User To Click Hero Card Action In Waterfall Dialog


I've been trying to figure out how to "pause" a waterfall on a step showing a carousel and wait for user input.

I've got a working implementation but I'm totally convinced there is a better / tidier way to do this.

Inside a waterfall step I have this code:

if (search.Result != null && search.Result.Properties.Any())
{
    var carousel = CarouselBuilder.BuildCarousel(search.Result);
    await stepContext.Context.SendActivityAsync(carousel);
    //return await stepContext.ContinueDialogAsync(cancellationToken);
    return await stepContext.PromptAsync("propertySelected", new PromptOptions
    {

    }, cancellationToken);
}

my propertySelected dialog is this:

public class EventActivityPrompt : ActivityPrompt
{
    public EventActivityPrompt(string dialogId, PromptValidator<Activity> validator)
        : base(dialogId, validator)
    {
    }
}

Which requires a validator like this:

public static class ActivityPromptValidator
{
    public static async Task<bool> ActivityValidator(
        PromptValidatorContext<Activity> promptContext,
        CancellationToken cancellationToken)
    {
        return true;
    }
}

This passes values to the next step ok

AddStep(async (stepContext, cancellationToken) =>
{
    botState.InterestedPropertyIdentifier = stepContext.Result.ToString();

    return await stepContext.BeginDialogAsync(MyNextDialog.Id, cancellationToken);
});

All these empty blocks and a validator that just returns true suggests this isn't the best method of getting this working but I've not enough experience with the Bot Framework to improve on this at the moment. There also doesn't appear to be any documentation that I can find that discusses this.

How can I best handle waiting for user input?

I think there used to be a .Wait() method in BF v3 which is all I can find on this topic but I've on v4.


Solution

  • It has been a little while since this question was asked, but for anyone looking for an implementation where the bot provides a Hero Card with (probably) buttons to select from and you want to give a pause until user selection(or a text), do this with

    return new DialogTurnResult(DialogTurnStatus.Waiting);

    Example:

        var heroCard = new HeroCard
        {
            Title = "some title",
            Subtitle = "some subtitle",
            Text = "Please select one of the mentioned",
            Buttons = cardObject
        };
    
        await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(heroCard.ToAttachment()));
    
        return new DialogTurnResult(DialogTurnStatus.Waiting);