Open black-snow opened 4 months ago
Quick headsup because I tried it this morning as well with dependency track.
Its not enough to wrap the existing message into the new payload structure that comes with the default template for sending messages to a teams channel (see)
They also only accept adaptive cards there, no more MessageCards or even the simpler text version of the old webhook. If you however put the example from the link above into a custom template in DTrack it works. So I guess we need a new adaptive card template.
Thanks for looking into this @otbe. Did you just reuse org.dependencytrack.notification.publisher.MsTeamsPublisher
for your custom template?
Thanks for looking into this @otbe. Did you just reuse
org.dependencytrack.notification.publisher.MsTeamsPublisher
for your custom template?
Yes exactly.
I'll be giving this a shot:
{
"type":"message",
"attachments":[
{
"contentType":"application/vnd.microsoft.card.adaptive",
"contentUrl":"{{ baseUrl }}/projects/{{ subject.project.uuid | escape(strategy='json') }}",
"content":{
"$schema":"http://adaptivecards.io/schemas/adaptive-card.json",
"type":"AdaptiveCard",
"version":"1.2",
"body":[
{
"type": "TextBlock",
{% if notification.group == "POLICY_VIOLATION" %}
"text": "{{ subject.policyViolation.policyCondition.subject | escape(strategy="json") }} {{ subject.component.toString | escape(strategy="json") }} - {{ notification.content | escape(strategy="json") }}"
{% elseif notification.group == "BOM_PROCESSING_FAILED" %}
"text": "BOM processing failed for {{ subject.project.toString | escape(strategy="json") }} - {{ notification.content | escape(strategy="json") }}"
{% else %}
"text": "{{ notification.content | escape(strategy="json") }}"
{% endif %}
}
]
}
}
]
}
Should be easy to add a new template then. Perhaps I'll do it today or tomorrow.
Hi, i'm suffering from the same problem. Unfortunately i'm not too deep into this subjects and i have to admit, that i have not understood everything from your post. I managed to create a workflow 'post to channel...'. When i post your templete to the workflow url, a message is displayed in the teams channel, but it's empty. No text at all. May i kindly ask, to have a look? Is there something missing in my payload?
4 def send_teams_message(flow_url, message):
5 headers = {
6 "Content-Type": "application/json"
7 }
8
9 proxyip = "blinded"
10 proxyport = "3128"
11 proxies= {"https": f"http://{proxyip}:{proxyport}"}
12
13 #payload = {
14 # "message": message
15 #}
16 payload = {
17 "title": "Ueberschrift",
18 "type":"AdaptiveCard",
19 "attachments":[
20 {
21 "contentType":"application/vnd.microsoft.card.adaptive",
22 "contentUrl":None,
23 "content":{
24 "$schema":"http://adaptivecards.io/schemas/adaptive-card.json",
25 "type":"AdaptiveCard",
26 "version":"1.2",
27 "body":[
28 {
29 "type": "TextBlock",
30 "size": "Medium",
31 "weight": "Bolder",
32 "text": "Bla Bla"
33 }
34 ]
35 }
36 }
37 ]
38 }
39
40
41 response = requests.post(flow_url, headers=headers, json=payload, proxies=proxies)
42
43 if response.status_code == 202:
44 print("Message sent successfully")
45 else:
46 print(f"Failed to send message. Status code: {response.status_code}")
47 print(f"Response: {response.text}")
Works - so all there is to do (probs) is deciding what to put where to have the information you need and to make it look pretty.
@hajohoetger didn't go through your code but it looks different from the template "draft" I posted above. Give it a try.
P.S.: You can use triple backticks to get a code block or > for quotes - makes it way easier to read.
I got this far, it works for new vulnerabilities.
{ "attachments": [ { "contentType": "object", "content": { "type": "AdaptiveCard", "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "version": "1.2", "body": [ { "type": "TextBlock", "size": "Medium", "weight": "Bolder", "text": "{{ notification.title | escape(strategy="json") }}" }, { "type": "TextBlock", "text": "Dependency-Track", "weight": "Bolder", "spacing": "Medium" }, { "type": "TextBlock", "text": "{{ timestamp }}", "spacing": "None" }, { "type": "Image", "url": "https://raw.githubusercontent.com/DependencyTrack/branding/master/dt-logo-symbol-blue-background.png", "size": "Small", "spacing": "Medium" }, { "type": "FactSet", "facts": [ { "title": "VulnID", "value":"{{ subject.vulnerability.vulnId | escape(strategy="json") }}" }, { "title": "Severity", "value": "{{ subject.vulnerability.severity | escape(strategy="json") }}" }, { "title": "Source", "value": "{{ subject.vulnerability.source | escape(strategy="json") }}" }, { "title": "Component", "value": "{{ subject.component.toString | escape(strategy="json") }}" } ] }, { "type": "TextBlock", "text": "{{ notification.content | escape(strategy="json") }}", "wrap": true } ] } } ] }
Use the teams workflow as below:
Hi, sorry to bother you again, but i'm trying for hours now without success. I did manage to display my card in teams, but it is cut, though i have defined "targetWidth": "Wide". I tried that in all parts but that does not change the layout. I just want the card to fit the width of the screen. Often the expert sees the problem at first sight. Then it would be very nice to hint me on that...
proxies= {
"https": f"http://{proxyip}:{proxyport}"
}
payload = {
"type":"AdaptiveCard",
"attachments":[
{
"contentType":"application/vnd.microsoft.card.adaptive",
"contentUrl":None,
"content":{
"$schema":"http://adaptivecards.io/schemas/adaptive-card.json",
"type":"AdaptiveCard",
"version":"1.2",
"targetWidth": "Wide",
"body":[
{
"type": "TextBlock",
"size": "Medium",
"weight": "Bolder",
"text": "Provisionierung erfolgt!"
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"items": [
{
"type": "TextBlock",
"text": "Ressource:"
},
{
"type": "TextBlock",
"text": "UserID:"
},
{
"type": "TextBlock",
"text": "Action:"
}
],
"width": "auto"
},
{
"type": "Column",
"items": [
{
"type": "TextBlock",
"text": ressource
},
{
"type": "TextBlock",
"text": uid
},
{
"type": "TextBlock",
"text": action
}
],
"width": "stretch"
}
]
}
]
}
}
]
}
response = requests.post(url[stage], headers=headers, json=payload, proxies=proxies)
The output in Teams looks like this:
I used three ticks to make the code more readeable, but that didn't work. Maybe, if i upload that as file:
@hajohoetger I used three ticks to make the code more readeable, but that didn't work.
It has to be backticks: ```
@hajohoetger I used three ticks to make the code more readeable, but that didn't work.
It has to be backticks:
```
...indeed, that works! (Have edited my former posts.) Thank you! :-)
Getting below error while posting a message with using new workflow URL
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.
I am using legacy card like that used to work with webhook URL. It's throwing an above error when use workflow URL
[Array]$audit =
@{
name = "LastBuildStatus and Provisioning State"
value = ("$($results.LastRunStatusRunState)" + " - " + "$($results.ProvisioningState -join ',')")
}
$body = ConvertTo-Json -Depth 10 @{
title = "Status"
text = "Reminder "
separator = "true"
sections = @(
@{
activityTitle = "Test "
activitySubtitle = "Please take an action, accordingly, refer [document](https: doc link)"
facts = $audit
}
)
}
Invoke-RestMethod -Method post -ContentType 'application/Json' -Body $body -Uri $workflowUrl
Any one encountered same issue? Do we really need to convert legacy card into adaptative card format ?
Yes we do. Apparently they realized the time window was a bit short and they are going to support old webhooks for longer but you still can no longer create them, only power automate workflows. And they expect a different body with attachments of adaptive cards. I haven't come around to file a PR as the duct taped version above is GEFN for me 🙃
Here is an adaptive-card-template that works well for me:
{
"type":"message",
"attachments":[
{
"contentType":"application/vnd.microsoft.card.adaptive",
"contentUrl":"{{ baseUrl }}/projects/{{ subject.project.uuid | escape(strategy='json') }}",
"content":{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"size": "Medium",
"weight": "Bolder",
"text": "{{ notification.title | escape(strategy="json") }}",
"wrap": true
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"items": [
{
"type": "Image",
"style": "Person",
"url": "https://raw.githubusercontent.com/DependencyTrack/branding/master/dt-logo-symbol-blue-background.png",
"altText": "DependencyTrack",
"size": "Small"
}
],
"width": "auto"
},
{
"type": "Column",
"items": [
{
"type": "TextBlock",
"weight": "Bolder",
"text": "DependencyTrack",
"wrap": true
},
{
"type": "TextBlock",
"spacing": "None",
"text": "{{ timestamp }}",
"isSubtle": true,
"wrap": true
}
],
"width": "stretch"
}
]
},
{
"type": "TextBlock",
"text": "{{ notification.content | escape(strategy="json") }}",
"wrap": true
},
{% if notification.group == "NEW_VULNERABILITY" %}
{
"type": "FactSet",
"facts": [
{
"title": "Project:",
"value": "{{ subject.component.project.toString | escape(strategy="json") }}"
},
{
"title": "Component:",
"value": "{{ subject.component.toString | escape(strategy="json") }}"
},
{
"title": "Version:",
"value": "{{ subject.component.version | escape(strategy="json") }}"
},
{
"title": "Severity:",
"value": "{{ subject.vulnerability.severity | escape(strategy="json") }}"
},
{
"title": "VulnId:",
"value": "{{ subject.vulnerability.vulnId | escape(strategy="json") }}"
}
]
}
{% elseif notification.group == "NEW_VULNERABLE_DEPENDENCY" %}
{
"type": "FactSet",
"facts": [
{
"title": "Project:",
"value": "{{ subject.component.project.toString | escape(strategy="json") }}"
},
{
"title": "Component:",
"value": "{{ subject.component.toString | escape(strategy="json") }}"
},
{
"title": "Version:",
"value": "{{ subject.component.version | escape(strategy="json") }}"
}
]
}
{% elseif notification.group == "POLICY_VIOLATION" %}
{
"type": "FactSet",
"facts": [
{
"title": "Project:",
"value": "{{ subject.component.project.toString | escape(strategy="json") }}"
},
{
"title": "Component:",
"value": "{{ subject.component.toString | escape(strategy="json") }}"
},
{
"title": "Version:",
"value": "{{ subject.component.version | escape(strategy="json") }}"
}
]
}
{% elseif notification.group == "BOM_PROCESSING_FAILED" %}
{
"type": "FactSet",
"facts": [
{
"title": "Project:",
"value": "{{ subject.component.project.toString | escape(strategy="json") }}"
},
{
"title": "Component:",
"value": "{{ subject.component.toString | escape(strategy="json") }}"
},
{
"title": "Version:",
"value": "{{ subject.component.version | escape(strategy="json") }}"
}
]
}
{% endif %}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.4"
}
}
]
}
Anything on this that could be included per default in DT? Do we need two separate publishers? One for the legacy, and one for the new format?
Someone still has to sit down and work this out for the general case.
As the legacy connectors' life span was extended we should have both.
@black-snow My template works for the general case.
There is a designer available here to work on the template: https://adaptivecards.io/
Someone still has to sit down and actually file a PR with @fabian-zeindl-oebb 's template :D
Note that Microsoft has updated the guidance in the original post and now says that they are looking into allowing messages to continue to be posted using the MessageCard format:
Current Behavior
M$ is retiring the classic webhooks and you'll have to use Power Automate workflows instead.
The linked page doesn't have too many details about the transition so I thought it'd be a swap & replace. But apparently that's not true. With the existing template my workflow errs with:
Proposed Behavior
I guess it'd be a good idea to have a new template for notifications for workflows that works out of the box and has an adequate name.
Checklist