3
votes

I am developing a chat bot using c# bot framework v4 sdk with multiple dialogs of waterfall type where one dialog class will display set of choices buttona through Prompt options.

Now, I want to know whether these choices in prompt options or the prompt options all together be displayed in a card either hero or rich cards using c# in bot framework v4 I a waterfall dialog. Such that if I select a choice button inside the displayed card the respective option should be triggered in the next step.

Usually, in normal way we take the response in next step and then proceed as needed but what I would like to k ow if is there a way we can display these choice buttons inside a card such that when clicked I can perform the respective action in next step?

Or this cannot be done and the expectation is wrong?

If there is a way, can you please provide a detailed step by step guide on how to achieve it as I am new to coding and in bot?

May be my question is not in detail so for explaining my query let me explain with example of a waterfalldialog 1:

What i already know:

STEP 1: Custom Choice options are displayed using Prompt options

STEP 2: Based on clicked choice in STEP 1 execute the related process by either navigating to another dialog or execute the functionality in this STEP #2 itself based on need

What I WANT TO ACHIEVE or KNOW HOW TO ACHIEVE

STEP 1: Display the previously displayed custom choice options as individual buttons side by side instead display this in form of cards like HERO CARD or RICH Card or any other card.

STEP 2: Accept the clicked choice as normally we do as explained in above step #2.

Please note these custom options are sometimes Dynamic so i cant hard code it to display it by designing the card with fixed options. I am able to get choices dynamically in normal prompt options but i am not sure how to do put them in CARDS like HERO CARDS and Etc and yet function as Normal choice options.

If there is a way can you please provide a detailed step by step guide as i am new to code and bot. or This is a wrong expectation it cannot be done?

Let me know if my query is still vague or not understandable.

Thanks & Regards ChaitanyaNG

1
I think I understand what you're wanting to know. Does this diagram look like what you want?Matt Stannett
Hi Matt, Not exactly the same. Like i know how to navigate to next step in waterfall if any choice option button is clicked and the respective option related process executed, what actually i am trying to ask or achieve is there a way to display these Choice buttons displayed through prompt options be displayed in a Rich cards or Hero cards or any other card and still function as normal choice options button click i.e. navigate to next step to continue respective process. Is this possible? if yes then how to achieve it please provide the step by step detailed guide as i am new to BOT and Code.Chaitanya N G
Alrighty then, I believe Hero and Rich cards are being replaced in favour of using Adaptive Cards. This question seems similar to what you want and shows off using adaptive cards with dynamic values. It also looks like a new AdaptiveCard prompt is in the works. Hope this helps.Matt Stannett
Adaptive Cards are currently only supported in Microsoft channels so hero cards are still useful for third-party channelsKyle Delaney
Hi Kyle, If my understanding is correct from above explanation. Is it safe to say that Adaptive Cards are not supported in WebChannel for now? Or My understanding is wrong?Chaitanya N G

1 Answers

2
votes

This can absolutely be done. I'm fairly certain I understand what you're looking for. If not, let me know and I'll edit this answer.

Create the Hero Cards

The important part is making sure that:

  1. The card has a button
  2. The button has a CardAction with an ImBack action type and the appropriate value
var heroCard1 = new HeroCard
{
    Title = "Option1",
    Subtitle = "subtitle",
    Text = "Some text",
    Images = new List<CardImage> { new CardImage("https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg") },
    Buttons = new List<CardAction> { new CardAction(ActionTypes.ImBack, "Option1", value: "Option1") },
};
var heroCard2 = new HeroCard
{
    Title = "Option2",
    Subtitle = "subtitle",
    Text = "Some text",
    Images = new List<CardImage> { new CardImage("https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg") },
    Buttons = new List<CardAction> { new CardAction(ActionTypes.ImBack, "Option2", value: "Option2") },
};
var heroCard3 = new HeroCard
{
    Title = "Option3",
    Subtitle = "subtitle",
    Text = "Some text",
    Images = new List<CardImage> { new CardImage("https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg") },
    Buttons = new List<CardAction> { new CardAction(ActionTypes.ImBack, "Option3", value: "Option3") },
};

Add the Hero Cards to a Message

var reply = stepContext.Context.Activity.CreateReply();
reply.AttachmentLayout = AttachmentLayoutTypes.Carousel;
reply.Attachments.Add(heroCard1.ToAttachment());
reply.Attachments.Add(heroCard2.ToAttachment());
reply.Attachments.Add(heroCard3.ToAttachment());

Send the Message, Followed By a Blank Text Prompt

Cards of any kind, by default, do not wait for user input. The blank text prompt is used force a wait and to capture the user's input, sending it to the next step.

await stepContext.Context.SendActivityAsync(reply);
return await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions() { Prompt = MessageFactory.Text("") });

Result

enter image description here

enter image description here

Notes

I recommend using Hero Cards for this because:

  • You can dynamically program the Hero Card however you want
  • If you use an Adaptive Card, capturing input is a bit trickier
  • If the input is just buttons, an Adaptive Card is overkill
  • As @KyleDelaney mentioned, Adaptive Cards aren't supported on all channels

You can have any number of buttons per card and it will still work. The Result is linked to the CardAction.value


Per @MattStannett

If you want to pass through a complex object rather than a simple string, this can be achieved by using the PostBack action and JsonConvert.SerializeObject to turn the object into a string. Using PostBack means that the message won't be displayed in the chat, the result can be retrieved from the Result object then read out using JsonConvert.DeserializeObject<>