Search code examples
c#.netbotframeworkadaptive-cards

Prompt using a dynamically generated Adaptive Card that depends on each scenario


I have a custom WaterfallDialog and one of the steps prompts the user to fill a variable set of options in a dish (for restaurants).

enter image description here

The problem is that I want the card to be generated dynamically: Depending on the selected dish, the amount of Input.ChoiceSets will vary. I mean, the layout of the cad itself will vary depending on the dish type.

My call to the make the prompt is like this:

private async Task<DialogTurnResult> ConfigureDishStep(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    return await stepContext.PromptAsync("ConfigureDish", new PromptOptions(), cancellationToken);
}

But as you see, the PromptAsync calls the prompt using the dialogId ("ConfigureDish") that has to be registered within the parent dialog using AddDialog. This leaves no way to configure the card depending on the dish type. If I have to register each prompt before using it, and this is done inside the constructor of the parent dialog:

AddDialog(new AdaptiveCardPrompt(ConfigureDish, CreateAdaptiveCardPromptSettings()));

Then how to provide a dynamically generated card for each of the ConfigureDishStep?


Solution

  • While it's great to see people using Michael Richardson's Adaptive Card prompt, it unfortunately is different from other prompts in that it uses an immutable attachment created at the time of construction. It makes sense in a way for the Adaptive Card prompt to only allow one specific card to be used, but it makes it difficult to do what you're trying to do using that class. I can think of a few options for you:

    1. Construct multiple Adaptive Card prompts. While it's common to want to reuse a prompt as much as possible, it can be considered good practice to define separate prompts for each case even when you don't have to. Though in your case you may have to.
    2. Manipulate the activity behind the scenes. There is always a way to hack the code to do what you want it to. You could for example use middleware to manipulate the activity as the prompt is sending it, or you could use reflection to modify the private variable that holds the card.
    3. Don't use that Adaptive Card prompt. You could create your own class that does what you want. Alternatively, a common solution is to just use a text prompt and then manually set the incoming activity's text once your code determines that the incoming activity came from an Adaptive Card.

    You may be interested in reading my blog post for more information: https://blog.botframework.com/2019/07/02/using-adaptive-cards-with-the-microsoft-bot-framework/