Workflow d'alerte aux risques de départ (Azure OpenAI + n8n)

Avancé

Ceci est unContent Creation, Multimodal AIworkflow d'automatisation du domainecontenant 16 nœuds.Utilise principalement des nœuds comme If, Code, Gmail, GoogleDrive, Agent. Détection du risque de départ d'employés et alertes RH avec Azure OpenAI GPT-4o-mini et Gmail

Prérequis
  • Compte Google et informations d'identification Gmail API
  • Informations d'identification Google Drive API
  • Clé API OpenAI
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": "ONqZuWnwkE64Mm4F",
  "meta": {
    "instanceId": "8443f10082278c46aa5cf3acf8ff0f70061a2c58bce76efac814b16290845177",
    "templateCredsSetupCompleted": true
  },
  "name": "Attrition Risk Alert Workflow (Azure OpenAI + n8n)",
  "tags": [],
  "nodes": [
    {
      "id": "c48bef67-a0d0-4a4b-a374-3df1a7ed4c19",
      "name": "Azure Modèle de chat OpenAI",
      "type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
      "position": [
        688,
        128
      ],
      "parameters": {
        "model": "gpt-4o-mini",
        "options": {}
      },
      "credentials": {
        "azureOpenAiApi": {
          "id": "C3WzT18XqF8OdVM6",
          "name": "Azure Open AI account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a44062d6-1e37-443b-b146-cf32a9ac74cc",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        816,
        128
      ],
      "parameters": {
        "jsonSchemaExample": "{\n\t\"average\": \"18\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "2ab2bd76-1809-4015-9d99-a278561287da",
      "name": "Trigger for new resume",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "position": [
        0,
        -96
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "list",
          "value": "1KyX5RGqeF7v0sAvvaoBnJPTQoq4aOHLz",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1KyX5RGqeF7v0sAvvaoBnJPTQoq4aOHLz",
          "cachedResultName": "HR auto"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "gPmEPTuQP4KLm1KD",
          "name": "jyothi"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "dabfc101-cfa3-43e6-b568-320c1c2d3e92",
      "name": "Download resume",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        224,
        -96
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $json.webViewLink }}"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "gPmEPTuQP4KLm1KD",
          "name": "jyothi"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "821c7e31-be41-4e6c-b58b-19a2cf880648",
      "name": "Extract text",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        448,
        -96
      ],
      "parameters": {
        "options": {},
        "operation": "pdf"
      },
      "typeVersion": 1
    },
    {
      "id": "78f8966f-dbeb-4773-b198-9dfb13defd35",
      "name": "Calculate avg span",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        672,
        -96
      ],
      "parameters": {
        "text": "={{ $json.text }}",
        "options": {
          "systemMessage": "You are given resume text as input. Your task is to extract employment experiences and return ONLY the average tenure (in months) across those experiences as a single number.\n\nInstructions:\n- Scope: Consider only professional employment entries under Experience (exclude Education, Projects, Achievements, Certifications, Skills, Languages).\n- Grouping: Treat each distinct job/employer entry as one experience. If multiple roles at the same employer have separate date ranges, treat each as separate experiences.\n- Dates:\n  - Parse start and end dates in formats like \"MMM YYYY\", \"Month YYYY\", \"YYYY\", or date ranges using -, –, —.\n  - If the end date is \"Present\"/current, use today's date.\n  - If a date has only a year, assume the month as January.\n  - If a start or end month/day is missing, default to the first day of that month.\n- Duration Calculation:\n  - Compute the difference in full months for each experience (start inclusive, end exclusive).\n  - Do not deduct overlaps; each listed experience is counted independently.\n  - Exclude entries without any valid start date.\n- Averaging:\n  - Compute the arithmetic mean of the months across all valid experiences.\n  - Round to the nearest whole month (standard rounding).\n\n"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "5e697388-e418-495e-b91f-5eba9deb0427",
      "name": "Logic",
      "type": "n8n-nodes-base.if",
      "position": [
        1024,
        -96
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "21c98617-ba35-4906-afd0-38a82211dbe7",
              "operator": {
                "type": "number",
                "operation": "lt"
              },
              "leftValue": "={{ $json.output.average.toNumber() }}",
              "rightValue": 12
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "93b32316-47a7-4769-8a82-289a4c66c73f",
      "name": "Create email",
      "type": "n8n-nodes-base.code",
      "position": [
        1248,
        -96
      ],
      "parameters": {
        "jsCode": "// filename: n8n-code-node-attrition-email.js\n// This Code node builds an email for each item indicating high attrition risk.\n// Output fields:\n//   - emailSubject\n//   - emailBody\n//   - emailTo (optional if you want to set here)\n//   - emailCc (optional)\n//   - emailMetadata (structured data for downstream logging)\n\nfunction formatDate(dateStr) {\n  if (!dateStr) return \"N/A\";\n  const d = new Date(dateStr);\n  if (isNaN(d.getTime())) return dateStr;\n  // Format as YYYY-MM-DD for clarity\n  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, \"0\")}-${String(d.getDate()).padStart(2, \"0\")}`;\n}\n\nfunction clampScore(score) {\n  const n = Number(score);\n  if (Number.isNaN(n)) return null;\n  return Math.max(0, Math.min(100, n));\n}\n\nfunction classifyRisk(score) {\n  if (score == null) return \"Unknown\";\n  if (score >= 80) return \"High\";\n  if (score >= 50) return \"Medium\";\n  return \"Low\";\n}\n\nfunction bulletList(items) {\n  if (!Array.isArray(items) || items.length === 0) return \"- None\";\n  return items.map(s => `- ${String(s).trim() || \"N/A\"}`).join(\"\\n\");\n}\n\nconst outputs = [];\n\nfor (const item of $input.all()) {\n  const j = item.json || {};\n\n  const personName = j.personName || j.name || \"The employee\";\n  const role = j.role || \"N/A\";\n  const department = j.department || null;\n  const managerName = j.managerName || \"HR/People Ops\";\n  const riskScoreRaw = j.riskScore ?? j.attritionRiskScore;\n  const riskScore = clampScore(riskScoreRaw);\n  const riskLevel = classifyRisk(riskScore);\n  const signals = Array.isArray(j.signals) ? j.signals : [];\n  const lastEngagementDate = formatDate(j.lastEngagementDate || j.lastCheckInDate);\n  const recommendedActions = Array.isArray(j.recommendedActions) ? j.recommendedActions : [\n    \"Schedule a 1:1 check‑in within the next 3–5 days\",\n    \"Offer growth or role‑clarity conversation\",\n    \"Review workload and compensation alignment\",\n  ];\n\n  // Email routing (optional; you can also set these in the Email node)\n  const emailTo = j.emailTo || j.managerEmail || j.hrEmail || \"\";\n  const emailCc = j.emailCc || \"\";\n\n  // Compose subject\n  const subjectParts = [\n    \"[Attrition Alert]\",\n    personName !== \"The employee\" ? personName : \"Employee\",\n    riskLevel !== \"Unknown\" ? `– ${riskLevel} Risk (${riskScore}%)` : \"– Risk Review\",\n  ];\n  const emailSubject = subjectParts.filter(Boolean).join(\" \");\n\n  // Compose body (plain text; you can convert to HTML if preferred)\n  const headerLine = `${personName} ${role !== \"N/A\" ? `(${role})` : \"\"}${department ? `, ${department}` : \"\"}`;\n  const riskLine = `Attrition Risk: ${riskLevel}${riskScore != null ? ` (${riskScore}%)` : \"\"}`;\n  const signalsBlock = bulletList(signals);\n  const actionsBlock = bulletList(recommendedActions);\n\n  const emailBody =\n`Hi ${managerName},\n\nThis is a heads‑up that ${headerLine} may be at risk of leaving soon. ${riskLine}.\n\nKey signals observed:\n${signalsBlock}\n\nLast engagement/check‑in: ${lastEngagementDate}\n\nSuggested next steps:\n${actionsBlock}\n\nPlease prioritize a supportive outreach. If helpful, we can prepare a retention plan (growth discussion, workload review, recognition, and role clarity).\n\nThanks,\nPeople Analytics\n`;\n\n  outputs.push({\n    json: {\n      ...j,\n      emailSubject,\n      emailBody,\n      emailTo,\n      emailCc,\n      emailMetadata: {\n        personName,\n        role,\n        department,\n        managerName,\n        riskScore,\n        riskLevel,\n        signals,\n        lastEngagementDate,\n        recommendedActions,\n        generatedAt: new Date().toISOString(),\n      },\n    },\n  });\n}\n\nreturn outputs;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "cc3e9d3e-4a29-4125-83bd-c43770219fca",
      "name": "Send email to hr",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1472,
        -96
      ],
      "webhookId": "15c04fae-06e4-41c8-860d-020d07ca31f6",
      "parameters": {
        "sendTo": "jyothi.swarup@techdome.net.in",
        "message": "={{ $json.emailBody }}",
        "options": {},
        "subject": "={{ $json.emailSubject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "70f5n8rPahCANHs7",
          "name": "jyothi"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "860057d2-af64-4ea5-8df5-1945f27b52d2",
      "name": "Note adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -336,
        -128
      ],
      "parameters": {
        "content": "## Trigger for new resume  \nStarts the workflow when a new resume file is added (e.g., to storage or inbox)."
      },
      "typeVersion": 1
    },
    {
      "id": "ce4d511d-b14d-4a13-ac97-a319e90b2d2a",
      "name": "Note adhésive1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        128,
        -304
      ],
      "parameters": {
        "content": "## Download resume  \nFetches the resume file from the source and makes it available for processing."
      },
      "typeVersion": 1
    },
    {
      "id": "dcf63ce0-b0f0-4ede-9c95-c7c37814b028",
      "name": "Note adhésive2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        80
      ],
      "parameters": {
        "content": "## Extract text  \nPulls readable text from the downloaded resume using a PDF extraction step."
      },
      "typeVersion": 1
    },
    {
      "id": "114d70ee-1e49-41f4-937b-6b8e183d787b",
      "name": "Note adhésive3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        656,
        -304
      ],
      "parameters": {
        "content": "## Chat Model  \nUses Azure OpenAI Chat to analyze or summarize the extracted resume content."
      },
      "typeVersion": 1
    },
    {
      "id": "b5ee6f06-3ac8-402a-9051-f5ee0aaae094",
      "name": "Note adhésive4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        96
      ],
      "parameters": {
        "content": "## Logic  \nApplies conditional checks and routing (true/false) based on parsed results."
      },
      "typeVersion": 1
    },
    {
      "id": "e7fcd240-e008-419f-ac1b-e45593f3c037",
      "name": "Note adhésive5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1168,
        -320
      ],
      "parameters": {
        "content": "## Create email  \nGenerates a tailored email draft to the candidate or HR using the parsed data."
      },
      "typeVersion": 1
    },
    {
      "id": "e8aae9bd-426b-4020-8b47-f48bc35b1ae3",
      "name": "Note adhésive6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1408,
        96
      ],
      "parameters": {
        "content": "## Send email to hr  \nSends the composed message to HR via the configured email service."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "a93f6021-cc9d-4249-b529-62a19a79292a",
  "connections": {
    "5e697388-e418-495e-b91f-5eba9deb0427": {
      "main": [
        [
          {
            "node": "93b32316-47a7-4769-8a82-289a4c66c73f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "93b32316-47a7-4769-8a82-289a4c66c73f": {
      "main": [
        [
          {
            "node": "cc3e9d3e-4a29-4125-83bd-c43770219fca",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "821c7e31-be41-4e6c-b58b-19a2cf880648": {
      "main": [
        [
          {
            "node": "78f8966f-dbeb-4773-b198-9dfb13defd35",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "dabfc101-cfa3-43e6-b568-320c1c2d3e92": {
      "main": [
        [
          {
            "node": "821c7e31-be41-4e6c-b58b-19a2cf880648",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "78f8966f-dbeb-4773-b198-9dfb13defd35": {
      "main": [
        [
          {
            "node": "5e697388-e418-495e-b91f-5eba9deb0427",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2ab2bd76-1809-4015-9d99-a278561287da": {
      "main": [
        [
          {
            "node": "dabfc101-cfa3-43e6-b568-320c1c2d3e92",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Azure OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "78f8966f-dbeb-4773-b198-9dfb13defd35",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "a44062d6-1e37-443b-b146-cf32a9ac74cc": {
      "ai_outputParser": [
        [
          {
            "node": "78f8966f-dbeb-4773-b198-9dfb13defd35",
            "type": "ai_outputParser",
            "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é - Création de contenu, IA Multimodale

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œuds16
Catégorie2
Types de nœuds10
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