Top
Adaptive Cards

Microsoft Message Cards – the ultimate guide


In the first part of the series I wrote a general overview of Message and Adaptive Cards, their brief history and purpose. This part is focused only on Message Cards – the technology from which it all begun and that is still available to use although recommendation is to move to Adaptive Cards.

Message Cards – introduction

Message Cards are created using a declarative JSON-format code. Then the definition is parsed by the SDK into a nice looking part of UI.

They can be used today still in Outlook (both Desktop and Browser based):

Message Card in Outlook
Message Card in Outlook

I doubt if it will be ever possible to use them in Outlook Mobile (Adaptive Cards are already there), plus in Microsoft Teams, sent by Flow or Bot, or via any application through a defined webhook:

Message Card in Microsoft Teams
Message Card in Microsoft Teams

JSON code that defines card is full of options. However it’s main structure consist of two areas: Card definition and Sections.

{
    "@type": "MessageCard",
    "@context": "https://schema.org/extensions",
    "summary": "",
    "themeColor": "",
    "title": "Card created: \"This is just a test\"",
    "sections": [
        {
                  …
        },
        "potentialAction": [
            {
                    …
            }
        ]
    ]
}
Areas in the Message Card
Areas in the Message Card

In Card’s information section you can define basics of your card. These are:

  1. title
  2. summary – property used by Outlook.
  3. themeColor – this is the colorful line on the left of your card. According to documentation, it is advised to use it to brand them e.g. to your organizational colors, but not to indicate status.
  4. hideOriginalBody – again, property used by Outlook.
  5. text – an additional block of text displayed using a regular font below title.

In Section, you can build blocks of data:

  1. facts –  a construct allowing to display data in organized way – a table.
  2. activity – constructed from image, title, subtitle and text.
  3. text – again, a block of text
  4. image 
  5. heroImage – different from regular image, as it displays full-width on a card.
  6. potentialAction – block dedicated for actions (described below). Can also be defined outside “Section” area.

Remember!

You can only use once each type of property in a single “Section” object, however you can have multiple objects (since Section is an array). Moreover – images cannot be defined via URI. It has to be a path to a physical image anonymously accessible (or where currently logged in user has access).

For Potential actions you can choose between the following types of actions:

  1. OpenUri
  2. HttpPost
  3. ActionCard
  4. InvokeAddInCommand
  5. ActionRequest (new version of old Transaction)

Again, there can be more than one action, since potentialAction is an array.

Anytime you would like to use “text” property remember, you can use markdown to format it too! (https://docs.microsoft.com/en-us/outlook/actionable-messages/message-card-reference#text-formatting)

There are two interesting types of actions: ActionCard, which allows to display a “sub card” with form fields and other actionable items. And ActionRequest – activity allowing payment functionalities right from the card, without a need for pushing user to leave our app.

For more information about the Message Cards structure, I recommend reading the documentation:

Important!

Note, that Message Cards are getting deprecated and replaced by their younger successor: Adaptive Cards. Microsoft recommends to migrate where possible from Message to Adaptive Cards format: https://docs.microsoft.com/en-us/outlook/actionable-messages/adaptive-card

Message Cards administration

Please note that administrator can disable rendering of Message Cards both in Outlook and Teams, by using Set-OrganizationConfig cmdlet: https://docs.microsoft.com/en-us/powershell/module/exchange/organization/set-organizationconfig

Working exampe (aka demo ;))

The solution I am about to show you is connecting SharePoint workflows (using 3rd party solution – Nintex) and Microsoft Teams, making this process running in a truly digital workplace experience mode. Let’s see how it works:

  1. In SharePoint user is creating an item, that requires approval
  2. Workflow assigns a task and in that moment it also sends, via a Teams webhook, prepared Message Card JSON.
  3. Approver therefore can complete a task any way he likes: through a native, SharePoint task, via an Actionable Message in Outlook or using Microsoft Teams.
  4. Let’s focus on Teams – approver decides, and clicks related outcome.
  5. Message Card is refreshed and instead of the previous form, now shows a confirmation information.

The workflow

SharePoint workflow is created with Nintex. It is quite simple: once an item is created it assignes a task to approver and in the same time it creates a Message Card in Teams for approval using that channel:

Nintex Workflow assigning task and sending Message Card
Nintex Workflow assigning task and sending Message Card

Posting a Message Card to Microsoft Teams

To be able to post a Message Card you must first create a Webhook for a channel. To do that first go to “Manage team” page of a team you want to post a message to:

Adding webhook to Teams, part 1
Adding webhook to Teams, part 1

Next go to “Apps” tab and click the “More apps” button:

Adding webhook to Teams, part 2
Adding webhook to Teams, part 2

Next type “Webhook” in the search menu and click the tile that appears:

Adding webhook to Teams, part 3
Adding webhook to Teams, part 3

Then click the button “Open” and after that select the channel, to which you want to post a Message Card and finally the button “Set up”:

Adding webhook to Teams, part 4
Adding webhook to Teams, part 4

Finally define webhook’s name (it will be displayed as the author of all messages), upload icon (avatar) and hit “Create”:

Adding webhook to Teams, part 5
Adding webhook to Teams, part 5

After it is created, copy the generated URL and “Done”:

Adding webhook to Teams, part 6
Adding webhook to Teams, part 6

Important!

The URL is the one that the “Web request” action in my workflow will use to post message to.

Next what has to be defined is the Message Card JSON. I have created a code using the Playground and then put dynamic values inside it, so that once workflow replaces them with actual data, the Card is really adjusted to the particular needs. Withing the “potentialActions” section I put buttons to Approve/ Reject request, which once clicked are executing HttpPOST action and is sending , along with the Outcome and Comments, SharePoint Task ID:

{
    "@@type": "ActionCard",
    "name": "Approve",
    "inputs": [
        {
            "@@type": "TextInput",
            "id": "ApprovalComment",
            "isMultiline": true,
            "title": "Comment (optional)"
        }
    ],
    "actions": [
        {
            "@@type": "HttpPOST",
            "name": "Submit",
            "target": "FLOW URL",
            "headers": [
                {
                    "name": "content-type",
                    "value": "application/json"
                },
                {
                    "name": "authorization",
                    "value": ""
                }
            ],
            "bodyContentType": "application/json",
            "body": "{\"approved\":true, \"comment\":\"{{ApprovalComment.value}}\", \"taskID\":10"
        }
    ]
}

In the end, posted Message Card looks like below:

Message Card posted by Nintex via webhook
Message Card posted by Nintex via webhook

Registering the outcome and refresing the Card

To handle actions from Message Card I decided to use Microsoft Flow that is triggered on incoming Web Request, using the following schema:

Microsoft Flow trigger for incoming web request
Microsoft Flow trigger for incoming web request
{
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        },
        "inputParameters": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "value": {
                        "type": "string"
                    }
                },
                "required": [
                    "id",
                    "value"
                ]
            }
        },
        "actionId": {
            "type": "string"
        },
        "potentialAction": {
            "type": "string"
        },
        "integrationId": {
            "type": "string"
        },
        "meta": {
            "type": "string"
        },
        "clientInfo": {
            "type": "object",
            "properties": {
                "locale": {
                    "type": "string"
                },
                "country": {
                    "type": "string"
                },
                "platform": {
                    "type": "string"
                },
                "clientVersion": {
                    "type": "string"
                }
            }
        }
    }
}

Next I am parsing property “Body” to get outcome, comment and taskID, using the following schema:

Parsing "Body" from Message Card
Parsing “Body” from Message Card

Next, based on the outcome, Flow is either updating Task Item to “Approved” or “Rejected”:

Microsoft Flow updating SharePoint task
Microsoft Flow updating SharePoint task

Now the “key” functionality: response being sent to the Message Card. As it can be read here: https://docs.microsoft.com/en-us/outlook/actionable-messages/message-card-reference#refresh-cards and here: https://docs.microsoft.com/en-us/outlook/actionable-messages/message-card-reference#reporting-an-actions-execution-success-or-failure to update a Card it has to receive a request with the following Header keys:

  1. CARD-UPDATE-IN-BODY – true|false, whether to replace card contents
  2. CARD-ACTION-STATUS – message shown as comment, below the card.

If key “CARD-UPDATE-IN-BODY” is set to “true” Card is expecting contents of a new card to be sent out. To build the Message Card to replace “Request” one, try to put as much details in the “body” parameter of the “Request” card so that later you can use them in the Flow to build the “Confirmation” one 🙂

Important!

If you see “@” in any attribute of the Message Card JSON body in your Flow, escape it with additional “@”, to make it double “@@”. Without that you will not be able to save/ execute the Flow.

Working solution

Below you can find animation showing how the whole solution works!

Message Card in Teams
Message Card in Teams

What I learnt?

  1. You can’t mention anyone using Message Card
  2. You can’t post Message Card in a private message
  3. You can’t get user context who clicks the button and pass it to Flow

Thank you for reaching that far! This post is a second one in series in which you can learn about:

  1. Introduction to Adaptive Cards
  2. Message Cards – case study and how-to
  3. Adaptive Cards – case study and how-to
  4. What’s ahead in 2.0 (hopefully with examples :))

Would you like to learn more about Adaptive Cards? Contact me or leave a comment.


Tomasz Poszytek

Hi, I am Tomasz. I am expert in the field of process automation and business solutions' building using Power Platform. I am Microsoft MVP and Nintex vTE.

36 Comments
  • Ashtosh

    I want to update a Sharepoint list item once submit button in adaptive card is clicked I have list item Id in adaptive card body.

    September 16, 2019 at 8:23 am Reply
    • Tomasz Poszytek

      Today that is not possible to be done using Teams and Microsoft Flow for posting a card. You have to create your own Bot or write your own app using Adaptive Cards SDK.

      September 16, 2019 at 8:25 am Reply
  • Martin Zutter

    Hi Tomasz
    Is it possible to save the message card Text to a file, excel, csv or SharePoint-List?
    This is an example:
    {“text”:{“DataInterface”:”Data-InterfacePRiOT-SCI-Space-DataHub”,”value”:25.7,”datasource”:”PoC-Data”,”operationscenter”:”69COSEWSD”,”airtemperature”:25.7,”airhumidity”:22}}

    This is kind of a “data import”. The goal is to visualize it in Power BI.
    Thanks a lot and sorry, english is not my “mother language”

    April 8, 2020 at 8:14 am Reply
    • Tomasz Poszytek

      Hi. Adaptive Cards are yet not supported in Power Bi. This is not even on a roadmap… Instead you can use HTML and display it using the HTML visualisation.

      April 8, 2020 at 8:32 pm Reply
  • Cristiano

    Hello, I have a problem, I’m using the MenssageCard, but the words that contain underscore (_) lose it when it arrives at Teams, example:

    “text”: router_BA_SDR

    teams displays:
    routerBASDR

    what could be happening?

    April 23, 2020 at 2:48 am Reply
    • Tomasz Poszytek

      I don’t really know what could the reason. If you put string inside quotes, like “key”: “value” then it should be sent together with underscores.

      April 27, 2020 at 10:25 am Reply
  • Steven

    Great article. I have managed to format some notifications in MS Teams using the MessageCard type now.
    One question, do you know if you can @mention someone as part of sending this over to teams. The icing on the cake would be someone being pinged they have a mention in a channel as a result of this.

    April 29, 2020 at 5:57 am Reply
  • Gurinder

    How to send message card in outgoing webhook,
    Do I need to attach it as an attachment in the json sent by teams which I deserialize via Newtonsoft and attach card inside attachment section as it is a collection of attachments.
    or only the message card json.
    I am using Azure functions at present able to send very simple message
    {
    “type”:”message “,
    “text”:”hello”
    }
    Looking to expand on it to send message card but don’t know how to structure it as mentioned above should the card be attached inside attachment section of original json post to azure function via team or message card json it self,
    Thanks you for help,
    Gurinder

    May 1, 2020 at 3:01 am Reply
    • Tomasz Poszytek

      I actually don’t understand what you’re trying to achieve. Basically if you try to send Message Card from Azure Function, via a webhook to Teams, you need to post the JSON as a Body of your POST request. The JSON must be formatted according to the examples: https://messagecardplayground.azurewebsites.net/ (try eg. Flow Approval example).

      May 2, 2020 at 10:03 pm Reply
      • Gurinder

        Thank you for reply I really appreciate,
        I was trying to send a card via Azure function but didn’t want to put raw json in it,but since have successfully created a card and post it to teams.
        Once again thanks reply.

        May 2, 2020 at 11:02 pm Reply
  • Steven

    Hey,
    In Flow, do you know how to parse out the title from the message card.
    I send over an email address as the MessageCard Summary, which in flow I turn into a variable and then use that as the mention – but I want to also refer to the title from the messagecard, I cannot see how to parse that out from the message that is received in teams

    Do you have a suggestion?

    May 26, 2020 at 5:23 am Reply
  • Bala Tadisetty

    Hi TOMASZ POSZYTEK,
    I have an internal API that I’m making available through my prod server. Now I want to call that API from a MessageCard HTTPPost action in Teams. When I click on the action button I do not see any errors, and Fiddler shows me a 200 respose and I can see the token in the authorization header and the below in the body: {“status”:”Completed”,”actionId”:”65d36e8b-e90a-4007-a556-bc4c74da8f1e”,”performedAt”:”2019-12-03T16:23:45.0463267Z”,”properties”:{“displayMessage”:””}} But nothing happens after that. Can you please share the card JSON which we can use.
    As per your above content i have tried keeping headers={
    “content-type”:”application/json;charset=UTF-8″,
    “CARD-UPDATE-IN-BODY”:true,
    “CARD-ACTION-STATUS”:”has been Approved”
    }

    July 28, 2020 at 2:40 am Reply
    • Tomasz Poszytek

      What would you like to achieve in details? Replace one card by another?

      July 30, 2020 at 8:23 pm Reply
      • Marudsa Cifuentes

        That’s right, my case is similar, and I intend to replace one card with another with the body that I send from my api through the HTTPPost action .. but I can’t find the way to do it, since what it does is add another card and respond to the first with what I place in the CARD-ACTION-STATUS. although it says updated, the card disappears.

        November 29, 2020 at 10:34 pm Reply
        • Tomasz Poszytek

          So the approach is that the service which receives the response from the card must respond and send message with CARD-UPDATE-IN-BODY header. The CARD-ACTION-STATUS will be displayed as a comment in Teams below the card (when using it for Teams).

          December 2, 2020 at 10:24 am Reply
  • Shubha

    Hi,
    Great Article.
    Is there a way to delete a card posted by bot erroneously. We do not see the delete option even for team owners.

    January 27, 2021 at 6:35 am Reply
    • Tomasz Poszytek

      One way is to replace it with another card. There should be however a regular option to delete a message in chat, like any other sent message.

      February 5, 2021 at 11:51 am Reply
  • Dinesh

    Could you please share complete json sample which you are using

    May 10, 2021 at 10:15 am Reply
    • Tomasz Poszytek

      I am sure you can easily build it using https://adaptivecards.io/designer. You can even get screenshot of my card and then in designer click “New card” and then “Create from Image” – this feature should turn my image into a working card 🙂

      May 12, 2021 at 8:21 am Reply
  • Robin

    Hi Tomasz. Is it possible to save the output of an Actionable Message and send to a Teams Channel message? I’ve pretty much done it but the formatting of the Teams message is not great. Is it just me but I see lots of tutorials on Adaptive cards and Actionable messages but not a huge amount on how to store the information meaningfully.

    Thanks.

    October 21, 2021 at 2:24 pm Reply
    • Tomasz Poszytek

      Well basically if data from Actionable Message is sent to a flow/ another endpoint that can receive it and handle, you’re ready to go. Save the outputs in SharePoint or Dataverse and then create another flow/ process that will submit new card with data to Teams.

      October 26, 2021 at 11:09 pm Reply
  • John Harper

    Hello Tomasz,
    I have enjoyed your posts on this subject. I was wondering if actionable messages are available for use in Outlook calendar meetings (body)? I have a process that creates a meeting request from our CMMS system and the ask was to populate a card with the info from the triggered event. I am thinking that the card json could be embeded into the microsoft graph create meeting request api call…….not sure if it would work however. any thoughts from you?

    February 17, 2022 at 7:49 pm Reply
    • Tomasz Poszytek

      I haven’t checked myself. You can try. However my first thoughts are it won’t work as one invitation may target multiple users, but maybe I am wrong? 🙂

      February 18, 2022 at 2:36 pm Reply
  • Usha

    Hello Tomasz, Amazing post this is by you and no where in the web i could find such explaining which actually gives clear understanding of how a Message Card is designed to send message to teams.
    With your blog, i am able to come to a certain extent of design, but still i have few gaps.
    I want to add color to the Title, and have the background color changed. Can you please guide me how to do it?

    July 6, 2022 at 9:53 am Reply
    • Tomasz Poszytek

      Thank you very much! 🙂 Speaking about the colors – you can try with background image, however there is no rule afaik to set it based on a condition.

      July 15, 2022 at 11:30 am Reply
  • Usha

    Also is there a way i can use ore defined templates and just pass the facts to send to teams?

    July 6, 2022 at 10:37 am Reply
    • Tomasz Poszytek

      Such feature is not available using oob functionalities, but possibly it will arrive one day. Currently, to fulfil such a requirement, you’d need to create your own bot.

      July 15, 2022 at 11:33 am Reply
  • Pavan Itla

    Hi Tomasz, I’m trying to change the title of the text using Message Card. But it’s not working. Could you help me with this ?

    Thanks in Advance

    November 21, 2022 at 2:13 pm Reply
    • Pavan Itla

      Some correction in the above Comment : “I Need to change the color of the text”

      November 21, 2022 at 2:14 pm Reply
      • Tomasz Poszytek

        You can’t control the colors. Those are controlled by hosts. You can change type, there are “positive”, “negative” – but it doesn’t mean the host has support for that and will respect the setting.

        December 14, 2022 at 10:23 am Reply
  • Murad

    Hi Tomosz, great stuff! Thank you for sharing!

    Do you have an experience in using actionable messages based on multiple sharepoint items in one single email. So idea is not to overload the users with multiple emails (e.g. items can go up to 10) It would be nice to have selection (e.g. yes/no), comment field for each item and submit button at the end.

    June 12, 2024 at 12:38 pm Reply
    • Tomasz Poszytek

      Sure, the point is you just need to wisely construct the payload sent on submit to e.g., cloud flow. So that you can handle individual answers per each item.

      September 20, 2024 at 9:03 pm Reply

Post a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.