Adaptive Cards Deep Dive

Understand the foundational ideas behind how OneBot uses Adaptive Cards

Written By Kevin Baker

Last updated 5 months ago

Overview

A number of the OneBot actions use Microsoft’s adaptive card solution to show information to the user, enable interaction, and to send information back into the OneBot workflow.

💡 The adaptive card website has a number of useful resources to support use of adaptive cards:

  • Sample cards demonstrate how cards can used

  • The Schema Explorer details properties and functions available to adaptive cards

  • The Designer provides an interactive environment supporting creation of cards

  • The Templating Language details how to set data bindings within card payloads

A number of the guides in this wiki assume familiarity with the basics of setup and use of adaptive cards to display information. For a more in-depth guide on how to get started with adaptive cards see the Creating a basic adaptive card walkthrough.

Features of Adaptive Cards

Adopting Adaptive Cards as a solution enables OneBot to provide rich information and formatting to your users while remaining lightweight, reusable, and platform agnostic. Some of the ways Adaptive Cards allows users to consume and interact with information might include:

  • Publish updates, activity information, and confirmations using branded assets

  • Display content agenda, travel itinerary, or calendar events

  • Enable users to place orders, or raise incidents using dynamic content and layouts

  • Display images and data with rich, interactive tables and galleries

  • Gather labeled user information and data using flexible formatting and dynamic forms.

How OneBot uses Adaptive Cards

Adaptive Cards used as part of a chat stream are the main way end users interacts with your OneBot app. They display output from the application and gather user interaction, information and data for use as part of your OneBot workflows.

When your user needs interact with richer or more varied information, you need more than a text bubble: this is where Adaptive Cards enable sharing information using more dynamic, more effective forms.

Data bindings in the cards allow workflows to connect into them. They provide the points where OneBot can ‘send’ data to and help to label the data that is sent back from the card.

Scope of interaction

Adaptive Cards are used throughout OneBot and across many of the systems it interacts with. Here are the key points that OneBot interacts with Adaptive Cards, and where they can be configured and managed.

  1. Design - Layout card elements and data bindings using OneBots’s Card Designer.

  2. Organise - Manage and administer the cards in your system using the Card Manager.

  3. Link - Connect processes to cards and work with returning data using Workflows.

  4. Render - Cards are displayed and made interactive once your app has been Deployed.

Understanding data binding

To use adaptive cards effectively, it is important to understand how OneBot can access bindings to present and read data. Declare bindings as part of a card definition to enable the exchange of data between a card and a workflow: OneBot can access these bindings to inject data into a card, presenting the injected data rather than the bindings themselves. Similarly, a card can return its data back to OneBot using a data binding, making the data accessible within a workflow.

Defining a binding

Adaptive cards use a binding syntax that starts with ${ and ends with } to ‘wrap’ the parts of bound properties. For example, a property value defined as theName would be bound in a card definition as ${theName}. Bindings can be assigned a value within a OneBot workflow.

Accessing a binding uses the same name but without the surrounding ${ }. Continuing the above example, a binding defined as ${theName} in a card would be accessed as theName from within a workflow action.

Further data binding:

  • Use Dot-notation to access sub-objects of an object hierarchy. E.g., ${myParent.myChild}

  • Graceful null handling ensures you won't get exceptions if you access a null property

  • Use Indexer syntax to retrieve properties by key or items in an array. E.g., ${myArray[0]}

Further information and more advanced binding features and examples can be found in the 'Binding to data' section of the Template Language page on Microsoft’s Adaptive Cards site.

Displaying data

Use bindings declared within a card payload to create access points into which OneBot can inject data for display. See the walkthrough Creating a basic adaptive card for a worked example of how to use bindings in an adaptive card to display workflow data.

Cards can containing bindings that are dynamically evaluated when the card is rendered. Fig. 1 shows rendered card: in this case, ‘Joe Smith’ and ‘j.smith@mail.com’ are inserted at the binding locations.Fig. 1 - a card as presented in Microsoft Teams

Previewing the same card in OneBot shows the bindings where the name and email will be displayed on the card. Fig. 2 shows an example of this, displaying the bindings where the name and email values will appear.Fig. 2 - a preview of the card in the definition page showing property bindings

Setting data using binding fields

Actions that need to inject data into an adaptive card display binding fields in their configuration view. These binding fields correspond to the bindings defined as part of the card elements in the card payload. OneBot actions use these binding fields to set the value of the corresponding, bound property when the card is displayed.

The action does not initially display the entry field: entry fields bound to a card property in the payload appear in the configuration view after selecting an appropriate card.

Note

Binding fields in the configuration view appear after selecting an appropriate card

Furthermore, it is necessary use bindings correctly within a card payload. To have a card element work with a binding to display workflow data, the correct property of the element needs to be set. The element should have the correct name-value property used with the binding: this will be whatever property actually gets displayed as part of the card presentation. The binding is used as the value for this property. This then enables the card payload to have corresponding entry fields displayed inside an action configuration view.

For example, a TextBlock being used to display a card title might need to be set dynamically, thus requiring the use of a binding. To do this, set up a binding as the value of the text property of the TextBlock.

Enter an appropriate value, expression, or OneBot action into this binding field to configure what data to send to the card.

Reading card data

Adaptive cards can submit data back to their host application. They do this as name-value pairs packaged using JSON. OneBot can read the data returned from the cards used in workflow actions and make it available to the rest of the workflow.

This is achieved by using a binding as the id of input elements. Setting the id to a binding makes the card’s data accessible (indirectly) to the workflow. Data is returned from the card when its Action.Submit or Action.Execute is triggered. The current value of the card’s input elements is read, packaged and returned as JSON name-value pairs. Using a binding as the id of an input element sets the name in the returned name-value pair equal to the binding. This can then be used in the workflow to access the value captured from the input element.

OneBot actions configured to use cards defined in this way expose the card’s id’s using these bindings. These appear as part of the action in the tag control.