Creating a basic adaptive card

Written By Ben Lehmann

Last updated 5 months ago

Overview

This page presents a walkthrough guide to creating a basic adaptive card for use within a OneBot workflow, and to creating a simple OneBot workflow to display data using the created card. The intent is to illustrate how Workflows and Adaptive Cards can be used together to display information to the user with OneBot.

The Outcome

The workflow developed through this walkthough asks a user to input their first name, their last name, and their email address. It then presents their information back to them using an adaptive card which is also created as part of this guide.

The finished card will look similar to the example below if you view it in Microsoft Teams.

Analysing the outcome

The personal details card created in this guide has a number of elements, each of which need to be defined as part of the card payload.

The elements needed for the card:

  • A Title

  • A name

  • A label for the name

  • An email address

  • A label for the email address

These elements need to be defined in the card payload definition so the defined card can display the data correctly. Three of these elements are static: the title, and the labels for the name and for the email - static just means they don’t change and so can be defined in the card payload directly. The actual name and email address, however, need to use bindings so that a OneBot action can ‘inject’ the correct data as needed by a workflow that uses the card.

Building a Personal Details card

This guide uses the adaptive card designer to support the building of the card. Newer users may find it helpful to refer to the Adaptive Cards Introduction alongside this walkthrough.

Setting up the designer workspace

  1. In the designer, click New Card > Blank Card. This should present a clean environment, with the only the most basic outline of a card in the card payload editor.

  2. Cards are platform-agnostic. However, we know we want to use the card inside of Teams, so click on Select host app and choose Microsoft Teams.

  3. This guide is written using the 1.5 version of the adaptive card schema, so ensure that the Target version in the top right is set to use the 1.5 version.

A blank card in the designer

Defining the payload

The card payload is the the actual JSON that is used to define the card itself. This section of the guide focuses on introducing the basics of how to create a card that will be able to display data from a OneBot workflow.

Adaptive Card structure

It is helpful to understand the basic format of adaptive cards in general. The following points are adapted from the Getting Started page of the Microsoft Adaptive Card website.

The basic structure of an adaptive card is as follows:

  • AdaptiveCard - The root object describes the adaptive card itself, including its element makeup, its actions, and the schema version required to render it.

  • body - The body of the card is made up of building-blocks known as elements. Elements can be composed in nearly infinite arrangements to create many types of cards.

  • actions - Many cards have a set of actions a user may take on it. This property describes those actions which typically get rendered in an "action bar" at the bottom of a card.

Setting the title element

  1. Drag a TextBlock onto the card from the Card Elements column. Notice the JSON in the card payload editor updates and the TextBlock element is added into the definition body.

Example
{ "type": "AdaptiveCard", "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "version": "1.5", "body": [ { "type": "TextBlock", "text": "New TextBlock", "wrap": true } ] }
  1. Select the TextBlock element either in the preview or the card structure. Then in the element properties pane, edit the Text field to match the card title: Personal Details (See Fig. 5.2).

  2. Alternatively, the value of the text property can also be edited directly in the card payload editor (see Fig. 5.3).

  3. Notice that the card preview and the card structure also update to reflect the new value.

Setting the title TextBlock text property

  1. The TextBlock will form the card’s title, and should be styled appropriately. In the element properties pane, set the element’s Base style to Heading. To add the style property directly into the JSON, add a "style": "heading" name-value pair into the body. (For a full list of TextBlock properties, see the Schema Explorer.)

  2. It can help to also set the size and weight of the title if host application is not displaying the title as you expect it to. Set the value of the size property to "large" and the value of the weight property to "bolder" . (Note that the element properties pane currently has a bug that sometimes uses an uppercase letter with when setting properties. If this happens, edit the JSON directly to use lowercase for the size and weight properties.) The JSON should look similar to this:

Example
{ "type": "AdaptiveCard", "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "version": "1.5", "body": [ { "type": "TextBlock", "text": "Personal Details", "wrap": true, "style": "heading", "size": "large", "weight": "bolder" } ] }

Adding a FactSet and setting static values

The name displayed on the card is not presented on its own: it is presented with a label saying ‘name’. These elements logically belong together. An equivalent relationship exists between the email address, and the email address label. When multiple pairs of data are related in the same way as each other, it is helpful to use a FactSet to organise, present and access them.

In this example, the labels for Name and Email on the Personal Details card are static - they won’t change, regardless of changes happening to the actual name or email values displayed next to them.

  1. Drag in a FactSet from the elements column and place it below the title.

  2. In the element properties pane, edit the name of the first fact: change it from reading Fact 1 to read Name.

  3. Edit the name of the second fact: change it from Fact 2 to read Email.

FactSet added to the card

Setting bindings for the name and email address

The actual Name and Email address that will be displayed on the card are delivered when the workflow is run, so the workflow needs to have a way to ‘get hold of’ the properties of the card elements that should be displaying them. This is done using a binding.

  1. In the element properties pane, change the value of the first fact from Value 1 to ${theName}.

  2. Next to the second fact, change the value from Value 2 to ${theEmail}.

  3. The FactSet should now look similar to the picture to the right. The card payload should look similar to the example below.

The completed FactSet

Example
{ "type": "AdaptiveCard", "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "version": "1.5", "body": [ { "type": "TextBlock", "text": "Personal Details", "wrap": true, "style": "heading", "size": "large", "weight": "bolder" }, { "type": "FactSet", "facts": [ { "title": "Name", "value": "${theName}" }, { "title": "Email", "value": "${theEmail}" } ] } ] }

Testing using sample data

The card can be tested using sample data to verify it is set up correctly.

  1. In the sample data editor, add the following JSON string:

{
    "theName" : "Joe Smith",
    "theEmail" : "j.smith@mail.com"
}
  1. Notice the card details displayed in the card preview now show the values defined by the sample data editor.

  2. Also notice that the sample data targets the bound properties of the card with name-value pairs. Within these pairs, the name of the pair is set to match the value of the bound target property, just without the surrounding ${ }.

Adding the card payload to OneBot

The card definition needs to be added into OneBot as part of a new card for workflows to be able to access it. See the article Use Adaptive Cards for guidance on how to add your newly written card definition as part of a new Card Configuration.

Building a workflow that sends data to the card

To actually display the card, it needs to be used as part of a workflow. That workflow will need to access the card and send data to it using the cards bound property values.

  1. Create a new workflow, set up with a name and an intent.

  2. Add three Ask actions to the workflow, asking for the user’s first name, their last name, and their email address.

  3. Add a Teams > Show Card action as the last step before the finish.

  4. In the action configuration view, give the action a name and a description.

  5. Click on Card Template and select the newly created card. Doing this reveals the two binding fields defined in the card payload.

  6. In the binding field titled theName, type ‘/’ to open the tag control. Select Ask for first name from the list of ask actions

  7. From the drop-down that is revealed, choose response message.

  8. This will only add the user’s first name, so add a space and then repeat the above steps for the user’s last name.

  9. Similarly, in the binding field titled theEmail, use the tag control to add the Ask for email action response message as the binding expression used to send the card the user’s email address.

  10. Click back into the main view, and then click Save to save the workflow.

Adding ask actions to request user data

Adding binding expressions to the card

The finished workflow

Triggering the workflow in teams will take the user through the data input questions, and then display the card with their data as part of the chat stream.

Conclusion

This walkthrough demonstrated how to create an adaptive card for use with OneBot, and how to configure its payload to be able to receive and display data from a OneBot workflow.

The areas covered in the guide included:

  • How to set up the working area inside the Microsoft Adaptive Card designer

  • How to understand the structure of an adaptive card

  • How to define the card payload by configuring its title element, the fact set it uses to display data sent to the card, and how to set up the data bindings on these elements

  • How to test the card’s data bindings using some sample data

  • How to add the card and its payload into OneBot so the card can be used in workflows

  • How to build a workflow to send data to a cards by using an action’s data binding fields