Getting Started With Adaptive Card Design Using Microsoft Bot Framework

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.

Microsoft Bot Framework

Prerequisite

I have explained about Bot framework installation, deployment, and implementation in the below articles -

  1. Getting Started with Chatbot Using Azure Bot Service
  2. Getting Started with Bots Using Visual Studio 2017
  3. Deploying A Bot to Azure Using Visual Studio 2017
  4. How to Create ChatBot In Xamarin
  5. Getting Started with Dialog Using Microsoft Bot Framework
  6. Getting Started with Prompt Dialog Using Microsoft Bot Framework
  7. Getting Started With Conversational Forms And FormFlow Using Microsoft Bot Framework
  8. Getting Started With Customizing A FormFlow Using Microsoft Bot Framework
  9. Sending Bot Reply Message With Attachment Using Bot Framework
  10. Getting Started With Hero Card Design Using Microsoft Bot Framework
  11. 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.

Microsoft Bot Framework

The Bot application template gets created with all the components and all required NuGet references installed in the solutions.

Microsoft Bot Framework

Install AdaptiveCard Nuget package

The Microsoft.AdaptiveCards library implements classes for building and serializing adaptive card objects and Visual Studio IntelliSense will help us for implement Adaptive card in the bot application.

Right click on Solution, select Manage NuGet Package for Solution > Search “ Microsoft AdaptiveCards” > select Project and install the package.

Microsoft Bot Framework

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.

  1. using System;  
  2. using System.Threading.Tasks;  
  3. using Microsoft.Bot.Builder.Dialogs;  
  4. using Microsoft.Bot.Connector;  
  5. using System.IO;  
  6. using System.Web;  
  7. using System.Collections.Generic;  
  8.   
  9. namespace BotAdaptiveCard.Dialogs  
  10. {  
  11.     [Serializable]  
  12.     public class AdaptiveCardDialog: IDialog<object>  
  13.     {   

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.

  1. public async Task StartAsync(IDialogContext context)  
  2.         {  
  3.             context.Wait(this.MessageReceivedAsync);  
  4.         } 

Step 3

Create a MessageReceivedAsync method and write the following code for the welcome message and to show the list of demo options dialog.

  1. [Serializable]  
  2.  public class AdaptiveCardDialog : IDialog<object>  
  3.  {  
  4.      public Task StartAsync(IDialogContext context)  
  5.      {  
  6.          context.Wait(this.MessageReceivedAsync);  
  7.          return Task.CompletedTask;  
  8.      }  
  9.      private readonly IDictionary<string, string> options = new Dictionary<string, string>  
  10.   
  11.  { "1""1. Show Demo Adaptive Card " },  
  12.  { "2""2. Show Demo for Adaptive Card Design with Column" },  
  13.  {"3" , "3. Input Adaptive card Design" }  
  14.   
  15.      };  
  16.      public async virtual Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)  
  17.      {  
  18.          var message = await result;  
  19.          var welcomeMessage = context.MakeMessage();  
  20.          welcomeMessage.Text = "Welcome to bot Adaptive Card Demo";  
  21.   
  22.          await context.PostAsync(welcomeMessage);  
  23.   
  24.          this.DisplayOptionsAsync(context);  
  25.      }  
  26.   
  27.      public void DisplayOptionsAsync(IDialogContext context)  
  28.      {  
  29.          PromptDialog.Choice<string>(  
  30.              context,  
  31.              this.SelectedOptionAsync,  
  32.              this.options.Keys,  
  33.              "What Demo / Sample option would you like to see?",  
  34.              "Please select Valid option 1 to 6",  
  35.              6,  
  36.              PromptStyle.PerLine,  
  37.              this.options.Values);  
  38.      }  
  39.      public async Task SelectedOptionAsync(IDialogContext context, IAwaitable<string> argument)  
  40.      {  
  41.          var message = await argument;  
  42.   
  43.          var replyMessage = context.MakeMessage();  
  44.   
  45.          Attachment attachment = null;  
  46.   
  47.          switch (message)  
  48.          {  
  49.              case "1":  
  50.                  attachment = CreateAdapativecard();  
  51.                  replyMessage.Attachments = new List<Attachment> { attachment };  
  52.                  break;  
  53.              case "2":  
  54.                  attachment = CreateAdapativecardWithColumn();  
  55.                  replyMessage.Attachments = new List<Attachment> { attachment };  
  56.                  break;  
  57.              case "3":  
  58.                  replyMessage.Attachments = new List<Attachment> { CreateAdapativecardWithColumn(), CreateAdaptiveCardwithEntry() };  
  59.                  break;  
  60.   
  61.          }  
  62.           
  63.   
  64.          await context.PostAsync(replyMessage);  
  65.   
  66.          this.DisplayOptionsAsync(context);  
  67.      } 

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.

Microsoft Bot Framework

Step 4 Design Adaptive Card

The Adaptive Cards are created using JSON but with the 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.

Microsoft Bot Framework

The following code shows the design of the welcome message with image, textblock, and speech.

  1. public Attachment CreateAdapativecard()  
  2.       {  
  3.   
  4.           AdaptiveCard card = new AdaptiveCard();  
  5.   
  6.           // Specify speech for the card.  
  7.           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";  
  8.           // Body content  
  9.           card.Body.Add(new Image()  
  10.           {  
  11.               Url = "https://i1.social.s-msft.com/profile/u/avatar.jpg?displayname=j%20suthahar&size=extralarge&version=88034ca2-9db8-46cd-b767-95d17658931a",  
  12.               Size = ImageSize.Small,  
  13.               Style = ImageStyle.Person,  
  14.               AltText = "Suthahar Profile"  
  15.   
  16.           });  
  17.   
  18.           // Add text to the card.  
  19.           card.Body.Add(new TextBlock()  
  20.           {  
  21.               Text = "Technical Lead and C# Corner MVP",  
  22.               Size = TextSize.Large,  
  23.               Weight = TextWeight.Bolder  
  24.           });  
  25.   
  26.           // Add text to the card.  
  27.           card.Body.Add(new TextBlock()  
  28.           {  
  29.               Text = "jssutahhar@gmail.com"  
  30.           });  
  31.   
  32.           // Add text to the card.  
  33.           card.Body.Add(new TextBlock()  
  34.           {  
  35.               Text = "97XXXXXX12"  
  36.           });  
  37.   
  38.           // Create the attachment with adapative card.  
  39.           Attachment attachment = new Attachment()  
  40.           {  
  41.               ContentType = AdaptiveCard.ContentType,  
  42.               Content = card  
  43.           };  
  44.           return attachment;  
  45.       }  

The above code will generate following adaptive card and reply to the user

Microsoft Bot Framework

Step 5 Design Adaptive Card with Column:

The Adaptive Cards contain many elements that allow designing UI content in a common and consistent way.

  1. Container - A Container is a CardElement which contains a list of CardElements that are logically grouped.
  2. ColumnSet and Column - The columnSet element adds the ability to have a set of Column objects and align the column object.
  3. FactSet - The FactSet element is displayed row and column like a tabular form.
  4. TextBlock - The TextBlock element allows for the inclusion of text, we can modify font sizes, weight, and color.
  5. 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.

Microsoft Bot Framework

The following code shows adding multiple columns and design of the UI Adaptive Card.

  1. public Attachment CreateAdapativecardWithColumn()  
  2.         {  
  3.             AdaptiveCard card = new AdaptiveCard()  
  4.             {  
  5.                 Body = new List<CardElement>()  
  6.     {  
  7.         // Container  
  8.         new Container()  
  9.         {  
  10.             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>",  
  11.             Items = new List<CardElement>()  
  12.             {  
  13.                 // first column  
  14.                 new ColumnSet()  
  15.                 {  
  16.                     Columns = new List<Column>()  
  17.                     {  
  18.                         new Column()  
  19.                         {  
  20.                             Size = ColumnSize.Auto,  
  21.                             Items = new List<CardElement>()  
  22.                             {  
  23.                                 new Image()  
  24.                                 {  
  25.                                     Url = "https://i1.social.s-msft.com/profile/u/avatar.jpg?displayname=j%20suthahar&size=extralarge&version=88034ca2-9db8-46cd-b767-95d17658931a",  
  26.                                     Size = ImageSize.Small,  
  27.                                     Style = ImageStyle.Person  
  28.                                 }  
  29.                             }  
  30.                         },  
  31.                         new Column()  
  32.                         {  
  33.                             Size = "300",  
  34.   
  35.                             Items = new List<CardElement>()  
  36.                             {  
  37.                                 new TextBlock()  
  38.                                 {  
  39.                                     Text =  "Suthahar Jegatheesan MCA",  
  40.                                     Weight = TextWeight.Bolder,  
  41.                                     IsSubtle = true  
  42.                                 },  
  43.                                  new TextBlock()  
  44.                                 {  
  45.                                     Text =  "jssuthahar@gmail.com",  
  46.                                     Weight = TextWeight.Lighter,  
  47.                                     IsSubtle = true  
  48.                                 },  
  49.                                   new TextBlock()  
  50.                                 {  
  51.                                     Text =  "97420XXXX2",  
  52.                                     Weight = TextWeight.Lighter,  
  53.                                     IsSubtle = true  
  54.                                 },  
  55.                                    new TextBlock()  
  56.                                 {  
  57.                                     Text =  "http://www.devenvexe.com",  
  58.                                     Weight = TextWeight.Lighter,  
  59.                                     IsSubtle = true  
  60.                                 }  
  61.   
  62.                             }  
  63.                         }  
  64.                     }  
  65.   
  66.                 },  
  67.                 // second column  
  68.                 new ColumnSet()  
  69.                 {  
  70.                      Columns = new List<Column>()  
  71.                     {  
  72.                           new Column()  
  73.                         {  
  74.                             Size = ColumnSize.Auto,  
  75.                             Separation =SeparationStyle.Strong,  
  76.                             Items = new List<CardElement>()  
  77.                             {  
  78.                                 new TextBlock()  
  79.                                 {  
  80.                                     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",  
  81.                                     Wrap = true  
  82.                                 }  
  83.                             }  
  84.                         }  
  85.                     }  
  86.                 }  
  87.             }  
  88.         }  
  89.      },  
  90.   
  91.             };  
  92.             Attachment attachment = new Attachment()  
  93.             {  
  94.                 ContentType = AdaptiveCard.ContentType,  
  95.                 Content = card  
  96.             };  
  97.             return attachment;  
  98.   
  99.         }  

The above code will generate the following card design and reply message.

Microsoft Bot Framework

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 action button.

  1. Text – Collect the text content from the user
  2. Date - Collect a Date from the user
  3. Time - Collect a Time from the user
  4. Number - Collect a Number from the user
  5. ChoiceSet - provide the user a set of choices and have them pick
  6. ToggleChoice - provide the user a single choice between two items and have them pick
  1. public Attachment CreateAdaptiveCardwithEntry()  
  2.         {  
  3.             var card = new AdaptiveCard()  
  4.             {  
  5.                 Body = new List<CardElement>()  
  6.     {  
  7.             // Hotels Search form  
  8.             
  9.             new TextBlock() { Text = "Please Share your detail for contact:" },  
  10.             new TextInput()  
  11.             {  
  12.                 Id = "Your Name",  
  13.                 Speak = "<s>Please Enter Your Name</s>",  
  14.                 Placeholder = "Please Enter Your Name",  
  15.                 Style = TextInputStyle.Text  
  16.             },  
  17.             new TextBlock() { Text = "When your Free" },  
  18.             new DateInput()  
  19.             {  
  20.                 Id = "Free",  
  21.                 Placeholder ="Your free Date"  
  22.             },  
  23.             new TextBlock() { Text = "Your Experence" },  
  24.             new NumberInput()  
  25.             {  
  26.                 Id = "No of Year experence",  
  27.                 Min = 1,  
  28.                 Max = 20,  
  29.             },  
  30.             new TextBlock() { Text = "Email" },  
  31.             new TextInput()  
  32.             {  
  33.                 Id = "Email",  
  34.                 Speak = "<s>Please Enter Your email</s>",  
  35.                 Placeholder = "Please Enter Your email",  
  36.                 Style = TextInputStyle.Text  
  37.             },  
  38.              new TextBlock() { Text = "Phone" },  
  39.             new TextInput()  
  40.             {  
  41.                 Id = "Phone",  
  42.                 Speak = "<s>Please Enter Your phone</s>",  
  43.                 Placeholder = "Please Enter Your Phone",  
  44.                 Style = TextInputStyle.Text  
  45.             },  
  46.     },  
  47.                 Actions = new List<ActionBase>()  
  48.     {  
  49.         new SubmitAction()  
  50.         {  
  51.             Title = "Contact",  
  52.             Speak = "<s>Contact</s>",  
  53.               
  54.         }  
  55.     }  
  56.             };  
  57.             Attachment attachment = new Attachment()  
  58.             {  
  59.                 ContentType = AdaptiveCard.ContentType,  
  60.                 Content = card  
  61.             };  
  62.             return attachment;  
  63.         }  

The above code will return the following adaptive card design.

Microsoft Bot Framework

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 in the browser.

Microsoft Bot Framework
Test Application on Bot Emulator

You can follow the below steps to test your bot application.

  1. Open Bot Emulator.
  2. Copy the above localhost URL and paste it in emulator e.g. - http://localHost:3979
  3. You can append the /api/messages in the above URL; e.g. - http://localHost:3979/api/messages.
  4. You won't need to specify Microsoft App ID and Microsoft App Password for localhost testing. So, click on "Connect".

Microsoft Bot Framework

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.