Introduction
The Bot Framework supports different types of rich cards and provides a richer interaction experience to the user. In this article, I will show how to integrate adaptive card UI design in a Bot application. The
Adaptive Card contains a combination of text, speech, images, buttons, and input controls. Adaptive Cards are created using the JSON format specified in the Adaptive Cards schema and Microsoft provided Microsoft.AdaptiveCards NuGet package for .NET Developer to building cards and handles the serialization.
Prerequisite
I have explained about Bot framework installation, deployment, and implementation in the below articles -
- Getting Started with Chatbot Using Azure Bot Service
- Getting Started with Bots Using Visual Studio 2017
- Deploying A Bot to Azure Using Visual Studio 2017
- How to Create ChatBot In Xamarin
- Getting Started with Dialog Using Microsoft Bot Framework
- Getting Started with Prompt Dialog Using Microsoft Bot Framework
- Getting Started With Conversational Forms And FormFlow Using Microsoft Bot Framework
- Getting Started With Customizing A FormFlow Using Microsoft Bot Framework
- Sending Bot Reply Message With Attachment Using Bot Framework
- Getting Started With Hero Card Design Using Microsoft Bot Framework
- Getting Started With Thumbnail Card Design Using Microsoft Bot Framework
Create New Bot Application
Let's create a new bot application using Visual Studio 2017. Open Visual Studio > Select File > Create New Project (Ctrl + Shift +N) > Select Bot application.
The Bot application template gets created with all the components and all required NuGet references installed in the solutions.
Install AdaptiveCard Nuget package
Microsoft.AdaptiveCards library implements classes for building and serializing adaptive card objects and Visual Studio IntelliSense will help us to implement Adaptive cards in the bot application.
Right-click on Solution, select Manage NuGet Package for Solution > Search “ Microsoft AdaptiveCards” > select Project and install the package.
Create New AdaptiveCardDialog Class
Step 1
You can create a new AdaptiveCardDialog class to show the Adaptive dialog. Rightclick on Project, select Add New Item, create a class that is marked with the [Serializable] attribute (so the dialog can be serialized to state), and implement the IDialog interface.
- using System;
- using System.Threading.Tasks;
- using Microsoft.Bot.Builder.Dialogs;
- using Microsoft.Bot.Connector;
- using System.IO;
- using System.Web;
- using System.Collections.Generic;
-
- namespace BotAdaptiveCard.Dialogs
- {
- [Serializable]
- public class AdaptiveCardDialog: IDialog<object>
- {
Step 2
IDialog interface has only StartAsync() method. StartAsync() is called when the dialog becomes active. The method passes the IDialogContext object, used to manage the conversation.
- public async Task StartAsync(IDialogContext context)
- {
- context.Wait(this.MessageReceivedAsync);
- }
Step 3
Create a MessageReceivedAsync method and write the following code for the welcome message and to show the list of the demo options dialog.
- [Serializable]
- public class AdaptiveCardDialog : IDialog<object>
- {
- public Task StartAsync(IDialogContext context)
- {
- context.Wait(this.MessageReceivedAsync);
- return Task.CompletedTask;
- }
- private readonly IDictionary<string, string> options = new Dictionary<string, string>
-
- { "1", "1. Show Demo Adaptive Card " },
- { "2", "2. Show Demo for Adaptive Card Design with Column" },
- {"3" , "3. Input Adaptive card Design" }
-
- };
- public async virtual Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
- {
- var message = await result;
- var welcomeMessage = context.MakeMessage();
- welcomeMessage.Text = "Welcome to bot Adaptive Card Demo";
-
- await context.PostAsync(welcomeMessage);
-
- this.DisplayOptionsAsync(context);
- }
-
- public void DisplayOptionsAsync(IDialogContext context)
- {
- PromptDialog.Choice<string>(
- context,
- this.SelectedOptionAsync,
- this.options.Keys,
- "What Demo / Sample option would you like to see?",
- "Please select Valid option 1 to 6",
- 6,
- PromptStyle.PerLine,
- this.options.Values);
- }
- public async Task SelectedOptionAsync(IDialogContext context, IAwaitable<string> argument)
- {
- var message = await argument;
-
- var replyMessage = context.MakeMessage();
-
- Attachment attachment = null;
-
- switch (message)
- {
- case "1":
- attachment = CreateAdapativecard();
- replyMessage.Attachments = new List<Attachment> { attachment };
- break;
- case "2":
- attachment = CreateAdapativecardWithColumn();
- replyMessage.Attachments = new List<Attachment> { attachment };
- break;
- case "3":
- replyMessage.Attachments = new List<Attachment> { CreateAdapativecardWithColumn(), CreateAdaptiveCardwithEntry() };
- break;
-
- }
-
-
- await context.PostAsync(replyMessage);
-
- this.DisplayOptionsAsync(context);
- }
After the user enters the first message, our bot will reply with a welcome message and list of demo options. Then, it waits for user input like below.
Step 4 Design Adaptive Card
The Adaptive Cards are created using JSON but with Microsoft.AdaptiveCards NuGet, we can create them by composing card objects. We can create AdaptiveCard objects and attach to the attachment and post message to a message.
The following code shows the design of the welcome message with image, textblock, and speech.
- public Attachment CreateAdapativecard()
- {
-
- AdaptiveCard card = new AdaptiveCard();
-
-
- card.Speak = "Suthahar J is a Technical Lead and C# Corner MVP. He has extensive 10+ years of experience working on different technologies, mostly in Microsoft space. His focus areas are Xamarin Cross Mobile Development ,UWP, SharePoint, Azure,Windows Mobile , Web , AI and Architecture. He writes about technology at his popular blog http://devenvexe.com";
-
- card.Body.Add(new Image()
- {
- Url = "https://i1.social.s-msft.com/profile/u/avatar.jpg?displayname=j%20suthahar&size=extralarge&version=88034ca2-9db8-46cd-b767-95d17658931a",
- Size = ImageSize.Small,
- Style = ImageStyle.Person,
- AltText = "Suthahar Profile"
-
- });
-
-
- card.Body.Add(new TextBlock()
- {
- Text = "Technical Lead and C# Corner MVP",
- Size = TextSize.Large,
- Weight = TextWeight.Bolder
- });
-
-
- card.Body.Add(new TextBlock()
- {
- Text = "[email protected]"
- });
-
-
- card.Body.Add(new TextBlock()
- {
- Text = "97XXXXXX12"
- });
-
-
- Attachment attachment = new Attachment()
- {
- ContentType = AdaptiveCard.ContentType,
- Content = card
- };
- return attachment;
- }
The above code will generate following adaptive card and reply to the user
Step 5 Design Adaptive Card with Column:
The Adaptive Cards contain many elements that allow designing UI content in a common and consistent way.
- Container - A Container is a CardElement which contains a list of CardElements that are logically grouped.
- ColumnSet and Column - The columnSet element adds the ability to have a set of Column objects and align the column object.
- FactSet - The FactSet element is displayed row and column like a tabular form.
- TextBlock - The TextBlock element allows for the inclusion of text, we can modify font sizes, weight, and color.
- ImageSet and Image - The ImageSet allows for the inclusion of collection images like a photo set, and the Image element allows for the inclusion of images.
The following code shows adding multiple columns and design of the UI Adaptive Card.
- public Attachment CreateAdapativecardWithColumn()
- {
- AdaptiveCard card = new AdaptiveCard()
- {
- Body = new List<CardElement>()
- {
-
- new Container()
- {
- Speak = "<s>Hello!</s><s>Suthahar J is a Technical Lead and C# Corner MVP. He has extensive 10+ years of experience working on different technologies, mostly in Microsoft space. His focus areas are Xamarin Cross Mobile Development ,UWP, SharePoint, Azure,Windows Mobile , Web , AI and Architecture. He writes about technology at his popular blog http://devenvexe.com</s>",
- Items = new List<CardElement>()
- {
-
- new ColumnSet()
- {
- Columns = new List<Column>()
- {
- new Column()
- {
- Size = ColumnSize.Auto,
- Items = new List<CardElement>()
- {
- new Image()
- {
- Url = "https://i1.social.s-msft.com/profile/u/avatar.jpg?displayname=j%20suthahar&size=extralarge&version=88034ca2-9db8-46cd-b767-95d17658931a",
- Size = ImageSize.Small,
- Style = ImageStyle.Person
- }
- }
- },
- new Column()
- {
- Size = "300",
-
- Items = new List<CardElement>()
- {
- new TextBlock()
- {
- Text = "Suthahar Jegatheesan MCA",
- Weight = TextWeight.Bolder,
- IsSubtle = true
- },
- new TextBlock()
- {
- Text = "[email protected]",
- Weight = TextWeight.Lighter,
- IsSubtle = true
- },
- new TextBlock()
- {
- Text = "97420XXXX2",
- Weight = TextWeight.Lighter,
- IsSubtle = true
- },
- new TextBlock()
- {
- Text = "https://www.devenvexe.com",
- Weight = TextWeight.Lighter,
- IsSubtle = true
- }
-
- }
- }
- }
-
- },
-
- new ColumnSet()
- {
- Columns = new List<Column>()
- {
- new Column()
- {
- Size = ColumnSize.Auto,
- Separation =SeparationStyle.Strong,
- Items = new List<CardElement>()
- {
- new TextBlock()
- {
- Text = "Suthahar J is a Technical Lead and C# Corner MVP. He has extensive 10+ years of experience working on different technologies, mostly in Microsoft space. His focus areas are Xamarin Cross Mobile Development ,UWP, SharePoint, Azure,Windows Mobile , Web , AI and Architecture. He writes about technology at his popular blog http://devenvexe.com",
- Wrap = true
- }
- }
- }
- }
- }
- }
- }
- },
-
- };
- Attachment attachment = new Attachment()
- {
- ContentType = AdaptiveCard.ContentType,
- Content = card
- };
- return attachment;
-
- }
The above code will generate the following card design and reply message.
Step 6 Adaptive Card Design with Input Control
The Adaptive Cards can include input controls for collecting the information from the user. It will support the following input controls - Text, Date, Time, Number, and for selecting options(choice set) and toggle.
The following sample code is included collecting basic information from the users with an action button.
- Text – Collect the text content from the user
- Date - Collect a Date from the user
- Time - Collect a Time from the user
- Number - Collect a Number from the user
- ChoiceSet - provide the user with a set of choices and have them pick
- ToggleChoice - provide the user with a single choice between two items and have them pick
- public Attachment CreateAdaptiveCardwithEntry()
- {
- var card = new AdaptiveCard()
- {
- Body = new List<CardElement>()
- {
-
-
- new TextBlock() { Text = "Please Share your detail for contact:" },
- new TextInput()
- {
- Id = "Your Name",
- Speak = "<s>Please Enter Your Name</s>",
- Placeholder = "Please Enter Your Name",
- Style = TextInputStyle.Text
- },
- new TextBlock() { Text = "When your Free" },
- new DateInput()
- {
- Id = "Free",
- Placeholder ="Your free Date"
- },
- new TextBlock() { Text = "Your Experence" },
- new NumberInput()
- {
- Id = "No of Year experence",
- Min = 1,
- Max = 20,
- },
- new TextBlock() { Text = "Email" },
- new TextInput()
- {
- Id = "Email",
- Speak = "<s>Please Enter Your email</s>",
- Placeholder = "Please Enter Your email",
- Style = TextInputStyle.Text
- },
- new TextBlock() { Text = "Phone" },
- new TextInput()
- {
- Id = "Phone",
- Speak = "<s>Please Enter Your phone</s>",
- Placeholder = "Please Enter Your Phone",
- Style = TextInputStyle.Text
- },
- },
- Actions = new List<ActionBase>()
- {
- new SubmitAction()
- {
- Title = "Contact",
- Speak = "<s>Contact</s>",
-
- }
- }
- };
- Attachment attachment = new Attachment()
- {
- ContentType = AdaptiveCard.ContentType,
- Content = card
- };
- return attachment;
- }
The above code will return the following adaptive card design.
Run Bot Application
The emulator is a desktop application that lets us test and debugs our bot on localhost. Now, you can click on "Run the application" in Visual Studio and execute it in the browser.
Test Application on Bot Emulator
You can follow the below steps to test your bot application.
- Open Bot Emulator.
- Copy the above localhost URL and paste it in emulator e.g. - http://localHost:3979
- You can append the /api/messages in the above URL; e.g. - http://localHost:3979/api/messages.
- You won't need to specify Microsoft App ID and Microsoft App Password for localhost testing. So, click on "Connect".
Summary
In this article, you learned how to create a Bot application using Visual Studio 2017 and create the adaptive design and input using Bot framework. If you have any questions/feedback/ issues, please write in the comment box.