AutomationFlowsAI & RAG › Escalate Product Uat Critical Bugs with Openai, Jira and Slack

Escalate Product Uat Critical Bugs with Openai, Jira and Slack

ByYassin Zehar @yassinzehar on n8n.io

Automatically detect and escalate Product UAT critical bugs using AI, create Jira issues, notify engineering teams, and close the feedback loop with testers.

Webhook trigger★★★★☆ complexityAI-powered19 nodesJiraSlackGmailOpenAI
AI & RAG Trigger: Webhook Nodes: 19 Complexity: ★★★★☆ AI nodes: yes Added:
Escalate Product Uat Critical Bugs with Openai, Jira and Slack — n8n workflow card showing Jira, Slack, Gmail integration

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

This workflow follows the Gmail → OpenAI 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": "R3ZzYANzMk10U0m8",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Product UAT Critical Bug Escalation (AI \u2192 Jira + Slack)",
  "tags": [
    {
      "id": "bX1tZbypCr5HBJMz",
      "name": "product management",
      "createdAt": "2025-11-20T18:06:00.432Z",
      "updatedAt": "2025-11-20T18:06:00.432Z"
    },
    {
      "id": "rYuINsb3Y1XjrgNv",
      "name": "Productivity",
      "createdAt": "2025-08-02T17:36:49.812Z",
      "updatedAt": "2025-08-02T17:36:49.812Z"
    }
  ],
  "nodes": [
    {
      "id": "a720620e-25aa-423c-9f02-f957995b8165",
      "name": "trigger",
      "type": "n8n-nodes-base.webhook",
      "position": [
        496,
        -192
      ],
      "parameters": {
        "path": "3a6c966e-0409-4a8d-9ad9-bbf834689964",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "799e4a87-8d32-47be-8e27-7f79b6e59735",
      "name": "normalize",
      "type": "n8n-nodes-base.code",
      "position": [
        880,
        0
      ],
      "parameters": {
        "jsCode": "const input = $json || {};\n\nconst source = input.source || input.uat?.source || \"webhook\";\nconst testerName = input.tester_name || input.tester?.name || input.uat?.tester_name || \"\";\nconst testerEmail = input.tester_email || input.tester?.email || input.uat?.tester_email || \"\";\nconst messageRaw = input.message || input.text || input.feedback || input.uat?.message_raw || \"\";\nconst buildVersion = input.build_version || input.uat?.build_version || \"unknown\";\nconst pageUrl = input.page_url || input.uat?.page_url || \"\";\nconst screenshotUrl = input.screenshot_url || input.uat?.screenshot_url || \"\";\n\nreturn {\n  uat: {\n    source,\n    tester_name: testerName,\n    tester_email: testerEmail,\n    message_raw: messageRaw,\n    build_version: buildVersion,\n    page_url: pageUrl,\n    screenshot_url: screenshotUrl,\n    received_at: new Date().toISOString(),\n  },\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "eca4998b-7324-4430-8268-e02de600d82a",
      "name": "parsing and validation",
      "type": "n8n-nodes-base.code",
      "position": [
        1600,
        0
      ],
      "parameters": {
        "jsCode": "// Try multiple possible fields depending on node output\nconst raw =\n  $json.output ||\n  $json.text ||\n  $json.message ||\n  ($json.response?.text) ||\n  ($json.data?.[0]?.content) ||\n  ($json.response?.[0]?.message?.content) ||\n\n  \"\";\n\nlet triage;\nlet parseOk = true;\n\ntry {\n  triage = JSON.parse(raw);\n} catch (e) {\n  parseOk = false;\n  triage = {\n    sentiment: \"Negative\",\n    type: \"Noise\",\n    severity: \"Minor\",\n    summary: \"AI response could not be parsed as JSON.\",\n    components: [\"other\"],\n    repro_steps: [],\n    suggested_title: \"UAT feedback (manual triage)\",\n    confidence: 0,\n  };\n}\n\n// Normalize + validate\nconst allowedType = [\"CriticalBug\", \"UXImprovement\", \"FeatureRequest\", \"Noise\"];\nif (!allowedType.includes(triage.type)) triage.type = \"Noise\";\n\nconst allowedSeverity = [\"Blocker\", \"Critical\", \"Major\", \"Minor\"];\nif (!allowedSeverity.includes(triage.severity)) triage.severity = \"Minor\";\n\nconst allowedSentiment = [\"Positive\", \"Negative\"];\nif (!allowedSentiment.includes(triage.sentiment)) triage.sentiment = \"Negative\";\n\ntriage.confidence = Math.max(0, Math.min(1, Number(triage.confidence ?? 0)));\n\nreturn {\n  ...$json,\n  triage: {\n    ...triage,\n    parse_ok: parseOk,\n  },\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "a89c57b4-7479-4a27-a71d-07f053ff04c2",
      "name": "critical bug",
      "type": "n8n-nodes-base.jira",
      "position": [
        1824,
        0
      ],
      "parameters": {
        "project": {
          "__rl": true,
          "mode": "list",
          "value": "10002",
          "cachedResultName": "test2"
        },
        "summary": "= {{ $json.triage.suggested_title || $json.triage.summary }}",
        "issueType": {
          "__rl": true,
          "mode": "list",
          "value": "10013",
          "cachedResultName": "Bug"
        },
        "additionalFields": {
          "priority": {
            "__rl": true,
            "mode": "list",
            "value": "2",
            "cachedResultName": "High"
          },
          "description": "=Build: {{ $json.uat.build_version }}\nPage: {{ $json.uat.page_url }}\nScreenshot: {{ $json.uat.screenshot_url }}\n\nRepro steps:\n{{ ($json.triage.repro_steps || []).join(\"\\n\") }}\n\nReporter:\n{{ $json.uat.tester_name }} - {{ $json.uat.tester_email }}\nSource: {{ $json.uat.source }}"
        }
      },
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e38ee892-a1c0-4570-b463-877ce34291ed",
      "name": "engeneering alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        2032,
        0
      ],
      "parameters": {
        "text": "=\ud83d\udea8 UAT Critical Bug ({{ $json.triage.severity }}) \u2022 {{ $json.triage.summary }} \u2022 Build: {{ $json.uat.build_version }} \u2022 Component: {{ ($json.triage.components || []).join(\", \") }} \u2022 Jira: {{ $json.key || $json.id }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09V1228324",
          "cachedResultName": "tous-n8n"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "c90dd414-4659-4421-8da0-a5f01892972a",
      "name": "tester email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2800,
        80
      ],
      "parameters": {
        "sendTo": "={{ $json.uat.tester_email }}",
        "message": "={{ $json.reply.body }}",
        "options": {},
        "subject": "={{ $json.reply.subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "42e9bcbf-a50b-4227-95c9-c063524a0b06",
      "name": "slack tester",
      "type": "n8n-nodes-base.slack",
      "position": [
        2800,
        -128
      ],
      "parameters": {
        "text": "={{ $json.reply.body }}",
        "user": {
          "__rl": true,
          "mode": "list",
          "value": "U09UKKK9R25",
          "cachedResultName": "analyticsn8n"
        },
        "select": "user",
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "f889f02d-3cc4-43ef-814f-3c566df54b19",
      "name": "clean text",
      "type": "n8n-nodes-base.code",
      "position": [
        1040,
        0
      ],
      "parameters": {
        "jsCode": "const msg = $json.uat?.message_raw || \"\";\n\nconst cleaned = msg\n  .replace(/<[^>]*>/g, \" \")\n  .replace(/\\s+/g, \" \")\n  .trim()\n  .slice(0, 3000);\n\nreturn {\n  ...$json,\n  uat: {\n    ...$json.uat,\n    message_clean: cleaned,\n  },\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "9960d6de-2665-47e0-a958-966e969cc1c7",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -48,
        -752
      ],
      "parameters": {
        "width": 400,
        "height": 1328,
        "content": "## How it works\n\nThis workflow automates Product UAT critical bug escalation using AI.\n\nWhen a tester submits feedback via a webhook, the workflow normalizes and cleans the input before sending it to an AI model. The AI classifies the feedback, evaluates severity, and generates a structured summary with a confidence score.\n\nValidated critical bugs automatically create a Jira issue, trigger an engineering Slack alert, and notify the tester via Slack or email.\nThe workflow then responds to the original webhook with a structured status payload, ensuring full traceability and fast feedback loops."
      },
      "typeVersion": 1
    },
    {
      "id": "a23dfd66-5b76-43de-8e15-96a1f6dda5df",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        -752
      ],
      "parameters": {
        "color": 7,
        "width": 768,
        "height": 1328,
        "content": "## Ingestion & Normalization\n\nCollects UAT feedback from a webhook and normalizes all inputs\n(tester, source, build, page, message) into a clean, AI-ready data structure."
      },
      "typeVersion": 1
    },
    {
      "id": "3be2ae4d-b1a0-4fa6-8969-e7397427ad76",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1184,
        -752
      ],
      "parameters": {
        "color": 7,
        "width": 576,
        "height": 1328,
        "content": "## AI Triage & Quality Control\n\nAn AI model analyzes the feedback and returns a structured triage\n(type, severity, summary, confidence), which is parsed and validated before execution."
      },
      "typeVersion": 1
    },
    {
      "id": "4d1479c8-74ed-4707-a6a1-d4d8d7f0277e",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1792,
        -752
      ],
      "parameters": {
        "color": 7,
        "width": 624,
        "height": 1328,
        "content": "## Critical Bug Escalation\n\nValidated critical bugs automatically create a Jira issue\nand trigger an engineering Slack alert with full context."
      },
      "typeVersion": 1
    },
    {
      "id": "c3c5b21f-0f6b-4159-a741-3ac30b36edda",
      "name": "Webhook response",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        2976,
        -32
      ],
      "parameters": {
        "options": {
          "responseKey": "={   \"status\": \"received\",   \"type\": \"{{ $json.triage.type }}\",   \"severity\": \"{{ $json.triage.severity }}\",   \"confidence\": \"{{ $json.triage.confidence }}\" }",
          "responseCode": 200
        },
        "respondWith": "allIncomingItems"
      },
      "typeVersion": 1.4
    },
    {
      "id": "0bdf87b2-2e98-4a19-a8ed-0af895be33ca",
      "name": "how to contact",
      "type": "n8n-nodes-base.if",
      "position": [
        2496,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "8433c8f3-bdaf-4c64-af3c-7c091e51b8cc",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.uat.source }}",
              "rightValue": "slack"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "99285181-4c7d-4d20-bece-0f066f5b40e5",
      "name": "compose reply branch 1",
      "type": "n8n-nodes-base.set",
      "position": [
        2256,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "9945be1d-27e1-4029-98f6-f19b04ae96a0",
              "name": "reply.subject",
              "type": "string",
              "value": "=UAT feedback received \u2014 Ticket {{ $json.key || $json.id }}"
            },
            {
              "id": "11a2ea6f-a0ab-43c7-9192-b43521667209",
              "name": "reply.body",
              "type": "string",
              "value": "=Thanks for your feedback!\n\nWe logged it as a Critical Bug ({{ $json.triage.severity }}).\nTicket: {{ $json.key || $json.id }}\n\nSummary: {{ $json.triage.summary }}\nBuild: {{ $json.uat.build_version }}\n\nWe\u2019ll keep you posted.\n"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "f86ce651-83a4-4983-bd0d-10a5c15d9efd",
      "name": "AI agent",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1296,
        0
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5.2",
          "cachedResultName": "GPT-5.2"
        },
        "options": {},
        "responses": {
          "values": [
            {
              "content": "=Analyze this UAT feedback and return ONLY JSON.\n\nContext:\n- build_version: {{ $json.uat.build_version }}\n- page_url: {{ $json.uat.page_url }}\n- screenshot_url: {{ $json.uat.screenshot_url }}\n\nFeedback:\n{{ $json.uat.message_clean }}\n\nJSON schema (strict):\n{\n  \"sentiment\": \"Positive|Negative\",\n  \"type\": \"CriticalBug|UXImprovement|FeatureRequest|Noise\",\n  \"severity\": \"Blocker|Critical|Major|Minor\",\n  \"summary\": \"string (max 160 chars)\",\n  \"components\": [\"string\"],\n  \"repro_steps\": [\"string\"],\n  \"suggested_title\": \"string (max 80 chars)\",\n  \"confidence\": 0.0\n}\n\nRules:\n- If the user reports something broken, crash, data loss, payment failure, login failure => type=CriticalBug and severity at least Critical.\n- If unclear or not actionable => type=Noise, confidence <= 0.5\n- repro_steps should be empty array if not inferable.\n- components: choose from [login, onboarding, checkout, search, profile, settings, performance, ui, api, other].\n"
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "659fd4a4-c0c4-4f7e-95d5-0cb305a94d20",
      "name": "data merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        704,
        0
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "91b87775-ed61-4ca9-a07b-df7f93ac017b",
      "name": "data mapping",
      "type": "n8n-nodes-base.set",
      "position": [
        496,
        192
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0346a94c-9b3c-4317-8085-ea2505521edf",
              "name": "cfg.jiraProjectKey",
              "type": "string",
              "value": "UAT"
            },
            {
              "id": "caf9cd84-2d85-4faa-bd7b-c7e240bf6c7f",
              "name": "cfg.jiraIssueTypeBug",
              "type": "string",
              "value": "Bug"
            },
            {
              "id": "da76905d-3985-4eae-88da-b705580e38c6",
              "name": "cfg.slackChannelEng",
              "type": "string",
              "value": "#eng-uat"
            },
            {
              "id": "c96cb9ed-66db-463d-a7a8-145d1cc3c9d9",
              "name": "cfg.slackChannelPm",
              "type": "string",
              "value": "#product-uat"
            },
            {
              "id": "1c3b1959-e21a-487e-b121-3662b8914819",
              "name": "cfg.sheetIdDigest",
              "type": "string",
              "value": "YourID"
            },
            {
              "id": "059b436b-a29b-4991-a72e-c8bd4b844722",
              "name": "cfg.manualReviewEmail",
              "type": "string",
              "value": "user@example.com"
            },
            {
              "id": "25dbf28f-db8a-4a49-9cbf-587276851c61",
              "name": "cfg.confidenceThreshold",
              "type": "number",
              "value": 0.6
            },
            {
              "id": "745af86b-f13d-4ead-a322-ab4e2473e3d6",
              "name": "cfg.dedupeEnabled",
              "type": "boolean",
              "value": false
            },
            {
              "id": "dd5c4b90-2919-4d15-8768-913c9b5ae62e",
              "name": "cfg.llmProvider",
              "type": "string",
              "value": "openai"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "b67fc4f1-6247-4bf3-a30f-eb90da2ab953",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2448,
        -752
      ],
      "parameters": {
        "color": 7,
        "width": 784,
        "height": 1328,
        "content": "## Closed Loop\n\nNotifies the tester via Slack or email\nand responds to the original webhook\nwith a structured status payload."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "4912105a-25bf-4f2d-90ce-dcf659e0303a",
  "connections": {
    "trigger": {
      "main": [
        [
          {
            "node": "data merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI agent": {
      "main": [
        [
          {
            "node": "parsing and validation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "normalize": {
      "main": [
        [
          {
            "node": "clean text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "clean text": {
      "main": [
        [
          {
            "node": "AI agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "data merge": {
      "main": [
        [
          {
            "node": "normalize",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "critical bug": {
      "main": [
        [
          {
            "node": "engeneering alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "data mapping": {
      "main": [
        [
          {
            "node": "data merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "slack tester": {
      "main": [
        [
          {
            "node": "Webhook response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "tester email": {
      "main": [
        [
          {
            "node": "Webhook response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "how to contact": {
      "main": [
        [
          {
            "node": "slack tester",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "tester email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "engeneering alert": {
      "main": [
        [
          {
            "node": "compose reply branch 1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "compose reply branch 1": {
      "main": [
        [
          {
            "node": "how to contact",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "parsing and validation": {
      "main": [
        [
          {
            "node": "critical bug",
            "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

Automatically detect and escalate Product UAT critical bugs using AI, create Jira issues, notify engineering teams, and close the feedback loop with testers.

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

More AI & RAG workflows → · Browse all categories →

Related workflows

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

AI & RAG

Imagine your recruitment process transformed into a sleek, efficient, AI-powered assembly line for talent. That's exactly what this system creates. It automates the heavy lifting, allowing your human

Google Sheets, OpenAI, Gmail +2
AI & RAG

Transform customer feedback into actionable insights automatically with AI analysis, professional PDF reports, personalized emails, and real-time team notifications. Overview Features Demo Prerequisit

OpenAI, Gmail, Google Sheets +2
AI & RAG

This workflow automates the end-to-end process of scheduling technical or behavioral interviews. It captures interview data via Webhook, creates a Google Calendar event with an integrated Google Meet

Google Calendar, OpenAI, Gmail +2
AI & RAG

Transform your webinar registrations from basic form submissions into a verified, personalized, and premium attendee experience.

N8N Nodes Verifiemail, Slack, Stop And Error +4
AI & RAG

Automate your inbound lead qualification pipeline by enriching raw lead data, scoring it with AI, and instantly creating follow-up tasks for your sales team. 🎯🤖 This workflow receives new leads via we

OpenAI, HTTP Request, Asana +3