Search code examples
c#botframework

Botframework V4: user typing response instead of clicking the choice prompt button


I have a choice prompt and I wanted to make it so that even if a user types something else that synonyms with the choice the dialog can still move on. I tried doing this but its not working.

public class InitialQuestions : WaterfallDialog
{
    public InitialQuestions(string dialogId, IEnumerable<WaterfallStep> steps = null)
        : base(dialogId, steps)
    { 

        AddStep(async (stepContext, cancellationToken) =>
        {
            var choices = new[] { "Agree" };
            return await stepContext.PromptAsync(
                "choicePrompt",
                new PromptOptions
                {
                    Prompt = MessageFactory.Text(string.Empty),
                    Choices = ChoiceFactory.ToChoices(choices),
                    RetryPrompt = MessageFactory.Text("Click Agree to proceed."),
                });
        });

        AddStep(async (stepContext, cancellationToken) =>
        {
            var response = (stepContext.Result as FoundChoice).Value.ToLower();
            var textResponse = (stepContext.Result as FoundChoice).ToString().ToLower();

            if (response == "agree" || textResponse == "okay" || textResponse == "ok")
            {
                return await stepContext.NextAsync();
            }
            else
            {
                return await stepContext.ReplaceDialogAsync(InitialQuestions.Id);
            }
        });
    }

    public static string Id => "initialQuestions";

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

Solution

  • A choice prompt has to validate the user input by comparing it to a list of choices and the dialog will not proceed until valid input is supplied. You're trying to validate the input in the next step, but the next step won't be reached until the input is already validated and that's why textResponse will never be "okay" or "ok".

    Luckily, choice prompts have a builtin way of providing synonyms for each choice. Instead of

    Choices = ChoiceFactory.ToChoices(choices),
    

    you could do something like

    Choices = new List<Choice>
    {
        new Choice
        {
            Value = "Agree",
            Synonyms = new List<string>
            {
                "Okay",
                "OK",
            },
        },
    },