Suivi automatique des dépendances inter-projets entre Jira et Monday.com

Avancé

Ceci est uncontenant 21 nœuds.Utilise principalement des nœuds comme If, Code, Cron, Jira, Gmail. Automatisation du suivi des dépendances inter-projects entre Jira et Monday.com

Prérequis
  • Compte Google et informations d'identification Gmail API
  • Token Bot Slack ou URL Webhook

Catégorie

-
Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "id": "hXfojMGA8g8QnEdF",
  "meta": {
    "instanceId": "8443f10082278c46aa5cf3acf8ff0f70061a2c58bce76efac814b16290845177",
    "templateCredsSetupCompleted": true
  },
  "name": "Automate Cross-Project Dependency Tracking between Jira and Monday.com",
  "tags": [],
  "nodes": [
    {
      "id": "b7490099-ba71-42e9-b2cc-0ce23060a602",
      "name": "Description du Workflow",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1360,
        -400
      ],
      "parameters": {
        "color": 4,
        "width": 389,
        "height": 560,
        "content": "## 🎯 Workflow Overview\n\nThis automation monitors Jira project dependencies and proactively alerts teams about blocking issues that could delay project delivery.\n\n**What it does:**\n- Runs nightly to scan all open Jira issues\n- Identifies blocking dependencies and calculates risk scores\n- Creates coordination tasks for high-impact blockers\n- Sends formatted email reports and Slack notifications\n- Syncs critical items to Monday.com boards\n\n**Use Case:** Perfect for project managers tracking cross-team dependencies and preventing delivery delays.\n\n**Required Setup:**\n- Jira Software Cloud credentials\n- Gmail OAuth2 credentials\n- Slack workspace access\n- Monday.com account\n- Update project key in Fetch Jira Issues node"
      },
      "typeVersion": 1
    },
    {
      "id": "185308d0-69ba-44f1-bdbe-a93ce06a5209",
      "name": "Déclencheur (Exécution Nocturne)",
      "type": "n8n-nodes-base.cron",
      "position": [
        -736,
        -144
      ],
      "parameters": {
        "triggerTimes": {
          "item": [
            {}
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "1bd430b2-9823-4650-af57-a7870851d9d2",
      "name": "Note - Déclencheur",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -944,
        -448
      ],
      "parameters": {
        "width": 262,
        "height": 306,
        "content": "## ⏰ Scheduled Trigger\n\nRuns daily at midnight (00:00) to generate fresh dependency reports.\n\n**Configuration:**\n- Default: Runs at 00:00:00 daily\n- Customize timing in trigger settings\n- Consider your team's timezone"
      },
      "typeVersion": 1
    },
    {
      "id": "b7cf7c45-aa71-4369-9d8b-3bc7a612a285",
      "name": "Note - Récupération",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -592,
        32
      ],
      "parameters": {
        "width": 262,
        "height": 357,
        "content": "## 📋 Fetch Open Issues\n\n**Setup Required:**\n1. Update JQL query with your project key\n2. Example: `project = MYPROJ AND statusCategory != Done`\n3. Connect your Jira credentials\n\n**What it fetches:**\n- All non-completed issues\n- Issue links and dependencies\n- Assignee and due date info"
      },
      "typeVersion": 1
    },
    {
      "id": "6d07db03-aa56-43ec-bad8-ba089d2b973a",
      "name": "Filtrer les Dépendances",
      "type": "n8n-nodes-base.if",
      "position": [
        -304,
        -144
      ],
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.fields.issuelinks }}",
              "operation": "isNotEmpty"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "9686f647-dafd-4597-842b-ff35aab99c23",
      "name": "Note - Filtre",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -384,
        -448
      ],
      "parameters": {
        "width": 262,
        "height": 290,
        "content": "## 🔍 Filter Dependencies\n\nOnly processes issues that have linked dependencies.\n\n**Logic:**\n- Checks if `issuelinks` field exists\n- Passes issues with dependencies to next node\n- Skips standalone issues"
      },
      "typeVersion": 1
    },
    {
      "id": "1ad0a222-37d2-4529-baf7-46fdcf31a704",
      "name": "Extraire les Détails des Dépendances",
      "type": "n8n-nodes-base.function",
      "position": [
        -80,
        -144
      ],
      "parameters": {
        "functionCode": "const items = [];\n\nfor (const item of $input.all()) {\n  const issue = item.json;\n  const issueKey = issue.key;\n  const summary = issue.fields.summary;\n  const dueDate = issue.fields.duedate || 'No due date';\n  const assignee = issue.fields.assignee?.displayName || 'Unassigned';\n  const assigneeEmail = issue.fields.assignee?.emailAddress || '';\n  const issueLinks = issue.fields.issuelinks || [];\n  \n  // Process each issue link\n  for (const link of issueLinks) {\n    const linkTypeName = link.type.name;\n    let dependencyType = '';\n    let linkedIssueKey = '';\n    let linkedIssueSummary = '';\n    let linkedIssueStatus = '';\n    let linkedIssuePriority = '';\n    \n    // Check if this issue is blocked by another issue (inwardIssue)\n    if (link.inwardIssue) {\n      dependencyType = link.type.inward; // \"is blocked by\"\n      linkedIssueKey = link.inwardIssue.key;\n      linkedIssueSummary = link.inwardIssue.fields?.summary || '';\n      linkedIssueStatus = link.inwardIssue.fields?.status?.name || '';\n      linkedIssuePriority = link.inwardIssue.fields?.priority?.name || '';\n    }\n    // Check if this issue blocks another issue (outwardIssue)\n    else if (link.outwardIssue) {\n      dependencyType = link.type.outward; // \"blocks\"\n      linkedIssueKey = link.outwardIssue.key;\n      linkedIssueSummary = link.outwardIssue.fields?.summary || '';\n      linkedIssueStatus = link.outwardIssue.fields?.status?.name || '';\n      linkedIssuePriority = link.outwardIssue.fields?.priority?.name || '';\n    }\n    \n    // Only add items where we found a linked issue\n    if (linkedIssueKey) {\n      items.push({\n        json: {\n          issueKey,\n          summary,\n          dueDate,\n          assignee,\n          assigneeEmail,\n          linkType: linkTypeName,\n          dependencyType,\n          linkedIssueKey,\n          linkedIssueSummary,\n          linkedIssueStatus,\n          linkedIssuePriority\n        }\n      });\n    }\n  }\n}\n\nreturn items;"
      },
      "typeVersion": 1
    },
    {
      "id": "094d3001-f935-493a-b59e-bef2d0ca431e",
      "name": "Note - Extraction",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        32
      ],
      "parameters": {
        "width": 262,
        "height": 274,
        "content": "## 🔗 Extract Dependencies\n\nParses issue links to identify blocking relationships.\n\n**Extracts:**\n- Blocker/blocked relationships\n- Linked issue details\n- Status and priority info\n- Assignee contact details"
      },
      "typeVersion": 1
    },
    {
      "id": "03f0b995-e4d5-45d4-90ec-fd987ae34833",
      "name": "Calculer le Score d'Impact",
      "type": "n8n-nodes-base.function",
      "position": [
        144,
        -48
      ],
      "parameters": {
        "functionCode": "const items = [];\n\nfor (const item of $input.all()) {\n  const jiraData = item.json;\n  const issueKey = jiraData.issueKey;\n  const dueDate = jiraData.dueDate;\n  const linkedIssueKey = jiraData.linkedIssueKey;\n  \n  let daysTillDue = 999;\n  let riskFlag = 'Low';\n  \n  if (dueDate && dueDate !== 'No due date') {\n    const today = new Date();\n    const due = new Date(dueDate);\n    daysTillDue = Math.ceil((due - today) / (1000 * 60 * 60 * 24));\n    \n    if (daysTillDue < 7) {\n      riskFlag = 'High';\n    } else if (daysTillDue < 14) {\n      riskFlag = 'Medium';\n    }\n  }\n  \n  const blockerCount = jiraData.dependencyType === 'is blocked by' ? 1 : 0.5;\n  const impactScore = Math.round(blockerCount * Math.max(1, 30 - daysTillDue));\n  \n  items.push({\n    json: {\n      ...jiraData,\n      daysTillDue,\n      riskFlag,\n      impactScore\n    }\n  });\n}\n\nreturn items;"
      },
      "typeVersion": 1
    },
    {
      "id": "5b2ad399-43f0-43dd-a248-312191e77080",
      "name": "Note - Calcul",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        144,
        96
      ],
      "parameters": {
        "width": 262,
        "height": 285,
        "content": "## 📊 Risk Calculation\n\nCalculates impact scores based on urgency and dependency type.\n\n**Risk Levels:**\n- **High:** < 7 days to due date\n- **Medium:** 7-14 days\n- **Low:** > 14 days\n\n**Impact Score:** Weighted by blocker type and time remaining"
      },
      "typeVersion": 1
    },
    {
      "id": "11f3c704-bca8-4273-9a2d-bb6cf551f47d",
      "name": "Créer un Élément Monday.com",
      "type": "n8n-nodes-base.mondayCom",
      "position": [
        144,
        -240
      ],
      "parameters": {
        "name": "={{ $json.summary }}",
        "boardId": "YOUR_BOARD_ID",
        "groupId": "topics",
        "resource": "boardItem",
        "additionalFields": {}
      },
      "credentials": {
        "mondayComApi": {
          "id": "Kxmnf2TltEtJLxDA",
          "name": "Monday.com account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "3bc54dd5-633e-4669-b8de-48bb5f93a848",
      "name": "Note - Monday",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -16,
        -512
      ],
      "parameters": {
        "width": 262,
        "height": 258,
        "content": "## 📋 Monday.com Sync\n\n**Setup Required:**\n1. Replace `YOUR_BOARD_ID` with your board ID\n2. Update `groupId` if needed\n3. Connect Monday.com credentials\n\n**Creates:** New items for each dependency issue"
      },
      "typeVersion": 1
    },
    {
      "id": "791ada1e-1556-4972-9cb5-fbd473f8abaa",
      "name": "Note - Format d'E-mail",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        320,
        -528
      ],
      "parameters": {
        "width": 262,
        "height": 285,
        "content": "## 📧 Email Formatter\n\nGenerates beautiful HTML email reports with:\n- Summary statistics\n- Blocking issues table\n- Blocked issues table\n- Color-coded risk indicators\n\n**No configuration needed** - automatically formats data"
      },
      "typeVersion": 1
    },
    {
      "id": "e3f85e5e-2552-4ffc-a05b-e204e65955d1",
      "name": "Envoyer un Rapport par E-mail",
      "type": "n8n-nodes-base.gmail",
      "position": [
        592,
        -240
      ],
      "webhookId": "cbf02576-4560-431f-831c-885fdd29da1d",
      "parameters": {
        "sendTo": "YOUR_EMAIL@example.com",
        "message": "={{ $json.html }}",
        "options": {},
        "subject": "={{ $json.subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "70f5n8rPahCANHs7",
          "name": "jyothi"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "ac63b00c-f50e-4a7d-a7c1-b3f2a42c7733",
      "name": "Note - Gmail",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        656,
        -496
      ],
      "parameters": {
        "width": 262,
        "height": 285,
        "content": "## 📬 Gmail Sender\n\n**Setup Required:**\n1. Replace `YOUR_EMAIL@example.com` with recipient email\n2. Connect Gmail OAuth2 credentials\n3. Grant necessary permissions\n\n**Sends:** Formatted HTML report to stakeholders"
      },
      "typeVersion": 1
    },
    {
      "id": "cd553b4f-2e1b-42c8-9db2-13ccc0c5b2ed",
      "name": "Créer une Tâche de Coordination",
      "type": "n8n-nodes-base.jira",
      "position": [
        368,
        -48
      ],
      "parameters": {
        "project": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_PROJECT_ID",
          "cachedResultName": "Coordination Project"
        },
        "summary": "=Dependency Coordination: {{ $json.issueKey }} → {{ $json.linkedIssueKey }}",
        "issueType": {
          "__rl": true,
          "mode": "list",
          "value": "10006",
          "cachedResultName": "Task"
        },
        "additionalFields": {
          "description": "=Impact Score: {{ $json.impactScore }}\\nRisk Level: {{ $json.riskFlag }}\\nDays Till Due: {{ $json.daysTillDue }}\\n\\nSource Issue: {{ $json.issueKey }} - {{ $json.summary }}\\nBlocked By: {{ $json.linkedIssueKey }} - {{ $json.linkedIssueSummary }}\\n\\nAction Required: Coordinate with dependency owner to resolve blocker."
        }
      },
      "credentials": {
        "jiraSoftwareCloudApi": {
          "id": "AnaUUmFzt0vUQADt",
          "name": "jyothi"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "75ed5b66-ec43-43d0-954d-cc5a4dfbea02",
      "name": "Note - Coordination",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        512,
        -80
      ],
      "parameters": {
        "width": 262,
        "height": 285,
        "content": "## 📝 Create Jira Task\n\n**Setup Required:**\n1. Replace `YOUR_PROJECT_ID` with coordination project ID\n2. Update issue type if needed\n3. Uses same Jira credentials\n\n**Creates:** Coordination tasks with risk details"
      },
      "typeVersion": 1
    },
    {
      "id": "27003e76-5b0b-4ff5-928a-9d3d9a062c1f",
      "name": "Publier sur Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        368,
        160
      ],
      "webhookId": "d9341fdd-659e-41b0-b494-74870fb11494",
      "parameters": {
        "text": "=*Dependency Radar Alert*\n\n{{ $json.riskFlag === 'High' ? '🔴' : ($json.riskFlag === 'Medium' ? '🟠' : '🟢') }} *{{ $json.issueKey }}* is {{ $json.dependencyType }} *{{ $json.linkedIssueKey }}*\n\n*Impact Score:* {{ $json.impactScore }}\n*Days Till Due:* {{ $json.daysTillDue }}\n*Risk Level:* {{ $json.riskFlag }}\n\nCoordination task created in Jira.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_CHANNEL_ID",
          "cachedResultName": "project-alerts"
        },
        "otherOptions": {}
      },
      "typeVersion": 2
    },
    {
      "id": "350fe417-1e8b-4451-9228-a64087d75a61",
      "name": "Note - Slack",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        480,
        272
      ],
      "parameters": {
        "width": 262,
        "height": 285,
        "content": "## 💬 Slack Alerts\n\n**Setup Required:**\n1. Replace `YOUR_CHANNEL_ID` with channel ID\n2. Connect Slack API credentials\n3. Ensure bot has channel permissions\n\n**Posts:** Real-time alerts with emoji indicators"
      },
      "typeVersion": 1
    },
    {
      "id": "27dcf4a8-02ad-4ee5-b599-0675c696e34e",
      "name": "Récupérer les Problèmes Jira Ouverts",
      "type": "n8n-nodes-base.jira",
      "position": [
        -528,
        -144
      ],
      "parameters": {
        "options": {
          "jql": "project = YOUR_PROJECT_KEY AND statusCategory != Done"
        },
        "operation": "getAll",
        "returnAll": true
      },
      "credentials": {
        "jiraSoftwareCloudApi": {
          "id": "AnaUUmFzt0vUQADt",
          "name": "jyothi"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "0914ca57-8aeb-474b-bb51-473854353e4f",
      "name": "Formateur d'E-mail",
      "type": "n8n-nodes-base.code",
      "position": [
        368,
        -240
      ],
      "parameters": {
        "jsCode": "// HTML Email Formatter for Dependency Risk Report\nlet data;\n\nif ($input.all().length > 0 && Array.isArray($input.all()[0].json)) {\n  data = $input.all()[0].json;\n} else if ($input.all().length > 0 && $input.all()[0].json.data) {\n  data = $input.all()[0].json.data;\n} else if (Array.isArray($input.all())) {\n  data = $input.all().map(item => item.json);\n} else {\n  data = $input.all();\n}\n\nif (!Array.isArray(data)) {\n  data = [data];\n}\n\nfunction generateHTMLEmail(data) {\n  const today = new Date().toLocaleDateString('en-US', { \n    year: 'numeric', \n    month: 'long', \n    day: 'numeric' \n  });\n  \n  const blockingIssues = data.filter(item => item.dependencyType === 'blocks');\n  const blockedIssues = data.filter(item => item.dependencyType === 'is blocked by');\n  \n  const blockingRows = blockingIssues.map(item => `\n    <tr>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb;\">\n        <strong style=\"color: #1f2937;\">${item.issueKey}</strong>\n      </td>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb;\">${item.summary}</td>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb;\">${item.assignee}</td>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb; text-align: center;\">\n        ${item.dueDate !== 'No due date' ? item.dueDate : '<span style=\"color: #6b7280;\">-</span>'}\n      </td>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb; text-align: center;\">\n        ${item.daysTillDue !== 999 ? `<span style=\"color: ${item.daysTillDue <= 2 ? '#dc2626' : '#f59e0b'}; font-weight: 600;\">${item.daysTillDue} days</span>` : '<span style=\"color: #6b7280;\">-</span>'}\n      </td>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb;\">\n        <strong>${item.linkedIssueKey}</strong><br/>\n        <span style=\"color: #6b7280; font-size: 13px;\">${item.linkedIssueSummary}</span>\n      </td>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb; text-align: center;\">\n        <span style=\"padding: 4px 8px; border-radius: 4px; font-size: 12px; font-weight: 600; background-color: ${item.riskFlag === 'High' ? '#fee2e2' : '#fef3c7'}; color: ${item.riskFlag === 'High' ? '#dc2626' : '#f59e0b'};\">\n          ${item.riskFlag}\n        </span>\n      </td>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb; text-align: center;\">\n        <span style=\"font-weight: 600; color: ${item.impactScore >= 20 ? '#dc2626' : '#f59e0b'};\">${item.impactScore}</span>\n      </td>\n    </tr>\n  `).join('');\n  \n  const blockedRows = blockedIssues.map(item => `\n    <tr>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb;\">\n        <strong style=\"color: #1f2937;\">${item.issueKey}</strong>\n      </td>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb;\">${item.summary}</td>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb;\">${item.assignee}</td>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb; text-align: center;\">\n        ${item.dueDate !== 'No due date' ? item.dueDate : '<span style=\"color: #6b7280;\">-</span>'}\n      </td>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb; text-align: center;\">\n        ${item.daysTillDue !== 999 ? `<span style=\"color: ${item.daysTillDue <= 2 ? '#dc2626' : '#f59e0b'}; font-weight: 600;\">${item.daysTillDue} days</span>` : '<span style=\"color: #6b7280;\">-</span>'}\n      </td>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb;\">\n        <strong>${item.linkedIssueKey}</strong><br/>\n        <span style=\"color: #6b7280; font-size: 13px;\">${item.linkedIssueSummary}</span>\n      </td>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb; text-align: center;\">\n        <span style=\"padding: 4px 8px; border-radius: 4px; font-size: 12px; font-weight: 600; background-color: ${item.riskFlag === 'High' ? '#fee2e2' : '#fef3c7'}; color: ${item.riskFlag === 'High' ? '#dc2626' : '#f59e0b'};\">\n          ${item.riskFlag}\n        </span>\n      </td>\n      <td style=\"padding: 12px; border-bottom: 1px solid #e5e7eb; text-align: center;\">\n        <span style=\"font-weight: 600; color: ${item.impactScore >= 20 ? '#dc2626' : '#f59e0b'};\">${item.impactScore}</span>\n      </td>\n    </tr>\n  `).join('');\n  \n  const htmlEmail = `\n<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Issue Dependency Risk Report</title>\n</head>\n<body style=\"margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #f3f4f6;\">\n  <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color: #f3f4f6; padding: 20px;\">\n    <tr>\n      <td align=\"center\">\n        <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"max-width: 1200px; background-color: #ffffff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\">\n          <tr>\n            <td style=\"background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 30px; border-radius: 8px 8px 0 0;\">\n              <h1 style=\"margin: 0; color: #ffffff; font-size: 28px; font-weight: 700;\">🚨 Issue Dependency Risk Report</h1>\n              <p style=\"margin: 8px 0 0 0; color: #e0e7ff; font-size: 14px;\">Generated on ${today}</p>\n            </td>\n          </tr>\n          <tr>\n            <td style=\"padding: 30px;\">\n              <div style=\"background-color: #fef3c7; border-left: 4px solid #f59e0b; padding: 16px; border-radius: 4px; margin-bottom: 24px;\">\n                <p style=\"margin: 0; color: #92400e; font-size: 14px; line-height: 1.6;\"><strong>⚠️ Attention Required:</strong> This report identifies critical dependencies that may impact project timelines.</p>\n              </div>\n              <div style=\"display: flex; gap: 16px; margin-bottom: 30px;\">\n                <div style=\"flex: 1; background-color: #fef2f2; padding: 20px; border-radius: 8px; border: 1px solid #fecaca;\">\n                  <div style=\"font-size: 32px; font-weight: 700; color: #dc2626; margin-bottom: 4px;\">${blockingIssues.length}</div>\n                  <div style=\"color: #991b1b; font-size: 14px; font-weight: 500;\">Blocking Issues</div>\n                </div>\n                <div style=\"flex: 1; background-color: #fef3c7; padding: 20px; border-radius: 8px; border: 1px solid #fde68a;\">\n                  <div style=\"font-size: 32px; font-weight: 700; color: #f59e0b; margin-bottom: 4px;\">${blockedIssues.length}</div>\n                  <div style=\"color: #92400e; font-size: 14px; font-weight: 500;\">Blocked Issues</div>\n                </div>\n                <div style=\"flex: 1; background-color: #fee2e2; padding: 20px; border-radius: 8px; border: 1px solid #fecaca;\">\n                  <div style=\"font-size: 32px; font-weight: 700; color: #dc2626; margin-bottom: 4px;\">${data.filter(i => i.riskFlag === 'High').length}</div>\n                  <div style=\"color: #991b1b; font-size: 14px; font-weight: 500;\">High Risk Items</div>\n                </div>\n              </div>\n              <h2 style=\"color: #1f2937; font-size: 20px; margin: 0 0 16px 0; padding-bottom: 8px; border-bottom: 2px solid #e5e7eb;\">🔴 Issues Blocking Others</h2>\n              <div style=\"overflow-x: auto; margin-bottom: 32px;\">\n                <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"border-collapse: collapse; border: 1px solid #e5e7eb; border-radius: 6px; overflow: hidden;\">\n                  <thead>\n                    <tr style=\"background-color: #f9fafb;\">\n                      <th style=\"padding: 12px; text-align: left; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Issue Key</th>\n                      <th style=\"padding: 12px; text-align: left; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Summary</th>\n                      <th style=\"padding: 12px; text-align: left; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Assignee</th>\n                      <th style=\"padding: 12px; text-align: center; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Due Date</th>\n                      <th style=\"padding: 12px; text-align: center; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Days Left</th>\n                      <th style=\"padding: 12px; text-align: left; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Blocking</th>\n                      <th style=\"padding: 12px; text-align: center; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Risk</th>\n                      <th style=\"padding: 12px; text-align: center; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Impact</th>\n                    </tr>\n                  </thead>\n                  <tbody style=\"background-color: #ffffff;\">\n                    ${blockingRows || '<tr><td colspan=\"8\" style=\"padding: 20px; text-align: center; color: #6b7280;\">No blocking issues found</td></tr>'}\n                  </tbody>\n                </table>\n              </div>\n              <h2 style=\"color: #1f2937; font-size: 20px; margin: 0 0 16px 0; padding-bottom: 8px; border-bottom: 2px solid #e5e7eb;\">🔒 Issues Being Blocked</h2>\n              <div style=\"overflow-x: auto;\">\n                <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"border-collapse: collapse; border: 1px solid #e5e7eb; border-radius: 6px; overflow: hidden;\">\n                  <thead>\n                    <tr style=\"background-color: #f9fafb;\">\n                      <th style=\"padding: 12px; text-align: left; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Issue Key</th>\n                      <th style=\"padding: 12px; text-align: left; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Summary</th>\n                      <th style=\"padding: 12px; text-align: left; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Assignee</th>\n                      <th style=\"padding: 12px; text-align: center; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Due Date</th>\n                      <th style=\"padding: 12px; text-align: center; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Days Left</th>\n                      <th style=\"padding: 12px; text-align: left; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Blocked By</th>\n                      <th style=\"padding: 12px; text-align: center; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Risk</th>\n                      <th style=\"padding: 12px; text-align: center; font-size: 13px; font-weight: 600; color: #374151; border-bottom: 2px solid #e5e7eb;\">Impact</th>\n                    </tr>\n                  </thead>\n                  <tbody style=\"background-color: #ffffff;\">\n                    ${blockedRows || '<tr><td colspan=\"8\" style=\"padding: 20px; text-align: center; color: #6b7280;\">No blocked issues found</td></tr>'}\n                  </tbody>\n                </table>\n              </div>\n            </td>\n          </tr>\n          <tr>\n            <td style=\"background-color: #f9fafb; padding: 20px; border-radius: 0 0 8px 8px; border-top: 1px solid #e5e7eb;\">\n              <p style=\"margin: 0; color: #6b7280; font-size: 13px; text-align: center;\">This is an automated report generated by n8n workflow.</p>\n              <p style=\"margin: 8px 0 0 0; color: #6b7280; font-size: 12px; text-align: center;\">© 2025 Project Management System</p>\n            </td>\n          </tr>\n        </table>\n      </td>\n    </tr>\n  </table>\n</body>\n</html>\n  `;\n  \n  return htmlEmail;\n}\n\nconst htmlContent = generateHTMLEmail(data);\n\nreturn [{\n  json: {\n    html: htmlContent,\n    subject: `🚨 Issue Dependency Risk Report - ${new Date().toLocaleDateString()}`,\n    text: `Issue Dependency Risk Report generated on ${new Date().toLocaleDateString()}`\n  }\n}];"
      },
      "typeVersion": 2
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "f9fd04b0-abca-463d-ad7d-9666c73d3c22",
  "connections": {
    "0914ca57-8aeb-474b-bb51-473854353e4f": {
      "main": [
        [
          {
            "node": "e3f85e5e-2552-4ffc-a05b-e204e65955d1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6d07db03-aa56-43ec-bad8-ba089d2b973a": {
      "main": [
        [
          {
            "node": "1ad0a222-37d2-4529-baf7-46fdcf31a704",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "03f0b995-e4d5-45d4-90ec-fd987ae34833": {
      "main": [
        [
          {
            "node": "cd553b4f-2e1b-42c8-9db2-13ccc0c5b2ed",
            "type": "main",
            "index": 0
          },
          {
            "node": "0914ca57-8aeb-474b-bb51-473854353e4f",
            "type": "main",
            "index": 0
          },
          {
            "node": "27003e76-5b0b-4ff5-928a-9d3d9a062c1f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "185308d0-69ba-44f1-bdbe-a93ce06a5209": {
      "main": [
        [
          {
            "node": "27dcf4a8-02ad-4ee5-b599-0675c696e34e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "27dcf4a8-02ad-4ee5-b599-0675c696e34e": {
      "main": [
        [
          {
            "node": "6d07db03-aa56-43ec-bad8-ba089d2b973a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1ad0a222-37d2-4529-baf7-46fdcf31a704": {
      "main": [
        [
          {
            "node": "03f0b995-e4d5-45d4-90ec-fd987ae34833",
            "type": "main",
            "index": 0
          },
          {
            "node": "11f3c704-bca8-4273-9a2d-bb6cf551f47d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Avancé

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds21
Catégorie-
Types de nœuds9
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Auteur
Rahul Joshi

Rahul Joshi

@rahul08

Rahul Joshi is a seasoned technology leader specializing in the n8n automation tool and AI-driven workflow automation. With deep expertise in building open-source workflow automation and self-hosted automation platforms, he helps organizations eliminate manual processes through intelligent n8n ai agent automation solutions.

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34