Integrating Adaptive Cards with the .NET Bot Framework

Introduction

Adaptive Cards is an open platform card exchange format for developers. It provides developers a new way to compose UX (user experiences) through multiple devices. An adaptive card is a piece of UI (HTML, CSS, and JavaScript) defined by the developer and rendered by the native app (bot application) to display required content to the end user. The Bot Framework connector renders these cards through different channels, such as Skype, Facebook, Emulator, WebChat, Slack, Kik, Telegram, SMS, GroupMe, Email, Bing, and so forth. An Adaptive Card can contain text, speech, images, buttons, and input fields created using the JSON format. Following the NuGet library implements classes for building and serializing adaptive card objects in the .NET platform.

Library Documentation

Learn about the adaptive card codebase from this site.

How Adaptive Cards Work

Adaptive Cards created by the developer using a JSON object is rendered natively inside the application, so that it automatically adopts to the look and feel of the host application. Card authors own the content and the host application owns the look and feel.

Following are the steps to add Adaptive Cards in your application:

  1. Add the reference to a renderer library in your bot application.
  2. Create an instance of the renderer library with your application style.
  3. Render your card with the UI framework in the native application.

Using Adaptive Cards with the Bot Framework

To add Adaptive Cards in your bot developed using .NET platform, you have to run the ‘Install-Package Microsoft.AdaptiveCards’ command to install the required package. For NodeJS, run the ‘npm install microsoft-adaptivecards’ command.

In the following walkthrough, I will demonstrate how to add Adaptive Cards to your existing bot developed using .NET platform.

Step 1

Let’s create a standard Bot Framework message in JSON format that can be delivered to any channel. Refer to the following JSON code:

{
   "type": "message",
   "text": "My Sample Adaptive Text Message..."
}

Step 2

With Adaptive Cards, you can add images to your card, organize your content with containers and columns, add actions, and collect input from users.

Next, we will create more complex card and add some richness beyond just text. You can paste the following JSON code into the visualizer to preview how the card will look.

{
   "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
   "type": "AdaptiveCard",
   "body": [
      {
         "type": "Container",
         "speak": "<s>Card created by Tapas Pal</s>",
         "items": [
            {
               "type": "TextBlock",
               "text": "Sample Card Created to Test",
               "weight": "bolder",
               "size": "medium"
            },
            {
               "type": "ColumnSet",
               "columns": [
                  {
                     "type": "Column",
                     "size": "auto",
                     "items": [
                        {
                           "type": "Image",
                           "url": "https://media.licdn.com/mpr/mpr/
                              shrinknp_200_200/AAEAAQAAAAAAAAQuAAAA
                              JGQ4Njk2ODY2LWE4MzQtNDE5Ni04OTAxLWZmN
                              zhhZDFhNjZjYQ.jpg",
                           "size": "small",
                           "style": "person"
                        }
                     ]
                  },
                  {
                     "type": "Column",
                     "size": "stretch",
                     "items": [
                        {
                           "type": "TextBlock",
                           "text": "**Tapas Pal**",
                           "wrap": true
                        },
                        {
                           "type": "TextBlock",
                           "separation": "none",
                           "text": "Created {{DATE(2017-09-14T06:
                              08:39Z,Long)}} {{TIME(2017-02-14T06:
                              08:39Z)}}",
                           "isSubtle": true,
                           "wrap": true
                        }
                     ]
                  }
               ]
            }
         ]
      },
      {
         "type": "Container",
         "items": [
            {
               "type": "TextBlock",
               "text": "Test .",
               "speak": "",
               "wrap": true
            },
            {
               "type": "FactSet",
               "speak": "Sample Text ",
               "facts": [
                  {
                     "title": "Sample:",
                     "value": "Adaptive Card"
                  },
                  {
                     "title": "List:",
                     "value": "Sample List"
                  },
                  {
                     "title": "Assigned to:",
                     "value": "Someone"
                  },
                  {
                     "title": "Due date:",
                     "value": "Not set"
                  }
               ]
            }
         ]
      }
   ],
   "actions": [
      {
         "type": "Action.ShowCard",
         "title": "Set due date",
         "card": {
            "type": "AdaptiveCard",
            "body": [
               {
                  "type": "Input.Date",
                  "id": "dueDate",
                  "title": "Select due date"
               }
            ],
            "actions": [
               {
                  "type": "Action.Http",
                  "title": "OK",
                  "url": "http://xyz.com",
                  "headers": {
                     "content-type": "application/json"
                  },
                  "body": "{ 'comment' : '{{comment.value}}' }"
               }
            ]
         }
      },
      {
         "type": "Action.ShowCard",
         "title": "Comment",
         "card": {
            "type": "AdaptiveCard",
            "body": [
               {
                  "type": "Input.Text",
                  "id": "comment",
                  "isMultiline": true,
                  "placeholder": " Enter some  comment"
               }
            ],
            "actions": [
               {
                  "type": "Action.Http",
                  "method": "POST",
                  "title": "OK",
                  "url": "http://tapaspal.com",
                  "headers": {
                     "content-type": "application/json"
                  },
                  "body": "{ 'comment' : '{{comment.value}}' }"
               }
            ]
         }
      },
      {
         "type": "Action.OpenUrl",
         "title": "View",
         "url": "http://test.com"
      }
   ]
}

Step 3

Next, we will create a JavaScript message to that contains an Adaptive Card. Refer to the following code.

var AdaptiveCardMessage = new builder.Message(session)
   .addAttachment({
      "contentType": "application/vnd.microsoft.card.adaptive",
      "content": {
         "type": "AdaptiveCard",
         "body": [
            {
               "type": "TextBlock",
               "text": "Sample Adaptive Card!",
               "size": "large"
            },
            {
               "type": "TextBlock",
               "text": "*Adaptive Cards 1*",
               "separation": "none"
            },
            {
               "type": "TextBlock",
               "text": "Adaptive Cards 2*",
               "separation": "none"
            }
         ],
         "actions": [
            {
               "type": "Action.OpenUrl",
               "url": "http://adaptivecards.io",
               "title": "Learn More on Adaptive Card"
            }
         ]
      }
   });

Conclusion

I hope this article has given you a kick start on Adaptive Cards and how you can use these cards to improve your bot’s communication. Please have a look at the following reference links to explore more ways that Adaptive Cards can enhance your bot.

References

Following are a few Adaptive Cards references for the developer community.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read