Tägliche Bewerberzusammenfassung
Dies ist ein AI Summarization, Multimodal AI-Bereich Automatisierungsworkflow mit 10 Nodes. Hauptsächlich werden Code, Gmail, ScheduleTrigger, ChainLlm, LmChatGoogleGemini und andere Nodes verwendet. Tägliche Bewerberzusammenfassung nach Positionskategorien mit Gemini AI extrahiert, für Personalvermittler
- •Google-Konto + Gmail API-Anmeldedaten
- •Google Gemini API Key
Verwendete Nodes (10)
Kategorie
{
"id": "MGgeJBbeovHVQAbq",
"meta": {
"instanceId": "14e4c77104722ab186539dfea5182e419aecc83d85963fe13f6de862c875ebfa",
"templateCredsSetupCompleted": true
},
"name": "Daily-Applicant-Digest",
"tags": [],
"nodes": [
{
"id": "75fe46c9-d9eb-455e-8f9d-7384c4a1d172",
"name": "Zeitplan-Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-340,
-80
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 6
}
]
}
},
"typeVersion": 1.2
},
{
"id": "ba41cb19-9463-4c8a-a94d-a7d579346b1e",
"name": "Google Gemini-Chat-Modell",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
120,
120
],
"parameters": {
"options": {},
"modelName": "models/gemini-1.5-flash"
},
"credentials": {
"googlePalmApi": {
"id": "VbpO5dd6r2AhD52y",
"name": "Google Gemini(PaLM) Api account 2"
}
},
"typeVersion": 1
},
{
"id": "9e2ef974-5183-4e7d-9cd2-8f3872bd0a66",
"name": "Haftnotiz",
"type": "n8n-nodes-base.stickyNote",
"position": [
-520,
-360
],
"parameters": {
"width": 1720,
"height": 680,
"content": "## Send daily applicant digest by role from Gmail to hiring managers with Google Gemini"
},
"typeVersion": 1
},
{
"id": "4648ef51-49af-40f8-9c82-490c5965e5be",
"name": "fetch_applicant_emails",
"type": "n8n-nodes-base.gmail",
"position": [
-120,
-80
],
"webhookId": "342f1447-19e1-4639-ae6e-a39fc1131b7c",
"parameters": {
"filters": {
"q": "label: applicant newer_than:1d is:unread"
},
"operation": "getAll"
},
"credentials": {
"gmailOAuth2": {
"id": "Kb30iigFce7pjkMZ",
"name": "Gmail account 5"
}
},
"typeVersion": 2.1
},
{
"id": "f479ae8a-490b-4b08-9fe3-dbe6a26b2320",
"name": "readAll_applicant_emails",
"type": "n8n-nodes-base.gmail",
"position": [
120,
-280
],
"webhookId": "801858f2-9076-47a1-88eb-c8c1c930102d",
"parameters": {
"messageId": "={{ $json.id }}",
"operation": "markAsRead"
},
"credentials": {
"gmailOAuth2": {
"id": "Kb30iigFce7pjkMZ",
"name": "Gmail account 5"
}
},
"typeVersion": 2.1
},
{
"id": "2a8e9656-df75-439f-ac16-ba608b29c87d",
"name": "Extract Applicant Details",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
100,
-80
],
"parameters": {
"text": "=You are an assistant that extracts job applicant information from emails.\n\nExtract the following fields and return ONLY valid JSON with these keys:\n- name\n- email\n- phone\n- role\n- years_of_experience\n- top_skills\n- location\n- notice_period\n- summary\n\nApplicant email:\n\"\"\"\n{{$json.snippet }}\n\"\"\"\n",
"batching": {},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "3937cc5c-ea58-4b5d-b22d-591f8097481f",
"name": "Assign Manager E-Mails",
"type": "n8n-nodes-base.code",
"position": [
480,
-80
],
"parameters": {
"jsCode": "function stripMarkdownJson(input) {\n let str = (input || '').trim();\n\n // Remove the ```json at the start and ```\n // This regex removes triple backticks and the 'json' keyword at the start\n str = str.replace(/^```json\\s*/, ''); // Remove starting ```\n str = str.replace(/```$/, ''); // Remove ending ```\n \n return str.trim();\n}\n\nfunction normalizeRole(role) {\n return (role || '').trim().toLowerCase();\n}\n\nconst roleToManagerEmail = {\n 'java team lead': 'javatl@mailinator.com',\n 'python developer': 'pythontl@mailinator.com',\n 'frontend developer': 'frontendtl@mailinator.com',\n // add other roles as needed\n};\n\nconst fallbackManagerEmail = 'fallback@mailinator.com';\n\nreturn items.map(item => {\n const raw = item.json.text || '';\n const jsonStr = stripMarkdownJson(raw);\n\n let parsed;\n try {\n parsed = JSON.parse(jsonStr);\n } catch (e) {\n item.json.error = `JSON parse failed: ${e.message}`;\n return item;\n }\n\n // Merge the parsed JSON fields into the current item\n Object.assign(item.json, parsed);\n\n // Normalize role and assign manager email\n const normalizedRole = normalizeRole(item.json.role);\n const managerEmail = Object.prototype.hasOwnProperty.call(roleToManagerEmail, normalizedRole)\n ? roleToManagerEmail[normalizedRole]\n : fallbackManagerEmail;\n\n item.json.managerEmail = managerEmail;\n\n return item;\n});\n"
},
"typeVersion": 2
},
{
"id": "5943f68f-a39f-4532-a437-732d98d53079",
"name": "Group & Build HTML Tables",
"type": "n8n-nodes-base.code",
"position": [
700,
-80
],
"parameters": {
"jsCode": "function escapeHtml(text) {\n if (!text) return '';\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n// Group applicants by managerEmail, then by role\nconst groupedByManager = {};\n\n// Step 1: Group items\nitems.forEach(item => {\n const applicant = item.json;\n const managerEmail = applicant.managerEmail || 'unknown@fallback.com';\n const role = applicant.role || 'Unknown Role';\n\n if (!groupedByManager[managerEmail]) {\n groupedByManager[managerEmail] = {};\n }\n if (!groupedByManager[managerEmail][role]) {\n groupedByManager[managerEmail][role] = [];\n }\n \n groupedByManager[managerEmail][role].push(applicant);\n});\n\n// Step 2: Build HTML per manager with tables per role\nconst output = [];\n\nfor (const [managerEmail, roles] of Object.entries(groupedByManager)) {\n\n let emailHtml = `<h2>Today's New Applicants</h2>`;\n\n for (const [role, applicants] of Object.entries(roles)) {\n emailHtml += `<h3>Role: ${escapeHtml(role)}</h3>`;\n \n // Build table header\n emailHtml += `\n <table border=\"1\" cellpadding=\"5\" cellspacing=\"0\" style=\"border-collapse:collapse; width: 100%;\">\n <thead style=\"background-color:#f0f0f0;\">\n <tr>\n <th>Name</th>\n <th>Email</th>\n <th>Phone</th>\n <th>Years of Experience</th>\n <th>Top Skills</th>\n <th>Location</th>\n <th>Notice Period</th>\n <th>Summary</th>\n </tr>\n </thead>\n <tbody>\n `;\n\n // Add each applicant as a row\n applicants.forEach(app => {\n emailHtml += `\n <tr>\n <td>${escapeHtml(app.name)}</td>\n <td><a href=\"mailto:${escapeHtml(app.email)}\">${escapeHtml(app.email)}</a></td>\n <td>${escapeHtml(app.phone)}</td>\n <td>${escapeHtml(app.years_of_experience?.toString())}</td>\n <td>${Array.isArray(app.top_skills) ? escapeHtml(app.top_skills.join(', ')) : escapeHtml(app.top_skills)}</td>\n <td>${escapeHtml(app.location)}</td>\n <td>${escapeHtml(app.notice_period)}</td>\n <td>${escapeHtml(app.summary)}</td>\n </tr>\n `;\n });\n\n emailHtml += `</tbody></table><br/>`;\n }\n\n // Push one item per manager, as output for the next step (email sending)\n output.push({\n json: {\n managerEmail,\n html: emailHtml\n }\n });\n}\n\nreturn output;\n"
},
"typeVersion": 2
},
{
"id": "9509d5c2-f66f-4294-9432-0b2587283b7a",
"name": "Send Digest to Managers",
"type": "n8n-nodes-base.gmail",
"position": [
900,
-80
],
"webhookId": "7fe812db-f512-4e0d-b4e5-f577fad2511c",
"parameters": {
"sendTo": "={{ $json.managerEmail }}",
"message": "={{ $json.html }}",
"options": {},
"subject": "=Today's Applicants Digest – {{ $now.format('MM-DD') }}"
},
"credentials": {
"gmailOAuth2": {
"id": "Kb30iigFce7pjkMZ",
"name": "Gmail account 5"
}
},
"typeVersion": 2.1
},
{
"id": "17486203-2374-43f0-88eb-80500108d770",
"name": "Haftnotiz1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-520,
360
],
"parameters": {
"width": 1720,
"height": 780,
"content": "## Workflow Overview: Send daily applicant digest by role from Gmail to hiring managers with Google Gemini\n\n**Purpose:**\nAutomatically fetches new job application emails labeled applicants, extracts structured applicant details using OpenAI, groups candidates by role and manager, then sends a daily HTML summary email to each hiring manager.\n\nDaily Applicant Digest Workflow – Node Overview\n\n**1. Daily Trigger (6PM IST)**\n\nStarts the workflow every day at 18:00 (Asia/Kolkata timezone).\n\n**2. Fetch Applicant Emails**\n\nRetrieves all new application emails labeled applicants from the last 24 hours.\n\n**3. Read All Emails**\n\nRead each email’s labeled applicants which we retrieves\n\n**4. Extract Applicant Details**\n\nUses OpenAI to extract and structure applicant info (name, email, role, skills, etc.) in JSON format.\n\n**5. Assign Manager Emails**\n\nMaps each applicant’s role to a hiring manager’s email address.\n\nUses a fallback email if the role does not match any manager.\n\n**6. Group & Build HTML Tables**\n\nGroups applicants by manager and role.\n\nBuilds a clear, formatted HTML table for each group, summarizing all applicants.\n\n**7. Send Digest to Managers**\n\nSends one HTML summary email per manager, listing all relevant new applicants for the day.\n"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "67d27489-333a-4e73-8d9c-1af780d66304",
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "4648ef51-49af-40f8-9c82-490c5965e5be",
"type": "main",
"index": 0
}
]
]
},
"Assign Manager Emails": {
"main": [
[
{
"node": "5943f68f-a39f-4532-a437-732d98d53079",
"type": "main",
"index": 0
}
]
]
},
"4648ef51-49af-40f8-9c82-490c5965e5be": {
"main": [
[
{
"node": "2a8e9656-df75-439f-ac16-ba608b29c87d",
"type": "main",
"index": 0
},
{
"node": "f479ae8a-490b-4b08-9fe3-dbe6a26b2320",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "2a8e9656-df75-439f-ac16-ba608b29c87d",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"2a8e9656-df75-439f-ac16-ba608b29c87d": {
"main": [
[
{
"node": "Assign Manager Emails",
"type": "main",
"index": 0
}
]
]
},
"5943f68f-a39f-4532-a437-732d98d53079": {
"main": [
[
{
"node": "9509d5c2-f66f-4294-9432-0b2587283b7a",
"type": "main",
"index": 0
}
]
]
}
}
}Wie verwende ich diesen Workflow?
Kopieren Sie den obigen JSON-Code, erstellen Sie einen neuen Workflow in Ihrer n8n-Instanz und wählen Sie "Aus JSON importieren". Fügen Sie die Konfiguration ein und passen Sie die Anmeldedaten nach Bedarf an.
Für welche Szenarien ist dieser Workflow geeignet?
Fortgeschritten - KI-Zusammenfassung, Multimodales KI
Ist es kostenpflichtig?
Dieser Workflow ist völlig kostenlos. Beachten Sie jedoch, dass Drittanbieterdienste (wie OpenAI API), die im Workflow verwendet werden, möglicherweise kostenpflichtig sind.
Verwandte Workflows
WeblineIndia
@weblineindiaA Leading Software Engineering, Consulting & Outsourcing Services Company in USA & India serving Clients Globally since 1999.
Diesen Workflow teilen