Introducing Multi-card Interfaces with Adaptive Cards 9445

Introducing Multi-card Interfaces with Adaptive Cards

Published

You can now return a new Adaptive Card definition from an Action.WebRequest!

As excited as we were to introduce Adaptive Card functionality in 2022, we believe this new enhancement will make them even more useful for you. In this post I'll review how a new capability recently added to the Adaptive Card Host SPA allows you to build even more complex, interactive, and (now) multi-card user experiences with Adaptive Cards. Instead of returning a toast message from an Action.Webrequest action, you can now return an entirely new Adaptive Card definition!

If you’ve not seen them, make sure to check out the previous posts on Adaptive Cards:
Adaptive Cards can define “actions” which are typically rendered as buttons within the card. The Adaptive Card Host SPA supports a variety of actions, including the ability to navigate the browser, show a toast message, or show a modal dialog. It also supports an action type of Action.Webrequest which provides the ability to send a web request to a server. This allows the card author to capture input from the user and send that input to a server (where additional interesting business logic can take place).

For example, the following Adaptive Card definition could be used to add a simple constituent record in Blackbaud Raiser’s Edge NXT®:

{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.4",
"body": [
{
"type": "TextBlock",
"text": "Use this card to add a new individual constituent."
},
{
"type": "Input.Text",
"id": "first",
"label": "First name",
"maxLength": 50
},
{
"type": "Input.Text",
"id": "last",
"label": "Last name",
"maxLength": 50,
"isRequired": true,
"errorMessage": "Last name is required."
}
],
"actions": [
{
"type": "Action.Webrequest",
"title": "Save",
"url": "https://someWebRequestURL...",
}
]
}


The card defines two input fields (first and last name) and a save button. When the save button is clicked, the first/last name are packaged into a request and sent to the specified URL.

Using techniques demonstrated in the previous posts, you can register a SKY Add-in for the Home Page Tile Dashboard in Raiser’s Edge NXT and use the Adaptive Card Host SPA to render this card in a tile:

b7cffc0ad38ab0d294a8a8e355232405-huge-ad

Previously, the response from the request sent by the save action could only show a toast message like “a new constituent record was added!”. Now, with the new capability of the Adaptive Card Host SPA the response can define a completely new Adaptive Card that will replace the initial data entry card and provide richer feedback to the user (and this new card can even contain its own actions that send requests and return different cards).

To implement this, you'll use Power Automate to implement a flow that will be triggered when the save button is clicked (note: using Power Automate isn’t a requirement, just a convenient way to implement some server-side logic). This flow will accept some input values (first/last name) that will be provided by the Adaptive Card, perform the logic for adding a constituent, and return a new card definition containing a confirmation message that the constituent was added along with a link to open the newly created constituent page.

You'll follow the same process as this post and create a new flow using the Trigger a flow from a SKY Add-in Adaptive Card action template. The flow will be triggered by an add-in on the home page, which provides no additional context, so you''ll remove the context element from the schema and update the placeholder fields in the schema to use the “first” and “last” field identifiers from my initial card:

{
"type": "object",
"properties": {
"uit": {
"type": "string"
},
"data": {
"type": "object",
"properties": {
"first": {
"type": "string"
},
"last": {
"type": "string"
}
}
}
}
}


After validating the user identity token, you'll use the Create an individual constituent action to create a new constituent using the values supplied in the flow trigger:

c7f3e34965f2cc58246f575edafa2426-huge-ad


Next, you'll build a new adaptive Card with details about the newly added constituent that will replace the initial card. To do this, you'll use the adaptive Card designer with a few placeholder values that I’ll update later in Microsoft Power Automate:

65e3dd24f29d47c26899a9307a374224-huge-ad


The card payload shown above is:

{
"type": "AdaptiveCard",
"version": "1.4",
"body": [
{
"type": "TextBlock",
"text": "Success!",
"size": "Large",
"weight": "Bolder",
"color": "Good"
},
{
"type": "TextBlock",
"text": "Constituent **xxxxx** was successfully added!"
},
{
"type": "TextBlock",
"text": "[View the new constituent record](https://host.nxt.blackbaud.com/constituent/records/xxxxx?&svcid=renxt&envid=xxxxx)"
}
]
}

Back in Power Automate, you'll paste the card payload from the designer into a Compose action, and replace the xxxxx placeholders with the appropriate values (You'll have the first/last name from the flow trigger, and the system record ID of the newly added constituent will come from the output of the Create new individual constituent action):

c75ccfd629a495062ea1ccb953231d7e-huge-ad


Now, it’s just a matter of returning the output from the compose action as the response:

1fe18ba4434ad919ee335703e42f2baa-huge-ad


Here is an overview of the flow:

c082505eba6c7139dbc2493067ad8b8d-huge-ad


After saving this flow, Power Automate will generate the URL that can be used to trigger the flow and you'll use that to update the url property of the Webrequest action in my original card.

{
"type": "Action.Webrequest",
"title": "Save",
"url": https://prod-116.westus.logic.azure.com:443/workflows/3aed...
}


When you click the save button, the second flow will be triggered. It will add the constituent and return a new Adaptive Card which will replace the original card:

d6004a32231d009e05debf060b7cdb11-huge-ad


To summarize - in this post we showed how a new Adaptive Card can be returned from an Action.Webrequest action. The new card will completely replace the original card, and allow users to build even more complex, interactive, and (now) multi-card users experiences.

For more information on Adaptive Card web request actions, see the documentation. We're excited to see how you decide to use this new functionality. Please share your thoughts on potential use cases in a comment below - or share completed projects in a discussion thread.

And a big thank you to Ben Lambert for his contribution to bring this functionality to Blackbaud customers.
News SKY Developer Announcements 04/11/2024 1:00pm EDT

Leave a Comment

3 Comments

The new Multi-Card interface works great! I just implemented it for my address change card and it now shows a new card which shows Success! Your update has been submitted instead of a toast message and it closes the card so they can't click Submit again!

Very easy to implement. My only hiccup was that I needed to put in Content-Type - application/json in the Response headers that wasn't there before.

Thanks to Ben Lambert and others!

@Ben Lambert @Heather McLean

@Carol Grant - your intial community post / request inspired this new feature! I hope you like it, too.

Great to hear Heather, thank you! Like Alex said, can't wait to try it out!

NOW WE ARE TALKING! can't wait to start implementing this

Share: