Top

Adaptive Cards in Outlook – ultimate guide


It has been a while since I first thought about writing this post. Recently I had more questions around this topic and somehow realized, that indeed this is something about Adaptive Cards that I haven’t yet written about. So let me fix it with this ultimate guide.

See it in action!

Actionable Messages using Adaptive Cards

First you need to understand, that although this is still Adaptive Cards that are sent to Outlook they are called Actionable Messages sometimes too. They are fairly similar, but have some differences:

 Adaptive CardsActionable Messages
Version1.31.0 (source)
Actions
  • Http,
  • Submit,
  • ShowCard,
  • ToggleVisibility
  • Http (for get and post),
  • OpenUrl.
  • InvokeAddInCommand to open an Outlook add-in task pane.
  • DisplayMessageForm to open the read form of a message
  • DisplayAppointmentForm to open the read form of a calendar item
  • ToggleVisibility
Target for submitNot supported, must be handled by hostSupported. You can define target URL, headers and body.
ActionSetYesYes
RefreshingYes, but via host requestYes, as a response from target URL
AuthenticationSecurity handled by the host, that sends card and receives response.Service that sends cards must be registered and approved by Microsoft. Responses must be validated by client to confirm submitter's validity.
Other differencesAll goodies coming from versions 1.0+
  • Input.Time not working,
  • hideOriginalBody parameter to hide contents of the mail others than card,
  • originator to pass GUID of the authenticated provider.
  • correlationId to set own unique ID to track card
Source: https://docs.microsoft.com/en-us/outlook/actionable-messages/adaptive-card#outlook-specific-adaptive-card-properties-and-features

Note! As you can see from the comparison above, Actionable Messages are some kind of a hybrid between Adaptive Cards and old, legacy Message Cards. Still, you can send Actionable Message following Message Card JSON schema, but that’s not the goal for this post.

Requirements

The technology wouldn’t be itself if there weren’t any limitations to when and how it can be used. Basically there are certain versions of Outlook and Office 365 that supports Actionable Messages using either Message Cards or Adaptive Cards schema. Find out more here: https://docs.microsoft.com/en-us/outlook/actionable-messages/#outlook-version-requirements-for-actionable-messages.

Important! Actionable Messages as a technology, works only inside Office 365 Outlook clients.

Send Actionable Message

Step 1, create Adaptive Card

To send Adaptive Card as an Actionable Message first go to https://adaptivecards.io/designer/ and switch “host app” to “Outlook Actionable Messages”:

This will automatically set version to 1.0 and change schema validation to allow you to insert all those exceptions I mentioned above. Now design your card.

Important! You need to define Id properties to each input fields in your card. They will be used to grab inserted values and send them to the target URL:

You can alternatively design card using Actionable Messages Designer: https://amdesigner.azurewebsites.net/ – using that tool you can not only preview the card to see how it looks, but you can as well send it to your inbox. And there is a set of ready-to-use templates. Awesome!

Step 2, define actions

Remember, there are couple more actions available for Actionable Messages. Lets focus on Http action. Take this one for an example:

{
            "type": "Action.Http",
            "title": "Approve",
            "url": "https://[URL-OF-TARGET-APP]",
            "id": "ac_approve",
            "style": "positive",
            "method": "POST",
            "body": "{\"comments\":\"{{ac_comments.value}}\",\"outcome\":\"approve\"}",
            "headers": [
                {
                    "name": "Authorization",
                    "value": ""
                },
                {
                    "name": "Content-type",
                    "value": "application/json"
                }
            ]
        }

You need to define the following attributes:

  • url – where contents from the form will be sent. In my case this will be another Power Automate flow triggered by Web Request action.
  • method – POST or GET? In case of form, naturally POST.
  • body – this has to be a serialized JSON. Note, you can refer to fields in your card by using {{field_id.value}} placeholder.
  • headers – define content type AND put empty “Authorization” header, since this will assure your request won’t interfere with target system authorization mechanism (source).

Step 3, build flow to handle response

Now you need to build flow triggered by “When a HTTP request is received” trigger. Define value of the request Body JSON Schema to the one, that you will be sending from Adaptive Card. In my case its simple:

{
    "type": "object",
    "properties": {
        "comments": {
            "type": "string"
        },
        "outcome": {
            "type": "string"
        }
    }
}

Now you can define any logic inside the flow, what is important though is to add action “Response” that will send confirmation to the Actionable Message.

Replace existing Adaptive Card with confirmation Adaptive Card

If you’d like to simply replace existing in user’s inbox Adaptive Card with a confirmation one, design it and then configure “Response” action as following:

  1. Add header: content-type – application/json,
  2. Add header: CARD-UPDATE-IN-BODY – true
    This header will tell Actionable Message, to rep[lace existing card with the one sent in Response body.
  3. In Body copy-paste your confirmation Adaptive Card JSON.

Source: https://docs.microsoft.com/en-us/outlook/actionable-messages/adaptive-card#refresh-cards

Send notification back to user

If you’d like to send notification back to user, but without actually closing the card, use Status Code 4xx (as per your scenario) and:

  1. Add header: content-type – application/json,
  2. Add header: CARD-ACTION-STATUS – information to be displayed to user.

Source: https://docs.microsoft.com/en-us/outlook/actionable-messages/adaptive-card#reporting-actionhttp-execution-success-or-failure

Step 4, publish flow handling response

And grab its URL, then paste in the “url” attribute of your post actions in the Adaptive Card.

Step 5, compose and send Actionable Message

Now put action Compose inside the flow that will be used to send Actionable Message. Inside the compose action, put Adaptive Card’s JSON between the <script> tags (source):

<script type="application/adaptivecard+json">
{ YOUR ADAPTIVE CARD'S JSON }
</script>

Finally add “Send an email (V2)” action, switch it into code mode and put outcomes of the “Compose” action:

Send message to yourself and test how it works! Voilla, easy scenario done.

Actionable Messages Debugger

To check and validate Actionable Message what you could find useful is the add-in to Microsoft Outlook called “Actionable Messages Debugger”. It will help you to identify issues with your message. To get it, click the “Get Add-ins” button, then search for debugger and finally hit “Add”:

Now once you open it for a message containing Actionable Message it will show you all the issues with it. For Like in the below example, where I sent Actionable Message without originator ID, so not from a registered provider:

Send Actionable Message to others

There are basically four scenarios how you can send the e-mail with Actionable Message (source):

  1. Send it from your inbox to the same inbox – no provider registration needed, generally described above.
  2. Defined test users within the same tenant – self-service provider registration and approval.
  3. Organization Exchange admins – approval sent to your tenant’s Exchange admins. Allows you to send Actionable Messages to any user within your tenant.
  4. Global – allow Actionable Message to be sent to any user in Office 365. Requires Microsoft approval.

To be able to send Actionable Message to other users inside Office 365 tenants, first thing you have to do is to open “Actionable Email Developer Dashboard” (https://outlook.office.com/connectors/oam/publish) and then register new provider.

Note! Registration of provider for the “Global” scope requires Microsoft approval and may take couple of days.

Once your provider is approved (it will be done automatically for test users and admins), copy “Provider Id” value:

And add it as an additional attribute to your Adaptive Card JSON code:

{
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.0",
  "hideOriginalBody": true,
  "originator": "f6f1d226-abcd-asdaa-asdasd-123123123123",
  "body": [

Now depending on a chosen scope, you will be able to distribute your messages to a wider audience.

Message response verification

To verify that the sender of the Actionable Message response is the one who we expect, see the techniques in the second part of this post: https://poszytek.eu/en/microsoft-en/office-365-en/powerautomate-en/securing-responses-from-actionable-messages/.

And that’s all! If you have any questions, feel free to leave them in the comments below. Thank you 🙂


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.

15 Comments
  • Nandha kumar

    Thanks for the great explanation.
    I have a created a flow to trigger mail. I can see adaptive card is getting rendered properly in Outlook office 365(App) and in browser(Outlook).
    But not in Windows mail client(Office 365 Configured).
    Is it something like windows mail client does not support adaptive card or am i missing something?
    Can you help on this?

    September 30, 2020 at 2:30 pm Reply
  • Anatolii

    Awesome tutorial!
    One thing I struggle to understand – are guest account emails within Organization scope or Global scope?

    December 3, 2020 at 5:04 pm Reply
    • Tomasz Poszytek

      Well, you’re sending mails to their “home” inboxes, aren’t you? So guests do have access to your data via local-guest accounts, however they don’t use the local inboxes. So in such case you need to use the Global scope, since these users are actually not form your tenant.

      December 8, 2020 at 4:24 pm Reply
  • oliver

    hi Tomasz, what could possibly trigger this error The remote endpoint returned an error (HTTP 401)?

    December 9, 2020 at 10:29 am Reply
    • Tomasz Poszytek

      Well, definitely some kind of missing permissions. What’s your case?

      December 9, 2020 at 11:54 pm Reply
  • Steve

    Awesome blog here!
    I am getting confused on versioning and how it applies to Actionable Messages / Adaptive Cards. I have a card that I send out through Outlook that works just great. I’m trying to add an iconURL to an Action button which was introduced in v1.1. If I change the version in the card to 1.1 it still doesn’t show up. It seems like Cards sent via Outlook can only use elements that existed in v1.0 of Adaptive Cards. Is that a correct assumption?

    December 9, 2020 at 3:32 pm Reply
    • Tomasz Poszytek

      Exactly. See here: https://docs.microsoft.com/en-us/adaptive-cards/resources/partners what are the Adaptive Cards versions you can use with each partner.

      December 9, 2020 at 11:55 pm Reply
      • Steve

        Thanks, any idea if they will update that in the near future to allow a more recent version for Outlook Actionable Messages?

        December 10, 2020 at 4:11 pm Reply
        • Purvi Parmar

          Hi Tomasz Poszytek,

          Awesome blog. Thank you.
          Even I get The remote endpoint returned an error (HTTP 401). I am using logic app http POST request.

          March 18, 2021 at 10:46 pm Reply
          • Tomasz Poszytek

            Have you registered the provider and used it’s id in card? Also, does the provider has the right scope? Please use Actionable Messages Debugger addin in Outlook to check potential issues.

            March 25, 2021 at 10:03 pm
  • Priya

    Hi Tomasz, Great blog.. I have created an adaptive card that is sent to multiple users. Is there any way to get user info like user email ID on click of submit action, to check which user actioned on response!!

    February 21, 2021 at 10:22 am Reply
  • Brandon Langford

    Tomasz,

    Thank you for the great video. I would like to use adaptive cards in an e-mail with approve or reject feature similar to your example, but with my application, there is a lot of logic that has to be processed which may require further approval based on an approver’s signature authority etc.. Is there a way for outlook to notify your application of the response and allow me to process the response and then send a response back to outlook with a new confirmation adaptive card?

    March 29, 2021 at 9:25 pm Reply
    • Tomasz Poszytek

      Thank you. Sure it is. If you use Power Automate to handle the response, you can then program whatever logic you need together with sending new Actionable Messages.

      April 3, 2021 at 7:14 am Reply

Post a Comment

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