Newsletter robot
Enjoyed the read?

Don't miss our next article

Digital Workplace, Intranets

How to build an Adaptive Card for a SharePoint intranet

Quick Links

Make your Assistant Build your free AI-powered Digital Workplace platform in minutes, with our free forever plan. Digital Assistant logo Yes please

Adaptive Cards are a standardized "recipe" for writing a Card in Microsoft Teams or other Microsoft products. However, oddly SharePoint does not directly let you embed Adaptive Cards from within their UI.

In this tutorial, I will show you how easily you can define an Adaptive Card that looks great, displays the data you connect it to, and how you can embed it into your SharePoint Intranet.

1. Make an Adaptive Card design

First of all we want to design a Card for a certain use case, in our example let's say we make a Card that shows you Sales leads from a CRM. In our example we will use Hubspot for this but (as you'll see below) most other services will work the same way.

You can design Cards either in the web-based Designer from Microsoft or we'll use a free tool called Digital Assistant that also handles data binding for you (more on that later).

In this tool's admin area you navigate to Cards → Add Card and select Add Adaptive Card.

New adaptive Cards can be created from the Cards page in the Admin Area, under the 'Add new' dropdown
Highlighted layout of the Adaptive Cards designer. The Card elements pane is on the left; the payload editor and sample data editor are split 50/50 at the bottom of the designer.

Then we enter the designer. It splits into three main areas that we will look at:

The yellow area is a list of card elements that you can drag and drop into the card framework where all you see currently is Empty Container.

In the turquoise area we have the Card Payload Editor which shows anything you add to your Adaptive Card. It is the"recipe" for your Card, formatted in JSON, which structurally describes your card's layout and content.

Lastly, in the purple area, we have the Sample Data Editor where you will see an example response from your connected app that you can use to test how the card will look with real data written directly into the Card. This is called "binding" and we'll get back to that in the next step.

Now for the actual Card. We're making a simple list that shows us the contacts from our Hubspot list. As the end result, we would like to have something that looks similar to this sketch mock-up:

Example mockup of an Adaptive Card design for Digital Assistant
Rough sketch of the finished Adaptive Card

To build this card we start designing the first row (or entry) of our list. We have a name, company name, as well as a direct email button. Clicking on the list entry should open our contact in a new tab.

So to start we need to drag into our Card a column, images, and text blocks that match the layout of our mockup.

Notice, how the Card Payload Editor changes as you drag each card element into your framework.

It's a little finicky, but once you added in your text columns, button (ActionSet), texts and icons your card preview should look something like this:

Preview of an example Adaptive Card built with the Adaptive Card designer, based on the mockup

Here's the code shown in the payload editor:

{
"type": "AdaptiveCard",
"body": [
{
"type": "Container",
"bleed": true,
"items": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "Lead name",
"size": "Medium",
"weight": "Bolder"
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "20px",
"items": [
{
"type": "Image",
"url": "<your-icon-url>",
"size": "Stretch"
}
],
"spacing": "None"
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "Organization name",
"fontType": "Default",
"size": "Small",
"weight": "Bolder"
}
],
"spacing": "Small",
"verticalContentAlignment": "Center"
}
],
"spacing": "None"
}
]
},
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "ActionSet",
"actions": [
{
"type": "Action.OpenUrl",
"title": "Message",
"style": "positive",
"iconUrl": "<your-icon-url>",
"url": ""
}
]
}
],
"verticalContentAlignment": "Center"
}
],
"selectAction": {
"type": "Action.OpenUrl",
"url": ""
},
"separator": true
}
],
"spacing": "None",
"backgroundImage": {},
"separator": true
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "17px",
"items": [
{
"type": "Image",
"url": "<your-icon-url>",
"size": "Stretch"
}
],
"spacing": "None"
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "Open Hubspot app"
}
],
"backgroundImage": {
"verticalAlignment": "Center"
},
"spacing": "Small"
}
],
"separator": true,
"selectAction": {
"type": "Action.OpenUrl",
"url": "https://app.hubspot.com/"
}
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.2"
}

2. Data binding

We now have a Card that shows a single lead, but we want the Designer to repeat this list item for each contact in our data. This is called "looping" or "iterating". And to start this process we first need to fill in some sample data into our design. (For now some sample data will suffice, but further down we'll set up a live feed as well.)

You will have to do your own research and start digging for an API endpoint documentation from the application you get your data from. In the case of Hubspot it would be the Lists endpoint. For our Card we want to get a sample readout of my own Hubspot account, so we will use a tool like Postman which can request this from the Hubspot API.

Once you have your sample data, paste it into the Sample Data Editor section.

Editor's tip:
If Postman isn't your thing, or you simply can't get easy access to the API, you could also use the sample response shown on the API docs website, although these are sometimes shortened for brevity.

Now we can bind to this data in our ColumnSet. We do this simply by adding the following code to line 10: "$data": "${$root.contacts}",

Example payload editor/sample data editor panes showing how data binding works

This tells the designer to show such a ColumnSet for each entry in the "contacts" array of our sample data JSON.

You know this worked successfully, when you click on Preview Mode and the entries suddenly multiply by however many items are in your API sample. If it didn't work, check out the docs for templating and see if you can debug your Card payload.

Finally, now we can bind the actual data from the sample response we copied to our design.

First we navigate to the the element where we want to show the name and we enter ${properties.firstname.value} ${properties.firstname.value}:

This tells the Card designer to look for the correct entry in the JSON by navigating through the "tree" and delving deeper into every branch denoted with a . in the binding command.

In our example the API's root is already set to the contacts array (defined in line 10), so to get to the first name of each contact the Card Designer needs to:

  • Go to the properties array
  • Within there, find the firstname object
  • Read out the value nested within

We follow the same logic for the last name, and the company name below that.

If everything worked, your Card should now show each contact separately.

Just for completeness' sake, you can find the finished Card payload code below:

{
"type": "AdaptiveCard",
"body": [
{
"type": "Container",
"bleed": true,
"items": [
{
"type": "ColumnSet",
"$data": "${$root.contacts}",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "${properties.firstname.value} ${properties.lastname.value}",
"size": "Medium",
"weight": "Bolder"
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "20px",
"items": [
{
"type": "Image",
"url": "<your-icon-url>",
"size": "Stretch"
}
],
"spacing": "None"
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "${properties.company.value}",
"fontType": "Default",
"size": "Small",
"weight": "Bolder"
}
],
"spacing": "Small",
"verticalContentAlignment": "Center"
}
],
"spacing": "None"
}
]
},
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "ActionSet",
"actions": [
{
"type": "Action.OpenUrl",
"title": "Message",
"style": "positive",
"iconUrl": "<your-icon-url>",
"url": "${profile-url}?interaction=email"
}
]
}
],
"verticalContentAlignment": "Center"
}
],
"selectAction": {
"type": "Action.OpenUrl",
"url": "${profile-url}?"
},
"separator": true
}
],
"spacing": "None",
"backgroundImage": {},
"separator": true
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "17px",
"items": [
{
"type": "Image",
"url": "https://logo.clearbit.com/hubspot.com",
"size": "Stretch"
}
],
"spacing": "None"
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "Open Hubspot app"
}
],
"backgroundImage": {
"verticalAlignment": "Center"
},
"spacing": "Small"
}
],
"separator": true,
"selectAction": {
"type": "Action.OpenUrl",
"url": "https://app.hubspot.com/"
}
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.2"
}

3. Connect to your data source

Cool, so we've got the Card working using our sample obtained from the API. How do we get a live feed set up?

This is where a free tool like Digital Assistant provides the infrastructure to continuously pull fresh data. To add the service from our example (Hubspot) just go over to the App Directory page and look for it.

Editor's tip:
If your project uses an app not listed in that Directory you can also use a free Postman template that lets you connect with any API.

Adding the Hubspot integration to Digital Assistant from the App Directory
Free integration with Hubspot allows to authenticate and pull live data

Click on the Add to Digital Assistant button to add an integration to this app to your Connectors page.

Success modal showing that the Hubspot integration was successfully added to Digital Assistant

Once that's added you will have to authenticate with Hubspot (so that the Card Designer can receive your data).

To do this, you need to actually open the Assistant app by clicking onOpen Assistant button and then find one of the Cards asking to authorize your Hubspot access.

Digital Assistant Board showing the new Hubspot Card. The Card states it needs access to be authorized before it can show data.

One that's authorized, go back to your Card in the Card Designer and click on the pencil next to the title. This opens the card settings where you click on the Connector tab.

Editor button in the Adaptive Card designer to open the Card configuration modal

Here just pick the Connector for Hubspot that we added from the App Directory. Click Save when you're done.

Selecting a new connector in the Adaptive Card configuration modal

Having selected this Connector, it will now replace the content in the Sample Data Editor section that we put in manually, with live data coming from your Connector.

To double check if all the data-binding is still valid, please toggle to the Preview Mode one more time and fix anything that may not be working as intended.

Seeing the finished Card toggling between Preview and Edit mode

And that's it. You're Card is ready to roll. 👍😎 You can view it in your Assistant by clicking on Open Assistant button, or access it through places like the MS Teams app for Digital Assistant. This is what the finished product should look like in the Designer:

Completed example Adaptive Card for Digital Assistant showing lead data from Hubspot
Preview from the Adaptive Cards Designer of our finished Adaptive Card

4. Embed the Card

The last step is to add our Card to an existing SharePoint site. We need to install a free companion Webpart in SharePoint for this.

Adding the Digital Assistant SharePoint webpart to a SharePoint modern team site

Once it is installed, you should be able to add it to your SharePoint site.

The Webpart requires two things to work, the URL of your Assistant (Tenant URL) and the Id of the Card you want to embed (Card Id).

Configuring the Digital Assistant SharePoint webpart

1) Tenant URL

To get this, head over to the Channels page in your Assistant admin area. Then toggle SharePoint on and copy the URL into the Tenant URL field in SharePoint.

Editor's tip:
Also add your SharePoint domain to the "Whitelist domains that may embed Digital Assistant" box.

2) Card Id

The Card Id is shown in the browser's address bar when you have the Card open in the Adaptive Card Designer. Just go back to the Cards menu, open your Card and look at the URL. It should look something like this: https://app.adenin.com/App/Designer/AdaptiveCard/1b6d003a-8b37-405f-a3c8-f1e0b6ad6d31 where the string 1b6d003a-8b37-405f-a3c8-f1e0b6ad6d31 is the Card Id.

Once you entered this into the Webpart properties and save them, your Card should be embedded.

Example of a Digital Assistant Card embedded into a SharePoint modern team site

That's it. Your Card is working, if you need make slight layout changes just go back to your Card Designer and make the changes you want, and they'll be live as soon as you hit Save.

Did you find this tutorial useful? Anything not clear? Let me know in the comments below.

Article by: Henry Amm

I’m the Senior Director for the Digital Assistant Platform. Prevously gained 6 years of experience as an Intranet consultant. Fluent in German.

Join the discussion

This field is required.
This field is required.
This field is required.

0 responses

Be the first to leave a comment!