Classification et reporting de retours pilotés par IA de Monday.com et Jira vers Outlook
Ceci est uncontenant 27 nœuds.Utilise principalement des nœuds comme Set, Code, Jira, Gmail, Merge. Analyser les retours clients de Monday.com et générer des rapports avec Azure GPT-4, Jira et Outlook
- •Compte Google et informations d'identification Gmail API
- •Informations d'identification Google Sheets API
- •Clé API OpenAI
Nœuds utilisés (27)
Catégorie
{
"id": "lgj2XcZly50vMqKU",
"meta": {
"instanceId": "8443f10082278c46aa5cf3acf8ff0f70061a2c58bce76efac814b16290845177",
"templateCredsSetupCompleted": true
},
"name": "AI-Driven Feedback Classification and Reporting from Monday.com and Jira to Outlook",
"tags": [],
"nodes": [
{
"id": "74675c08-9d89-4a2d-a36d-59c167bb42e1",
"name": "Vue d'ensemble du workflow",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2448,
-528
],
"parameters": {
"color": 4,
"width": 450,
"height": 661,
"content": "## 📊 Customer Feedback Intelligence Workflow\n\n**Purpose:** Automatically process customer feedback from Monday.com, analyze with AI, create Jira tasks, and send weekly reports.\n\n**Key Features:**\n- Fetches feedback from Monday.com boards\n- AI-powered sentiment analysis and theme classification\n- Automatic Jira issue creation for product team\n- Google Sheets logging for analytics\n- Weekly HTML email reports via Outlook\n- Error notification system\n\n**Data Flow:**\n1. Fetch feedback from Monday.com\n2. Normalize and structure data\n3. AI analyzes sentiment & categorizes themes\n4. Calculate business impact scores\n5. Create Jira tasks for high-priority items\n6. Log to Google Sheets\n7. Generate and send weekly summary report\n\n**Schedule:** Runs every Monday at 9:00 AM\n\n⚠️ **Setup Required:** Configure credentials for Monday.com, Azure OpenAI, Jira, Google Sheets, and Outlook before running."
},
"typeVersion": 1
},
{
"id": "47e27d91-6cc5-44cd-9374-f4b0c10188b1",
"name": "Configuration : Source de données",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1792,
32
],
"parameters": {
"width": 344,
"height": 259,
"content": "## Step 1: Fetch Feedback Data\n\nRetrieves all customer feedback items from Monday.com board.\n\n**Setup:**\n- Replace `boardId` with your Monday.com board ID\n- Configure Monday.com API credentials\n- Ensure `groupId` matches your board structure"
},
"typeVersion": 1
},
{
"id": "553ce617-8fcc-4f94-a7b1-b5d76ebdd215",
"name": "Récupérer les retours Monday.com",
"type": "n8n-nodes-base.mondayCom",
"position": [
-1648,
-160
],
"parameters": {
"boardId": "YOUR_BOARD_ID",
"groupId": "topics",
"resource": "boardItem",
"operation": "getAll",
"returnAll": true
},
"credentials": {
"mondayComApi": {
"id": "v9QkK1x0MHK2ULvk",
"name": "Monday.com account ch"
}
},
"typeVersion": 1
},
{
"id": "c9de6225-3282-49ca-9db4-8bb10fd80aab",
"name": "Configuration : Normalisation des données",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1552,
-496
],
"parameters": {
"width": 344,
"height": 312,
"content": "## Step 2: Normalize Data\n\nExtracts and standardizes feedback fields into consistent format.\n\n**Fields Mapped:**\n- Title (feedback text)\n- Account Name\n- ARR (Annual Recurring Revenue)\n- NPS Before/After scores\n- Feedback Type\n- Contact Email\n- Submission Date"
},
"typeVersion": 1
},
{
"id": "73233e74-bcb5-47d7-87d1-4848d10e0268",
"name": "Normaliser les champs de retour",
"type": "n8n-nodes-base.set",
"position": [
-1424,
-160
],
"parameters": {
"fields": {
"values": [
{
"name": "Title",
"stringValue": "={{ $json.name }}"
},
{
"name": "Account Name",
"stringValue": "={{ $json.column_values[1].text }}"
},
{
"name": "ARR(USD)",
"stringValue": "={{ $json.column_values[2].text }}"
},
{
"name": "NPS Before",
"stringValue": "={{ $json.column_values[3].text }}"
},
{
"name": "NPS After",
"stringValue": "={{ $json.column_values[4].text }}"
},
{
"name": "FeedBack Type",
"stringValue": "={{ $json.column_values[5].text }}"
},
{
"name": "Contact Email",
"stringValue": "={{ $json.column_values[6].text }}"
},
{
"name": "Submitted On",
"stringValue": "={{ $json.column_values[7].text }}"
}
]
},
"include": "selected",
"options": {}
},
"typeVersion": 3
},
{
"id": "c101c93b-0b00-4734-8247-27f90ef3297f",
"name": "Configuration : Analyse IA",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1120,
-656
],
"parameters": {
"width": 344,
"height": 355,
"content": "## Step 3: AI Theme Classification\n\nUses Azure OpenAI to analyze feedback and extract:\n- Theme category (e.g., \"app-crash\", \"ui-design\")\n- Human-readable label\n- Sentiment (positive/neutral/negative)\n\n**Setup:**\n- Configure Azure OpenAI credentials\n- Model: GPT-4o\n- Returns structured JSON output"
},
"typeVersion": 1
},
{
"id": "cbd79e63-6ef3-4de3-8e93-5d3825865ac0",
"name": "Fusionner les résultats IA avec les retours",
"type": "n8n-nodes-base.merge",
"position": [
-848,
-160
],
"parameters": {
"mode": "combine",
"options": {},
"combinationMode": "mergeByPosition"
},
"typeVersion": 2.1
},
{
"id": "7fa77a1a-b1e4-4c0b-803f-41688c7662ea",
"name": "Configuration : Intégration Jira",
"type": "n8n-nodes-base.stickyNote",
"position": [
-32,
-544
],
"parameters": {
"width": 343.81788385280146,
"height": 308.6359741062274,
"content": "## Step 4: Create Jira Issues\n\nAutomatically creates Jira tasks with:\n- Theme as title\n- Feedback text in description\n- ARR impact and NPS data\n- Sentiment analysis\n- Impact score\n\n**Setup:**\n- Replace `project` ID with your Jira project\n- Configure Jira credentials\n- Customize issue type if needed"
},
"typeVersion": 1
},
{
"id": "22662502-fdce-4ab1-85e5-32196d570fda",
"name": "Créer une tâche Jira pour le retour",
"type": "n8n-nodes-base.jira",
"position": [
-176,
-352
],
"parameters": {
"project": {
"__rl": true,
"mode": "list",
"value": "YOUR_PROJECT_ID",
"cachedResultName": "Your Project Name"
},
"summary": "=Theme: {{$json[\"theme_label\"]}} ({{$json[\"theme_key\"]}})",
"issueType": {
"__rl": true,
"mode": "list",
"value": "10006",
"cachedResultName": "Task"
},
"additionalFields": {
"description": "=💬 Feedback: {{$json[\"feedback\"]}}\n\n💰 ARR Impact: ${{$json[\"arr_usd\"]}}\n😐 Sentiment: {{$json[\"sentiment\"]}}\n📊 NPS Before → {{$json[\"nps_before\"]}} | After → {{$json[\"nps_after\"]}}\n⚡ Impact Score: {{$json[\"impact_score\"]}}\n\nLabels: feedback, {{$json[\"theme_key\"]}}\n"
}
},
"credentials": {
"jiraSoftwareCloudApi": {
"id": "Q6d7sLBVOfGWmaLw",
"name": "Jira SW Cloud account vivek"
}
},
"typeVersion": 1
},
{
"id": "d0084ad1-e8ad-4802-b560-74f997c365cb",
"name": "Configuration : Journalisation des données",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
-208
],
"parameters": {
"width": 343.81788385280146,
"height": 288.6362189310366,
"content": "## Step 5: Log to Google Sheets\n\nAppends processed feedback to Google Sheets for:\n- Long-term analytics\n- Dashboard integration\n- Historical tracking\n\n**Setup:**\n- Replace `documentId` with your Sheet ID\n- Configure Google Sheets OAuth2\n- Ensure sheet has matching columns"
},
"typeVersion": 1
},
{
"id": "f95ddd6f-e581-4a8a-8321-74b50c183ebf",
"name": "Journaliser dans Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
-176,
-160
],
"parameters": {
"columns": {
"mappingMode": "autoMapInputData",
"matchingColumns": [
"theme_key"
]
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultName": "Customer Feedback"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "YOUR_SHEET_ID",
"cachedResultName": "Your Feedback Sheet"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "kpPEOLCGn963qpoh",
"name": "automations@techdome.ai"
}
},
"typeVersion": 4.4
},
{
"id": "2abb077d-0419-4693-a3bf-782d9f0e92b1",
"name": "Configuration : Alertes d'erreur",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2240,
304
],
"parameters": {
"width": 344,
"height": 369,
"content": "## Error Handling\n\nCatches workflow failures and sends email alerts.\n\n**Alert includes:**\n- Workflow name\n- Execution ID\n- Failed node name\n- Error message\n- Timestamp\n\n**Setup:**\n- Set environment variable `ERROR_ALERT_EMAIL`\n- Configure Gmail OAuth2 credentials"
},
"typeVersion": 1
},
{
"id": "1dc8d357-370c-4db4-bf62-c0fc90a03300",
"name": "En cas d'erreur du workflow",
"type": "n8n-nodes-base.errorTrigger",
"position": [
-1872,
464
],
"parameters": {},
"typeVersion": 1
},
{
"id": "022da409-d000-44e8-85a1-21bce519482d",
"name": "Envoyer une alerte par email",
"type": "n8n-nodes-base.gmail",
"position": [
-1648,
464
],
"webhookId": "f19b5216-ea1f-4483-acbd-3d46469a6d5f",
"parameters": {
"sendTo": "={{ $env.ERROR_ALERT_EMAIL }}",
"message": "=Workflow Execution Failed\n\nWorkflow: {{ $workflow.name }}\nExecution ID: {{ $execution.id }}\nFailed Node: {{ $json.node?.name || 'Unknown' }}\nError: {{ $json.error?.message || 'No error message' }}\nTimestamp: {{ $now.toISO() }}",
"options": {},
"subject": "=n8n Workflow Error: {{ $workflow.name }}"
},
"credentials": {
"gmailOAuth2": {
"id": "70f5n8rPahCANHs7",
"name": "jyothi"
}
},
"typeVersion": 2.1
},
{
"id": "a037a368-1d36-4771-993f-7770ce89ba17",
"name": "Déclencheur hebdomadaire",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-1872,
-160
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * 1"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "4018a5de-0860-49f3-8db0-d97bf7bf88c8",
"name": "Configuration : Planification",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1984,
-448
],
"parameters": {
"width": 343.8178838528013,
"height": 280,
"content": "## Trigger: Weekly Schedule\n\nAutomatically runs every Monday at 9:00 AM.\n\n**Cron Expression:** `0 9 * * 1`\n- Minute: 0\n- Hour: 9 (9 AM)\n- Day of Month: * (any)\n- Month: * (any)\n- Day of Week: 1 (Monday)\n\nAdjust the schedule in node settings if needed."
},
"typeVersion": 1
},
{
"id": "640ed7b7-7acf-4a89-9f7f-da1a0747e0c6",
"name": "Analyseur de sortie structurée JSON",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-976,
-16
],
"parameters": {
"jsonSchemaExample": "{\n \"theme_key\": \"\",\n \"theme_label\": \"\",\n \"sentiment\": \"\"\n}"
},
"typeVersion": 1.3
},
{
"id": "b2997445-aefe-4bfa-ad21-7754b2c6d498",
"name": "Classificateur de thèmes par IA",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-1200,
-284
],
"parameters": {
"text": "=Analyze the following customer feedback record and return structured JSON.\n\nFeedback data:\n{{ JSON.stringify($json) }}\n\nReturn JSON in this exact schema:\n{\n \"theme_key\": \"short-keyword-style category (lowercase, kebab-case)\",\n \"theme_label\": \"concise readable label (2-5 words)\",\n \"sentiment\": \"positive | neutral | negative\"\n}\n\nExamples:\nInput: \"App crashes when submitting reports.\"\nOutput: {\"theme_key\":\"app-crash\",\"theme_label\":\"App Stability\",\"sentiment\":\"negative\"}\n\nInput: \"Love the new dashboard design!\"\nOutput: {\"theme_key\":\"ui-design\",\"theme_label\":\"Dashboard Design\",\"sentiment\":\"positive\"}\n\nNow analyze this feedback and respond only with JSON.",
"options": {
"systemMessage": "=You are an intelligent product feedback classifier. \nYour job is to analyze each feedback text and extract structured insights.\n\nFollow these strict rules:\n- Output must be valid JSON only (no markdown, no explanations).\n- Identify the underlying theme or category of the feedback.\n- Create a short, human-readable label for that theme.\n- Detect overall sentiment (positive, neutral, negative).\n- Do not repeat the full feedback text in output."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.7
},
{
"id": "ae2b52c2-9be1-4d8e-9b72-6dcff9b948f4",
"name": "Tampon de mémoire de conversation",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
-1104,
-80
],
"parameters": {
"sessionKey": "=\"feedback_classification_\" + $now.format('yyyy-MM-dd')",
"sessionIdType": "customKey",
"contextWindowLength": 7
},
"typeVersion": 1.3
},
{
"id": "78abb932-8eb0-407f-b059-ed2285778f71",
"name": "Configuration : Structuration des données",
"type": "n8n-nodes-base.stickyNote",
"position": [
-848,
32
],
"parameters": {
"width": 343.81788385280146,
"height": 270.78228621783586,
"content": "## Step 3b: Structure AI Output\n\nConverts AI classification results into clean format:\n- Extracts ARR and NPS values as numbers\n- Combines theme data from AI\n- Preserves original feedback text\n- Prepares data for impact scoring"
},
"typeVersion": 1
},
{
"id": "f90ec364-b556-47f3-8250-e93938a4455b",
"name": "Structurer la sortie de classification IA",
"type": "n8n-nodes-base.set",
"position": [
-624,
-160
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "={\n \"arr_usd\": {{ Number($json['ARR(USD)']) }},\n \"nps_before\": {{ Number($json['NPS Before']) }},\n \"nps_after\": {{ Number($json['NPS After']) }},\n \"theme_key\": \"{{ $json.output.theme_key }}\",\n \"theme_label\": \"{{ $json.output.theme_label }}\",\n \"sentiment\": \"{{ $json.output.sentiment }}\",\n \"feedback\": \"{{ $json['Title'] }}\"\n}"
},
"typeVersion": 3.4
},
{
"id": "9395692c-3e78-4266-b45f-4ce4eba5739d",
"name": "Configuration : Score d'impact",
"type": "n8n-nodes-base.stickyNote",
"position": [
-672,
-432
],
"parameters": {
"width": 343.81788385280146,
"height": 250.78228621783586,
"content": "## Step 3c: Calculate Impact Score\n\nCalculates business impact using weighted formula:\n- 50% weight: ARR value (normalized)\n- 30% weight: NPS stability\n- 20% weight: Sentiment severity\n\nHigher scores = higher priority for product team."
},
"typeVersion": 1
},
{
"id": "ceceb3a5-ba7a-4b90-a4d8-248ac18abe4f",
"name": "Calculer le score d'impact métier",
"type": "n8n-nodes-base.set",
"position": [
-400,
-160
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "impact-score-calc",
"name": "impact_score",
"type": "number",
"value": "={{ (0.5 * ($json.arr_usd / 50000)) + (0.3 * ((10 - Math.abs($json.nps_after - $json.nps_before)) / 10)) + (0.2 * ($json.sentiment === 'negative' ? 1 : $json.sentiment === 'neutral' ? 0.5 : 0.2)) }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "be4e3188-2f09-4490-ac95-c32a372b2ec5",
"name": "Configuration : Rapports par email",
"type": "n8n-nodes-base.stickyNote",
"position": [
-80,
192
],
"parameters": {
"width": 343.81788385280146,
"height": 310.78228621783586,
"content": "## Step 6: Weekly Email Report\n\nGenerates professional HTML email with:\n- Executive summary\n- Key metrics dashboard\n- Critical issues (high ARR or NPS drops)\n- Customer wins\n- Complete feedback table\n\n**Setup:**\n- Configure Outlook OAuth2\n- Replace recipient email address\n- Runs automatically every Monday"
},
"typeVersion": 1
},
{
"id": "08498f99-f113-4b02-8716-0091a04f7b2b",
"name": "Générer un rapport HTML",
"type": "n8n-nodes-base.code",
"position": [
-176,
32
],
"parameters": {
"jsCode": "// Weekly Feedback Report Formatter\n// Generates Outlook-compatible HTML email\n\nconst feedbackData = $input.all();\n\n// Calculate summary metrics\nlet totalARR = 0;\nlet positiveCount = 0;\nlet negativeCount = 0;\nlet neutralCount = 0;\nlet npsImproved = 0;\nlet npsDeclined = 0;\nlet totalNPSChange = 0;\n\nconst criticalIssues = [];\nconst wins = [];\n\nfeedbackData.forEach(item => {\n const arr = parseFloat(item.json.arr_usd) || 0;\n const npsBefore = parseFloat(item.json.nps_before) || 0;\n const npsAfter = parseFloat(item.json.nps_after) || 0;\n const npsChange = npsAfter - npsBefore;\n \n totalARR += arr;\n totalNPSChange += npsChange;\n \n // Count sentiments\n if (item.json.sentiment === 'positive') positiveCount++;\n else if (item.json.sentiment === 'negative') negativeCount++;\n else neutralCount++;\n \n // Track NPS changes\n if (npsChange > 0) npsImproved++;\n else if (npsChange < 0) npsDeclined++;\n \n // Identify critical issues\n if (item.json.sentiment === 'negative' && (arr > 20000 || npsChange <= -2)) {\n criticalIssues.push({ ...item.json, arr, npsChange });\n }\n \n // Identify wins\n if (item.json.sentiment === 'positive' && npsChange > 0) {\n wins.push({ ...item.json, arr, npsChange });\n }\n});\n\ncriticalIssues.sort((a, b) => b.arr - a.arr);\nwins.sort((a, b) => b.npsChange - a.npsChange);\n\nconst today = new Date();\nconst weekStart = new Date(today);\nweekStart.setDate(today.getDate() - 7);\n\nconst formatDate = (date) => {\n return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });\n};\n\nconst subject = `Customer Feedback Weekly Report - ${formatDate(weekStart)} to ${formatDate(today)}`;\n\nconst htmlBody = `<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n</head>\n<body style=\"margin: 0; padding: 0; background-color: #f4f4f4; font-family: Arial, sans-serif;\">\n <table role=\"presentation\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\" style=\"background-color: #f4f4f4;\">\n <tr>\n <td style=\"padding: 20px 0;\">\n <table role=\"presentation\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"600\" style=\"margin: 0 auto; background-color: #ffffff; border-radius: 8px;\">\n <tr>\n <td style=\"padding: 30px;\">\n <h1 style=\"margin: 0 0 10px 0; font-size: 24px; color: #2c3e50; border-bottom: 3px solid #3498db; padding-bottom: 10px;\">📊 Customer Feedback Weekly Report</h1>\n <p style=\"margin: 0; color: #7f8c8d; font-size: 14px;\">Report Period: <strong>${formatDate(weekStart)}</strong> to <strong>${formatDate(today)}</strong></p>\n </td>\n </tr>\n <tr>\n <td style=\"padding: 0 30px 20px 30px;\">\n <table role=\"presentation\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\" style=\"background-color: #e8f4f8; border-radius: 6px;\">\n <tr>\n <td style=\"padding: 20px;\">\n <h2 style=\"margin: 0 0 12px 0; font-size: 18px; color: #34495e;\">📈 Executive Summary</h2>\n <p style=\"margin: 0; color: #555555; font-size: 14px; line-height: 1.6;\">\n This week we collected <strong>${feedbackData.length} feedback responses</strong> from customers representing \n <strong>$${totalARR.toLocaleString()}</strong> in total ARR. Overall NPS movement shows \n <strong>${npsImproved} accounts improved</strong> and <strong>${npsDeclined} declined</strong>.\n </p>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n <tr>\n <td style=\"padding: 0 30px 20px 30px;\">\n <h2 style=\"margin: 0 0 15px 0; font-size: 18px; color: #34495e;\">🎯 Key Metrics</h2>\n <table role=\"presentation\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\">\n <tr>\n <td width=\"33%\" style=\"padding: 5px;\">\n <table role=\"presentation\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\" style=\"background-color: #667eea; border-radius: 6px;\">\n <tr>\n <td style=\"padding: 20px; text-align: center;\">\n <div style=\"font-size: 11px; color: #ffffff; text-transform: uppercase; margin-bottom: 5px;\">Total Feedback</div>\n <div style=\"font-size: 32px; font-weight: bold; color: #ffffff;\">${feedbackData.length}</div>\n </td>\n </tr>\n </table>\n </td>\n <td width=\"33%\" style=\"padding: 5px;\">\n <table role=\"presentation\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\" style=\"background-color: #2ecc71; border-radius: 6px;\">\n <tr>\n <td style=\"padding: 20px; text-align: center;\">\n <div style=\"font-size: 11px; color: #ffffff; text-transform: uppercase; margin-bottom: 5px;\">Positive</div>\n <div style=\"font-size: 32px; font-weight: bold; color: #ffffff;\">${positiveCount}</div>\n </td>\n </tr>\n </table>\n </td>\n <td width=\"33%\" style=\"padding: 5px;\">\n <table role=\"presentation\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\" style=\"background-color: #e74c3c; border-radius: 6px;\">\n <tr>\n <td style=\"padding: 20px; text-align: center;\">\n <div style=\"font-size: 11px; color: #ffffff; text-transform: uppercase; margin-bottom: 5px;\">Negative</div>\n <div style=\"font-size: 32px; font-weight: bold; color: #ffffff;\">${negativeCount}</div>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n ${criticalIssues.length > 0 ? `\n <tr>\n <td style=\"padding: 0 30px 20px 30px;\">\n <h2 style=\"margin: 0 0 10px 0; font-size: 18px; color: #34495e;\">🚨 Critical Issues</h2>\n ${criticalIssues.slice(0, 5).map(issue => `\n <table role=\"presentation\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\" style=\"background-color: #fee; border-left: 4px solid #e74c3c; border-radius: 4px; margin-bottom: 10px;\">\n <tr>\n <td style=\"padding: 15px;\">\n <strong style=\"color: #2c3e50;\">${issue.theme_label}</strong>\n <span style=\"background-color: #e74c3c; color: #fff; padding: 2px 6px; border-radius: 3px; font-size: 10px; margin-left: 8px;\">CRITICAL</span>\n <br>\n <span style=\"font-size: 12px; color: #666;\">ARR: ${issue.arr.toLocaleString()} | NPS: ${issue.nps_before} → ${issue.nps_after}</span>\n <p style=\"margin: 8px 0 0 0; color: #555; font-style: italic; font-size: 13px;\">${issue.feedback}</p>\n </td>\n </tr>\n </table>\n `).join('')}\n </td>\n </tr>\n ` : ''}\n ${wins.length > 0 ? `\n <tr>\n <td style=\"padding: 0 30px 20px 30px;\">\n <h2 style=\"margin: 0 0 10px 0; font-size: 18px; color: #34495e;\">🎉 Customer Wins</h2>\n ${wins.slice(0, 5).map(win => `\n <table role=\"presentation\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" width=\"100%\" style=\"background-color: #efe; border-left: 4px solid #2ecc71; border-radius: 4px; margin-bottom: 10px;\">\n <tr>\n <td style=\"padding: 15px;\">\n <strong style=\"color: #2c3e50;\">${win.theme_label}</strong>\n <span style=\"background-color: #2ecc71; color: #fff; padding: 2px 6px; border-radius: 3px; font-size: 10px; margin-left: 8px;\">WIN</span>\n <br>\n <span style=\"font-size: 12px; color: #666;\">ARR: ${win.arr.toLocaleString()} | NPS: ${win.nps_before} → ${win.nps_after}</span>\n <p style=\"margin: 8px 0 0 0; color: #555; font-style: italic; font-size: 13px;\">${win.feedback}</p>\n </td>\n </tr>\n </table>\n `).join('')}\n </td>\n </tr>\n ` : ''}\n <tr>\n <td style=\"padding: 20px 30px; border-top: 1px solid #ddd;\">\n <p style=\"margin: 0; text-align: center; color: #7f8c8d; font-size: 12px;\">\n Automated by n8n | Generated on ${formatDate(today)}\n </p>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n</body>\n</html>`;\n\nreturn [{\n json: {\n subject: subject,\n body: htmlBody,\n summary: {\n total_feedback: feedbackData.length,\n total_arr: totalARR,\n positive_count: positiveCount,\n negative_count: negativeCount,\n neutral_count: neutralCount,\n nps_improved: npsImproved,\n nps_declined: npsDeclined,\n critical_issues_count: criticalIssues.length,\n wins_count: wins.length\n }\n }\n}];"
},
"typeVersion": 2
},
{
"id": "9856c766-0c69-4720-835d-a485927fbb69",
"name": "Envoyer un message",
"type": "n8n-nodes-base.microsoftOutlook",
"position": [
48,
32
],
"webhookId": "bac58a25-de50-4bca-a6cc-5d35012c67cb",
"parameters": {
"subject": "={{ $json.subject }}",
"bodyContent": "={{ $json.body }}",
"toRecipients": "YOUR_EMAIL@example.com",
"additionalFields": {
"bodyContentType": "html"
}
},
"credentials": {
"microsoftOutlookOAuth2Api": {
"id": "dVY4LPJeMsLJMtJZ",
"name": "Microsoft Outlook account"
}
},
"typeVersion": 2
},
{
"id": "836e0820-15a8-4938-a4ff-d59fd0c93050",
"name": "Azure OpenAI Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
"position": [
-1248,
32
],
"parameters": {
"model": "gpt-4o",
"options": {}
},
"credentials": {
"azureOpenAiApi": {
"id": "C3WzT18XqF8OdVM6",
"name": "Azure Open AI account"
}
},
"typeVersion": 1
}
],
"active": true,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "c7cc5d75-cfd8-430e-b300-69f53c5881b3",
"connections": {
"1dc8d357-370c-4db4-bf62-c0fc90a03300": {
"main": [
[
{
"node": "022da409-d000-44e8-85a1-21bce519482d",
"type": "main",
"index": 0
}
]
]
},
"b2997445-aefe-4bfa-ad21-7754b2c6d498": {
"main": [
[
{
"node": "cbd79e63-6ef3-4de3-8e93-5d3825865ac0",
"type": "main",
"index": 0
}
]
]
},
"08498f99-f113-4b02-8716-0091a04f7b2b": {
"main": [
[
{
"node": "9856c766-0c69-4720-835d-a485927fbb69",
"type": "main",
"index": 0
}
]
]
},
"a037a368-1d36-4771-993f-7770ce89ba17": {
"main": [
[
{
"node": "553ce617-8fcc-4f94-a7b1-b5d76ebdd215",
"type": "main",
"index": 0
}
]
]
},
"836e0820-15a8-4938-a4ff-d59fd0c93050": {
"ai_languageModel": [
[
{
"node": "b2997445-aefe-4bfa-ad21-7754b2c6d498",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"553ce617-8fcc-4f94-a7b1-b5d76ebdd215": {
"main": [
[
{
"node": "73233e74-bcb5-47d7-87d1-4848d10e0268",
"type": "main",
"index": 0
}
]
]
},
"73233e74-bcb5-47d7-87d1-4848d10e0268": {
"main": [
[
{
"node": "b2997445-aefe-4bfa-ad21-7754b2c6d498",
"type": "main",
"index": 0
},
{
"node": "cbd79e63-6ef3-4de3-8e93-5d3825865ac0",
"type": "main",
"index": 1
}
]
]
},
"ae2b52c2-9be1-4d8e-9b72-6dcff9b948f4": {
"ai_memory": [
[
{
"node": "b2997445-aefe-4bfa-ad21-7754b2c6d498",
"type": "ai_memory",
"index": 0
}
]
]
},
"640ed7b7-7acf-4a89-9f7f-da1a0747e0c6": {
"ai_outputParser": [
[
{
"node": "b2997445-aefe-4bfa-ad21-7754b2c6d498",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"cbd79e63-6ef3-4de3-8e93-5d3825865ac0": {
"main": [
[
{
"node": "f90ec364-b556-47f3-8250-e93938a4455b",
"type": "main",
"index": 0
}
]
]
},
"ceceb3a5-ba7a-4b90-a4d8-248ac18abe4f": {
"main": [
[
{
"node": "22662502-fdce-4ab1-85e5-32196d570fda",
"type": "main",
"index": 0
},
{
"node": "f95ddd6f-e581-4a8a-8321-74b50c183ebf",
"type": "main",
"index": 0
},
{
"node": "08498f99-f113-4b02-8716-0091a04f7b2b",
"type": "main",
"index": 0
}
]
]
},
"f90ec364-b556-47f3-8250-e93938a4455b": {
"main": [
[
{
"node": "ceceb3a5-ba7a-4b90-a4d8-248ac18abe4f",
"type": "main",
"index": 0
}
]
]
}
}
}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.
Workflows recommandés
Rahul Joshi
@rahul08Rahul 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.
Partager ce workflow