AutomationFlowsSlack & Telegram › Track Jira Epic Health with Automated Risk Alerts via Slack, Monday & Sheets

Track Jira Epic Health with Automated Risk Alerts via Slack, Monday & Sheets

ByRahul Joshi @rahul08 on n8n.io

Transform your Jira project management workflow with this intelligent n8n automation template that continuously tracks, scores, and reports the health of Jira Epics.

Cron / scheduled trigger★★★★☆ complexity20 nodesJiraSlackMonday.comGoogle Sheets
Slack & Telegram Trigger: Cron / scheduled Nodes: 20 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #9832 — we link there as the canonical source.

This workflow follows the Google Sheets → Slack recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "KwWlPZAiObwL1LOi",
  "name": "Jira Epic Health Score & Risk Dashboard",
  "tags": [],
  "nodes": [
    {
      "id": "5bb8e683-bde5-48d3-a424-1221f40f6580",
      "name": "Trigger Every 6 Hours",
      "type": "n8n-nodes-base.cron",
      "position": [
        -2864,
        1360
      ],
      "parameters": {
        "triggerTimes": {
          "item": [
            {
              "mode": "everyX",
              "value": 6
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a452f278-a5ea-443a-b98e-b33bb7d27aef",
      "name": "\ud83d\udcca Workflow Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3216,
        1232
      ],
      "parameters": {
        "width": 280,
        "height": 256,
        "content": "\ud83d\udcca WORKFLOW START\n\nThis workflow monitors Jira Epics and calculates health scores:\n\n\u2022 Runs every 6 hours\n\u2022 Fetches all Epics\n\u2022 Analyzes linked issues\n\u2022 Calculates health metrics\n\u2022 Flags at-risk epics\n\u2022 Updates dashboards\n\u2022 Alerts team via Slack"
      },
      "typeVersion": 1
    },
    {
      "id": "e051afef-6cb0-45aa-b244-51baacd48602",
      "name": "Fetch All Epics from Jira",
      "type": "n8n-nodes-base.jira",
      "position": [
        -2608,
        1360
      ],
      "parameters": {
        "options": {},
        "operation": "getAll"
      },
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "aef82a98-c0db-40f6-a3bb-a9df4535ec98",
      "name": "\ud83d\udce5 Fetch Epics",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2752,
        1088
      ],
      "parameters": {
        "width": 280,
        "height": 236,
        "content": "\ud83d\udce5 EPIC RETRIEVAL\n\nFetches all Epics from Jira:\n\n\u2022 Uses Jira REST API\n\u2022 getAll operation\n\u2022 Retrieves: Epic keys, names, fields\n\u2022 Filters to Epics only\n\nReturns list of all Epics in project\nPassed to Split Epics for processing"
      },
      "typeVersion": 1
    },
    {
      "id": "1d172b8c-c88f-4ab5-b6ce-19110edcd433",
      "name": "Split Epics for Processing",
      "type": "n8n-nodes-base.function",
      "position": [
        -2368,
        1360
      ],
      "parameters": {
        "functionCode": "const output = [];\nfor (const epic of items) {\n  const key = epic.json.key;\n  output.push({ json: { epicKey: key }});\n}\nreturn output;"
      },
      "typeVersion": 1
    },
    {
      "id": "464b3b19-6f73-4a72-9dd4-8e77edb75439",
      "name": "\ud83d\udd00 Split Epics",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2496,
        1552
      ],
      "parameters": {
        "width": 280,
        "height": 316,
        "content": "\ud83d\udd00 SPLIT EPICS\n\nTransforms Epic batch into individual items:\n\n\u2022 Iterates through each Epic\n\u2022 Extracts Epic key\n\u2022 Creates separate object per Epic\n\u2022 Enables sequential processing\n\nInput: Array of Epics\nOutput: Individual Epic objects with key\n\nAllows detailed analysis per Epic"
      },
      "typeVersion": 1
    },
    {
      "id": "63fe1ee2-e389-42f7-81ee-a8cf7fca80f7",
      "name": "Fetch Epic + Linked Issues",
      "type": "n8n-nodes-base.jira",
      "position": [
        -2112,
        1360
      ],
      "parameters": {
        "issueKey": "={{ $json.epicKey }}",
        "operation": "get",
        "additionalFields": {}
      },
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "0f47c09d-d22d-423e-9be4-e43fe3c39d0b",
      "name": "\ud83d\udd17 Fetch Linked",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2208,
        1024
      ],
      "parameters": {
        "width": 280,
        "height": 300,
        "content": "\ud83d\udd17 FETCH LINKED ISSUES\n\nFor each Epic, retrieves:\n\n\u2022 Epic metadata\n\u2022 All linked child issues\n\u2022 Issue details:\n  \u2713 Status\n  \u2713 Issue type (Bug/Task)\n  \u2713 Labels (blocker, etc)\n  \u2713 Cycle time metrics\n  \u2713 Custom fields\n\nUsed to calculate health metrics"
      },
      "typeVersion": 1
    },
    {
      "id": "750efdd8-c544-41ee-aa9c-ac3c11df107a",
      "name": "Calculate Health Score",
      "type": "n8n-nodes-base.function",
      "position": [
        -1856,
        1360
      ],
      "parameters": {
        "functionCode": "const results = [];\n\nfor (const item of items) {\n  const issues = item.json.issues || [];\n  const total = issues.length || 1;\n\n  let cycleTime = 0;\n  let blockers = 0;\n  let churn = 0;\n  let bugs = 0;\n\n  for (const issue of issues) {\n    cycleTime += issue.fields.customfield_cycle_time || 0;\n    if (issue.fields.labels && issue.fields.labels.includes('blocker')) blockers++;\n    if (issue.fields.status && issue.fields.status.name === 'Reopened') churn++;\n    if (issue.fields.issuetype && issue.fields.issuetype.name === 'Bug') bugs++;\n  }\n\n  const avgCycleTime = cycleTime / total;\n  const bugRatio = bugs / total;\n  const churnRatio = churn / total;\n  const blockerRatio = blockers / total;\n\n  // Weighted scoring\n  const healthScore = (avgCycleTime * 0.4) + (bugRatio * 0.3) + (churnRatio * 0.2) + (blockerRatio * 0.1);\n\n  results.push({\n    json: {\n      epicKey: item.json.epicKey || item.json.key,\n      healthScore: Number(healthScore.toFixed(2))\n    }\n  });\n}\n\nreturn results;\n"
      },
      "typeVersion": 1
    },
    {
      "id": "c8f3a361-a296-461d-93f8-3472d1f9f337",
      "name": "\ud83d\udcc8 Health Score",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1968,
        1536
      ],
      "parameters": {
        "width": 280,
        "height": 376,
        "content": "\ud83d\udcc8 HEALTH SCORE ALGORITHM\n\nWeighted formula (0-1 scale):\n\nmetrics calculated:\n\u2713 avgCycleTime: Average days/hours\n\u2713 bugRatio: Bugs / Total issues\n\u2713 churnRatio: Reopened / Total\n\u2713 blockerRatio: Blockers / Total\n\nWeights (importance):\n\u2022 avgCycleTime: 40% (velocity)\n\u2022 bugRatio: 30% (quality)\n\u2022 churnRatio: 20% (stability)\n\u2022 blockerRatio: 10% (dependencies)\n\nScore 0.0 = Healthy\nScore > 0.6 = At Risk \u26a0\ufe0f"
      },
      "typeVersion": 1
    },
    {
      "id": "8aee7bd4-f155-4540-9598-d8923556673c",
      "name": "Is Score > 0.6 (At Risk)?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1616,
        1360
      ],
      "parameters": {
        "conditions": {
          "number": [
            {
              "value1": "={{$json[\"healthScore\"]}}",
              "value2": 0.6,
              "operation": "larger"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e33d520e-955a-4ca2-9e11-1aaf8a078dfe",
      "name": "\u26a0\ufe0f Risk Check",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1792,
        1008
      ],
      "parameters": {
        "width": 280,
        "height": 316,
        "content": "\u26a0\ufe0f RISK THRESHOLD\n\nCondition: healthScore > 0.6\n\nInterpretation:\n\u2022 Score 0.0-0.6 = Healthy \u2705\n\u2022 Score > 0.6 = At Risk \u26a0\ufe0f\n\nIf AT RISK:\n\u2192 Update Epic in Jira\n\u2192 Add \"At Risk\" label\n\u2192 Alert team via Slack\n\u2192 Log to Monday & Sheets\n\nIf HEALTHY:\n\u2192 No action needed"
      },
      "typeVersion": 1
    },
    {
      "id": "7a14fe1b-bd86-4040-8655-0e8d48f5e35e",
      "name": "Update Epic in Jira",
      "type": "n8n-nodes-base.jira",
      "position": [
        -1344,
        1024
      ],
      "parameters": {
        "issueKey": "={{$json[\"epicKey\"]}}",
        "operation": "update",
        "updateFields": {
          "labels": [
            "At Risk"
          ],
          "customFieldsUi": {
            "customFieldsValues": [
              {
                "fieldId": "customfield_10060",
                "fieldValue": "={{$json[\"healthScore\"]}}"
              }
            ]
          }
        }
      },
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "dc4eba68-ee7f-4226-8369-3fdeaf7806d7",
      "name": "\ud83d\udd04 Jira Update",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1440,
        720
      ],
      "parameters": {
        "width": 280,
        "height": 268,
        "content": "\ud83d\udd04 JIRA UPDATE\n\nUpdates at-risk Epic:\n\n\u2022 Sets custom field:\n  customfield_10060 = Health Score\n\u2022 Adds label: \"At Risk\"\n\u2022 Creates audit trail\n\u2022 Visible in Epic view\n\nTeam sees risk status immediately in Jira\nEnables auto-filtering by label"
      },
      "typeVersion": 1
    },
    {
      "id": "48ef861d-0de4-4424-b453-a5a26f94716f",
      "name": "Alert Slack Channel",
      "type": "n8n-nodes-base.slack",
      "position": [
        -1360,
        1200
      ],
      "parameters": {
        "text": "\ud83d\udea8 *Epic At Risk:* {{$json[\"epicKey\"]}}\nHealth Score: {{$json[\"healthScore\"]}}\nhttps://yourdomain.atlassian.net/browse/{{$json[\"epicKey\"]}}",
        "channel": "#project-alerts",
        "attachments": [],
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "822fc9ef-2efe-45a5-9bdf-4d4cd5bc14a2",
      "name": "\ud83d\udea8 Slack Alert",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1168,
        1168
      ],
      "parameters": {
        "width": 280,
        "height": 268,
        "content": "\ud83d\udea8 SLACK ALERT\n\nSends to: #project-alerts\n\nContains:\n\u2713 Epic key\n\u2713 Health score value\n\u2713 Direct link to Epic in Jira\n\u2713 Timestamp (automatic)\n\nEnables real-time team notification\nCritical for risk mitigation\nAllows quick team action"
      },
      "typeVersion": 1
    },
    {
      "id": "cd79db68-7aad-43bf-a436-75e377daa0fa",
      "name": "Update Monday.com Pulse",
      "type": "n8n-nodes-base.mondayCom",
      "position": [
        -1280,
        1552
      ],
      "parameters": {
        "operation": "update"
      },
      "credentials": {
        "mondayComApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "03da2282-3393-4c2d-b81b-66d8527e2873",
      "name": "\ud83d\udccb Monday Pulse",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1072,
        1488
      ],
      "parameters": {
        "width": 280,
        "height": 300,
        "content": "\ud83d\udccb MONDAY.COM PULSE\n\nUpdates Monday.com board with:\n\n\u2022 Health score metric\n\u2022 Risk status\n\u2022 Last updated timestamp\n\nSyncs data across platforms\nKeeps Monday boards current\nPulse shows real-time metrics\n\nNote: Requires Monday.com credential setup"
      },
      "typeVersion": 1
    },
    {
      "id": "716d2c3b-5cc4-4358-8f1a-c89844774af6",
      "name": "Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1280,
        1760
      ],
      "parameters": {
        "range": "A:C",
        "options": {
          "valueInputMode": "USER_ENTERED"
        },
        "sheetId": "Your Google Sheet ID",
        "operation": "append"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "41c60824-3019-4cc1-8284-1ca48deb52f4",
      "name": "\ud83d\udcca Sheets Log",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1408,
        1920
      ],
      "parameters": {
        "width": 280,
        "height": 332,
        "content": "\ud83d\udcca GOOGLE SHEETS LOG\n\nAppends historical record:\n\nColumns (A:C):\n\u2713 Timestamp\n\u2713 Epic Key\n\u2713 Health Score\n\nUsed for:\n\u2022 Trend analysis\n\u2022 Risk history\n\u2022 Compliance audit\n\u2022 Dashboard creation\n\u2022 Performance tracking\n\nBuilds dataset over time"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "258c9a43-6f98-43c1-bbe4-91090329165b",
  "connections": {
    "Trigger Every 6 Hours": {
      "main": [
        [
          {
            "node": "Fetch All Epics from Jira",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Health Score": {
      "main": [
        [
          {
            "node": "Is Score > 0.6 (At Risk)?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch All Epics from Jira": {
      "main": [
        [
          {
            "node": "Split Epics for Processing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Score > 0.6 (At Risk)?": {
      "main": [
        [
          {
            "node": "Update Epic in Jira",
            "type": "main",
            "index": 0
          },
          {
            "node": "Alert Slack Channel",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Monday.com Pulse",
            "type": "main",
            "index": 0
          },
          {
            "node": "Log to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Epic + Linked Issues": {
      "main": [
        [
          {
            "node": "Calculate Health Score",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Epics for Processing": {
      "main": [
        [
          {
            "node": "Fetch Epic + Linked Issues",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Transform your Jira project management workflow with this intelligent n8n automation template that continuously tracks, scores, and reports the health of Jira Epics.

Source: https://n8n.io/workflows/9832/ — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

&gt; n8n, Binance API, Google Sheets, Slack, Telegram, Jira & Email

HTTP Request, Google Sheets, Slack +3
Slack & Telegram

This workflow continuously monitors the Meta Ads Library for new creatives from a specific competitor pages, logs them into Google Sheets, and sends a concise Telegram notification with the number of

HTTP Request, Telegram, Google Sheets +1
Slack & Telegram

Enhance financial oversight with this automated n8n workflow. Triggered every 5 minutes, it fetches real-time bank transactions via an API, enriches and transforms the data, and applies smart logic to

HTTP Request, Email Send, Google Sheets +1
Slack & Telegram

This workflow automates competitive price intelligence using Bright Data's enterprise web scraping API. On a scheduled basis (default: daily at 9 AM), the system loops through configured competitor pr

HTTP Request, Google Sheets, Slack +1
Slack & Telegram

Ensure your customer SLAs never slip with this n8n automation template. The workflow runs on a schedule, fetching open tickets from Zendesk, calculating SLA time remaining, and sending proactive alert

Zendesk, Slack, Google Sheets