March 2021 update: I’ve finally got around to documenting the changes related to the change in format of the adaptive card.
There isn’t a trigger for Praise in the Teams connector in Power Automate (UserVoice here), but tracking praise seems like quite a handy thing, if not for an HR department or team leader to do, but for yourself personally.
Imagine going into your next performance appraisal with a PowerBI report that not only shows how much praise you give to and get from your colleagues, but also demonstrates your Power Platform skills!
Imagine no longer, because I’m going to show you how to do this in Power Automate.
Firstly the trigger. This is quite simple, we trigger on every new message in a channel.
Next we need to filter out what isn’t praise and terminate the Flow. Bear in mind that under the API call limit licensing model, your Office 365 seeded plan will allow you 2000 actions per day, so it’s important to stop the flow at the earliest opportunity.
I start by creating a Scope. I called it “establish whether this message is praise” and it contains four conditions:
A standard message has empty arrays for attachments and mentions. Praise has both (one attachment and one or more mentions), so unless the message has both attachments and mentions, it’s definitely not praise, so end here.
Now we need to establish whether the attachment is an Adaptive Card, and if not, end the flow. We get this information from:
The value should be “application/vnd.microsoft.card.adaptive”
Next we need to do something with the first attachment’s content. If you look at the raw JSON output from the trigger, the attachments content is a serialised JSON string:
If we select that property with
then the output is a string. It’s still serialised and we need to deserialise it with the json() function. The final expression in a Compose should be
Now, the next set of conditions are a little trickier. The adaptive card in Praise (as of Nov 2020) now has 1 column, and it contains four items, and within one of those items there’s a text property that contains the string “sent praise to”.
There are arrays within arrays within arrays in the Adaptive Card JSON so we need to play with expressions and data operations a bit here.
Firstly though, while Praise comes on an Adaptive Card, it’s not the only thing that might be shown on one. The subsequent operations use expressions that rely on certain characteristics being present in the adaptive card, and if they’re not, the flow will fail.
The Praise Adaptive Card has a body, which is an array that contains one item (a Container in Adaptive Card parlance), which has two properties, type and items. Type is “container” and items is an array with four objects inside.
These 4 objects are the details of the praise: Who sent it, who received it, the image that relates to the type of praise it is, and the text description, as written by the person giving the praise.
The contents of these objects is how we identify whether this adaptive card is actually praise.
To be able to get to that point, we need to check the length of the body array is 1 and the length of the “items” array within it is 5.
The screen shot below shows three data operations; a Compose and two Filter arrays.
The expression in first body is
Here is the screen shot. The “From” input of the first Filter array action (Filter items for TextBlock) is the expression outputs(‘first_body’)?[‘items’] and the input of the second one (Filter items for text containing praise) is just the output of the action above it.
The result of this is we will have an empty array if the string “sent praise to” does not exist in the text property of any of the items in the second column of the adaptive card.
The last action in this scope is to see if the array contains an object. If it does, then great, it was Praise, and if not, then it turns out it was just a Teams message with a mention in it and an adaptive card with one body and two columns.
Now we’ve established it’s Praise we can do something with the data.
In the Apply to each is the ‘Message mentions’ dynamic content from the trigger. You can do several mentions in one Praise so we want to create a list item for each of them.
Within the loop I do a lookup on the user. The mentions in the Teams message only has the Azure AD ID of the user, which is like a GUID. Thankfully the Office 365 Users connector takes that as an input (despite it asking for a UPN!).
The title is the personalised message text, which is:
..and the Praise Type is
You could also capture the image URL I guess, but I haven’t done that.
Lastly, I do a few follow up actions.
I produced a report of the praise by connecting Power BI to this SharePoint list. So outside of the Apply to each loop, I want to refresh my Power BI dataset after new praise is added.
I’m also going to follow up the praise by replying to the Praise message in Teams with a count of the praisers praise this year. This shows me the process is still working (note the total lack of any error control in this) and reminds people of the existence of the Power BI report:
That’s it folks. This is one of those simple but also quite tricky flows. It’s simple because it’s just catching a small number of bits of data from a Teams message, but tricky because the structure of the adaptive card is slightly complex and for the flow to run each time without errors, it needs to cleanly terminate at a number of places before any data runs through a formula that can’t take that data as an input.
As always, I hope someone finds this useful, and comments (or indeed some praise!) are welcome. If you feel my work has saved you heaps of time and effort, I will gratefully accept a small donation via PayPal: