Teams Workflows provides a seamless way to automate tasks, integrate with various services, and improve team collaboration. This guide will help you navigate the process, ensuring a smooth transition from Connectors to Workflows, and leverage the full potential of the latest features and functionalities that Teams Workflows offer.
Go to Teams
Right-click on any channel
Select ‘Workflows'
Now we need to create a flow chain that will listen to Jira webhooks and react to the JSON sent in the request. In this example, we will send an Adaptive card with information about the changed issue to the channel
HTTP POST URL should be decoded or all ‘%2F' should be replaced with the '/’, otherwise Jira Webhook will throw 403 error code
The domain for the webhook should be added to the Allow list in order to send data to the webhook. otherwise, it could be blocked.
5. Add new action to the Workflow → Prase JSON
6. Set @{triggerBody()}
to the Content field
7. Set Json Schema to the Schema field
{
"type": "object",
"properties": {
"webhookEvent": {
"type": "string"
},
"issue_event_type_name": {
"type": "string"
},
"user": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"avatarUrls": {
"type": "object",
"properties": {
"48x48": {
"type": [
"string",
"null"
]
}
}
}
}
},
"issue": {
"type": "object",
"properties": {
"self": {
"type": "string"
},
"key": {
"type": "string"
},
"fields": {
"type": "object",
"properties": {
"issuetype": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
"summary": {
"type": "string"
},
"description": {
"type": [
"string",
"null"
]
},
"status": {
"type": "object",
"properties": {
"statusCategory": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"colorName": {
"type": "string"
}
}
}
}
},
"priority": {
"type": "object",
"properties": {
"iconUrl": {
"type": [
"string",
"null"
]
}
}
},
"assignee": {
"type": [
"object",
"null"
],
"properties": {
"avatarUrls": {
"type": "object",
"properties": {
"48x48": {
"type": [
"string",
"null"
]
}
}
}
}
}
}
}
}
},
"changelog": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field": {
"type": "string"
},
"fromString": {
"type": [
"string",
"null"
]
},
"toString": {
"type": [
"string",
"null"
]
}
}
}
}
}
}
}
}
8. Add new Action → Post card in a chat or channel
9. Choose where the Adaptive card will be sent and configure the Adaptive Card JSON
{ "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "version": "1.4", "type": "AdaptiveCard", "body": [ { "type": "Container", "width": "stretch", "items": [ { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "auto", "items": [ { "type": "Image", "style": "Person", "url": "@{if(equals(body('Parse_JSON')?['user']?['avatarUrls']?['48x48'], null), 'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp&f=y', body('Parse_JSON')['user']['avatarUrls']['48x48'])}", "size": "Small", "height": "32px", "width": "32px", "horizontalAlignment": "Right" } ], "verticalContentAlignment": "Center" }, { "type": "Column", "width": "stretch", "items": [ { "type": "TextBlock", "text": "@{if(equals(body('Parse_JSON')['webhookEvent'], 'jira:issue_created'), concat(body('Parse_JSON')['user']['name'], ' **created** this issue:'), if(equals(body('Parse_JSON')['issue_event_type_name'], 'issue_commented'), concat(body('Parse_JSON')['user']['name'], ' **commented** on this issue:'), concat(body('Parse_JSON')['user']['name'], ' updated the **', body('Parse_JSON')['changelog']['items'][0]['field'], '** on this issue:')))}", "size": "Large", "color": "Default", "wrap": true } ], "verticalContentAlignment": "Center" } ] }, { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "auto", "items": [ { "type": "Image", "url": "@{concat('https://product-integrations-cdn.atl-paas.net/jira-issuetype/medium/', if(or(equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'access request'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'bug'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'epic'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'change'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'concern'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'defect'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'design task'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'development task'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'documentation'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'improvement'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'incident'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'issue'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'new feature'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'new-feature'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'problem'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'question'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'remove feature'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'requirement'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'sales request'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'story'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'sub-task'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'subtask'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'suggestion'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'task')), toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'bug grey'), '.png')}", "size": "Small", "width": "24px", "horizontalAlignment": "Right" } ], "verticalContentAlignment": "Center" }, { "type": "Column", "width": 80, "items": [ { "type": "TextBlock", "text": "@{concat(body('Parse_JSON')['issue']['key'], ' - ', replace(body('Parse_JSON')['issue']['fields']['summary'], '"', '\"')) }", "color": "Default", "wrap": true } ], "verticalContentAlignment": "Center" }, { "type": "Column", "width": 20, "items": [ { "type": "RichTextBlock", "inlines": [ { "type": "TextRun", "text": "@{toUpper(body('Parse_JSON')['issue']['fields']['status']['statusCategory']['name'])}", "highlight": true, "isSubtle": true, "color": "Default" } ] } ], "verticalContentAlignment": "Center", "rtl": true }, { "type": "Column", "width": "auto", "items": [ { "type": "Image", "url": "@{if(equals(body('Parse_JSON')['issue']['fields']['assignee'], null), 'https://jira.atlassian.com/secure/useravatar?size=small&avatarId=10613', body('Parse_JSON')['issue']['fields']['assignee']['avatarUrls']['48x48'])}", "size": "Small", "width": "24px", "style": "Person", "horizontalAlignment": "Right" } ], "verticalContentAlignment": "Center" } ], "separator": true, "spacing": "ExtraLarge" }, { "type": "ColumnSet", "spacing": "Small", "isVisible": "@{and(not(equals(body('Parse_JSON')['webhookEvent'], 'jira:issue_created')), contains(string(body('Parse_JSON')), 'changelog'))}", "columns": [ { "type": "Column", "width": "auto", "items": [ { "type": "RichTextBlock", "horizontalAlignment": "Right", "inlines": [ { "type": "TextRun", "text": "@{if(or(equals(body('Parse_JSON')?['changelog']?['items']?[0]?['fromString'], null), equals(body('Parse_JSON')?['changelog']?['items']?[0]?['fromString'], '')), 'Empty', replace(body('Parse_JSON')?['changelog']?['items']?[0]?['fromString'], '"', '\"')) }" } ] } ], "verticalContentAlignment": "Center" }, { "type": "Column", "verticalContentAlignment": "Center", "width": "15px", "items": [ { "type": "RichTextBlock", "inlines": [ { "type": "TextRun", "text": "→" } ] } ], "spacing": "Small" }, { "type": "Column", "width": "auto", "items": [ { "type": "RichTextBlock", "inlines": [ { "type": "TextRun", "text": "@{if(or(equals(body('Parse_JSON')?['changelog']?['items']?[0]?['toString'], null), equals(body('Parse_JSON')?['changelog']?['items']?[0]?['toString'], '')), 'Empty', replace(body('Parse_JSON')?['changelog']?['items']?[0]?['toString'], '"', '\"')) }" } ] } ], "verticalContentAlignment": "Center" } ] }, { "type": "ColumnSet", "spacing": "Small", "isVisible": "@{contains(body('Parse_JSON')['issue_event_type_name'], 'issue_commented')}", "columns": [ { "type": "Column", "width": "stretch", "items": [ { "type": "TextBlock", "text": "@{if(equals(body('Parse_JSON')['issue_event_type_name'], 'issue_commented'), replace(body('Parse_JSON')?['comment']?['body'], '"', '\"'), '') }", "wrap": true } ], "verticalContentAlignment": "Center" } ] }, { "type": "ActionSet", "actions": [ { "type": "Action.OpenUrl", "title": "Open in Jira", "url": "@{concat(substring(body('Parse_JSON')['issue']['self'], 0, indexOf(body('Parse_JSON')['issue']['self'], '/rest/api/2/issue')), '/browse/', body('Parse_JSON')['issue']['key'])}" } ] } ] } ], "msTeams": { "width": "full" } }
10. The final step chain should look like on the screenshot
Now when the issue in Jira Data Center is modified, the Adaptive card will be sent to the chosen channel
The configuration above works only for issue created and updated events, including comment creation event. If you also want to receive the events when comment was updated or removed or just events related to comments, please follow next instructions to adjust the Workflow configuration above:
"@body('Parse_JSON')?['webhookEvent']" equals "jira:issue_created"
"expression": {
"or": [
{
"equals": [
"@body('Parse_JSON')?['webhookEvent']",
"jira:issue_created"
]
},
{
"and": [
{
"equals": [
"@body('Parse_JSON')?['webhookEvent']",
"jira:issue_updated"
]
},
{
"not": {
"contains": [
"@body('Parse_JSON')?['issue_event_type_name']",
"comment"
]
}
}
]
}
]
}
"expression": {
"or": [
{
"equals": [
"@body('Parse_JSON')?['webhookEvent']",
"comment_created"
]
},
{
"equals": [
"@body('Parse_JSON')?['webhookEvent']",
"comment_updated"
]
},
{
"equals": [
"@body('Parse_JSON')?['webhookEvent']",
"comment_deleted"
]
}
]
}
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.4",
"type": "AdaptiveCard",
"body": [
{
"type": "Container",
"width": "stretch",
"items": [
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "Image",
"style": "Person",
"url": "@{if(equals(body('Parse_JSON')?['comment']?['author']?['avatarUrls']?['48x48'], null), 'https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp&f=y', body('Parse_JSON')['comment']['author']['avatarUrls']['48x48'])}",
"size": "Small",
"height": "32px",
"width": "32px",
"horizontalAlignment": "Right"
}
],
"verticalContentAlignment": "Center"
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "@{if(equals(body('Parse_JSON')['webhookEvent'], 'comment_updated'), concat(body('Parse_JSON')['comment']['author']['name'], ' **updated comment** on this issue::'), if(equals(body('Parse_JSON')['webhookEvent'], 'comment_deleted'), concat(body('Parse_JSON')['comment']['author']['name'], ' **removed commented** on this issue:'), concat(body('Parse_JSON')['comment']['author']['name'], ' **commented** on this issue:')))}",
"size": "Large",
"color": "Default",
"wrap": true
}
],
"verticalContentAlignment": "Center"
}
]
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "Image",
"url": "@{concat('https://product-integrations-cdn.atl-paas.net/jira-issuetype/medium/', if(or(equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'access request'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'bug'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'epic'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'change'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'concern'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'defect'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'design task'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'development task'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'documentation'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'improvement'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'incident'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'issue'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'new feature'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'new-feature'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'problem'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'question'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'remove feature'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'requirement'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'sales request'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'story'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'sub-task'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'subtask'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'suggestion'), equals(toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'task')), toLower(body('Parse_JSON')['issue']['fields']['issuetype']['name']), 'bug grey'), '.png')}",
"size": "Small",
"width": "24px",
"horizontalAlignment": "Right"
}
],
"verticalContentAlignment": "Center"
},
{
"type": "Column",
"width": 80,
"items": [
{
"type": "TextBlock",
"text": "@{concat(body('Parse_JSON')['issue']['key'], ' - ', replace(body('Parse_JSON')['issue']['fields']['summary'], '"', '\"'))
}",
"color": "Default",
"wrap": true
}
],
"verticalContentAlignment": "Center"
},
{
"type": "Column",
"width": 20,
"items": [
{
"type": "RichTextBlock",
"inlines": [
{
"type": "TextRun",
"text": "@{toUpper(body('Parse_JSON')['issue']['fields']['status']['statusCategory']['name'])}",
"highlight": true,
"isSubtle": true,
"color": "Default"
}
]
}
],
"verticalContentAlignment": "Center",
"rtl": true
},
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "Image",
"url": "@{if(equals(body('Parse_JSON')['issue']['fields']['assignee'], null), 'https://jira.atlassian.com/secure/useravatar?size=small&avatarId=10613', body('Parse_JSON')['issue']['fields']['assignee']['avatarUrls']['48x48'])}",
"size": "Small",
"width": "24px",
"style": "Person",
"horizontalAlignment": "Right"
}
],
"verticalContentAlignment": "Center"
}
],
"separator": true,
"spacing": "ExtraLarge"
},
{
"type": "ColumnSet",
"spacing": "Small",
"columns": [
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "@{replace(body('Parse_JSON')?['comment']?['body'], '"', '\"')}",
"wrap": true
}
],
"verticalContentAlignment": "Center"
}
]
},
{
"type": "ActionSet",
"actions": [
{
"type": "Action.OpenUrl",
"title": "Open in Jira",
"url": "@{concat(substring(body('Parse_JSON')['issue']['self'], 0, indexOf(body('Parse_JSON')['issue']['self'], '/rest/api/2/issue')), '/browse/', body('Parse_JSON')['issue']['key'])}"
}
]
}
]
}
],
"msTeams": {
"width": "full"
}
}
Cheers,
Product Integrations Team
Zakhar Listiev
65 comments