Apologies for the novice question. I have been experimenting with posting alerts from a Python script (using the pymsteams library) to one of our internal Teams channels via an old-school Office 365 Connectors webhook. Today, alongside a posted alert, I got the notice that those connectors are being deprecated:
Per the advice in that article, I am trying to transition to a Power Automate based flow. I was able to set up the linked template with our team and channel IDs, and I got a URL which I presume is the new webhook URL. When I tried to post to that webhook, I got an error; within the web interface I can see that the flow failed on the "Send each adaptive card" step:
The execution of template action 'Send_each_adaptive_card' failed: the result of the evaluation of 'foreach' expression '@triggerOutputs()?['body']?['attachments']' is of type 'Null'. The result must be a valid array.
It seems like the content that I am trying to send is not being seen as an attachment? I don't have a ton of insight into how the request is actually formed, since I am using the library to make the request. The code within Python that I'm using to send the message is as follows:
import pymsteams
import os
def post_teams(message):
myTeamsMessage = pymsteams.connectorcard(os.environ.get("TEAMS_WEBHOOK_URL"))
myTeamsMessage.text(message)
myTeamsMessage.send()
(The message is a string with markdown content; I swapped the URL from the Power Automate flow in to my webhook environment variable there.)
Do I need to format my request to the webhook URL differently (perhaps using the requests library or similar), or is the issue on the Power Automate side - should I be telling it to get the content in some other way? From their repo, I see that pymsteams has not been updated in quite some time, so possibly it does not post requests in the format that Power Automate expects.
Thank you in advance for any insight you can provide!
Alright, I figured it out myself.
...
What, you want to know the solution? (Who were you, DenverCoder9? What did you see?)
I pushed a POST request to the webhook URL with the Python requests library, using the adaptive card template listed here. Sample code is as follows:
import requests
import json
import os
def post_teams(message):
payload = {
"type":"message",
"attachments":[
{
"contentType":"application/vnd.microsoft.card.adaptive",
"contentUrl":None,
"content":{
"$schema":"http://adaptivecards.io/schemas/adaptive-card.json",
"type":"AdaptiveCard",
"version":"1.2",
"body":[
{
"type": "TextBlock",
"text": f"{message}"
}
]
}
}
]
}
response = requests.post(
os.environ.get("TEAMS_WEBHOOK_URL"),
data=json.dumps(payload).encode("utf-8"),
headers={"Content-Type": "application/json"}
)
return response
post_teams('Testing new webook!')
I had to make some small tweaks to this for it to be pythonic ("None" instead of "null" in the dictionary that becomes the JSON payload), but this works nicely. Not sure how different this is from the content that pymsteams sends, but apparently it's different enough to work 🙂 .
Editing to add... One unfortunate thing I am discovering is that cards generated this way support a lesser subset of markdown than the old version. It looks like quotes and code blocks (two features I was using previously) are out. The stuff that _is_ still supported is listed here:
https://learn.microsoft.com/en-us/adaptive-cards/authoring-cards/text-features
However, there appear to be plenty of other ways to format content, and the ability to directly post small images via a data URI will be a big boon.