Postuler à des emplois depuis Excel et suivre le statut des candidatures
Ceci est unPersonal Productivity, Multimodal AIworkflow d'automatisation du domainecontenant 24 nœuds.Utilise principalement des nœuds comme If, Set, Cron, Gmail, Filter. Demandes d'emploi et suivi de statut automatisés basés sur LinkedIn, Indeed et Google Sheets
- •Compte Google et informations d'identification Gmail API
- •Peut nécessiter les informations d'identification d'authentification de l'API cible
- •Informations d'identification Google Sheets API
Nœuds utilisés (24)
{
"name": "Apply to Jobs from Excel and Track Application Status",
"tags": [
{
"id": "job-automation",
"name": "Job Automation",
"createdAt": "2025-01-15T00:00:00.000Z",
"updatedAt": "2025-01-15T00:00:00.000Z"
}
],
"nodes": [
{
"id": "template-overview",
"name": "📋 Aperçu du modèle",
"type": "n8n-nodes-base.stickyNote",
"position": [
380,
160
],
"parameters": {
"color": 4,
"width": 389,
"height": 464,
"content": "## 🎯 Job Application Automation System\n\n**What it does:**\n- Reads job listings from Google Sheets\n- Automatically applies to jobs with personalized cover letters\n- Tracks application status every 2 days\n- Sends email notifications for updates\n- Maintains complete application history\n\n**Who's it for:**\n- Job seekers wanting to automate repetitive applications\n- Recruiters managing bulk applications\n- Career coaches tracking client progress\n\n**Requirements:**\n- Google Sheets with job data\n- Gmail account for notifications\n- Resume stored online (Google Drive recommended)\n- Job platform API access (LinkedIn, Indeed)\n\n**Setup Instructions:**\n1. Create Google Sheet with required columns\n2. Configure your spreadsheet ID in 'Configuration' node\n3. Set up Google Sheets and Gmail credentials\n4. Update email addresses in notification nodes\n5. Test with 1-2 jobs before full automation\n\n**⚠️ Important:** Replace mock HTTP requests with actual job platform APIs. Current implementation is for demonstration purposes."
},
"typeVersion": 1
},
{
"id": "sheet-structure",
"name": "📊 Structure de la feuille",
"type": "n8n-nodes-base.stickyNote",
"position": [
820,
160
],
"parameters": {
"color": 7,
"width": 295,
"height": 284,
"content": "## 📊 Excel Sheet Structure\n\nRequired columns:\n- Job_ID: Unique identifier\n- Company: Company name\n- Position: Job title\n- Status: Not Applied, Applied, etc.\n- Applied_Date: Application date\n- Last_Checked: Last status check\n- Application_ID: Platform reference\n- Notes: Additional info\n- Job_URL: Direct job link\n- Priority: High, Medium, Low"
},
"typeVersion": 1
},
{
"id": "setup-notes",
"name": "⚙️ Notes de configuration",
"type": "n8n-nodes-base.stickyNote",
"position": [
1180,
160
],
"parameters": {
"color": 6,
"width": 295,
"height": 224,
"content": "## 🔧 Configuration Setup\n\n1. Replace 'YOUR_GOOGLE_SHEET_ID' with actual ID\n2. Add your resume URL (Google Drive link)\n3. Customize cover letter template\n4. Update email addresses\n\n**Security Note:** Never hardcode API keys!\nUse n8n's credential store for all auth."
},
"typeVersion": 1
},
{
"id": "daily-trigger",
"name": "🕘 Déclencheur de candidature quotidien",
"type": "n8n-nodes-base.cron",
"position": [
240,
480
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * 1-5"
}
]
}
},
"typeVersion": 1
},
{
"id": "configuration",
"name": "⚙️ Configuration",
"type": "n8n-nodes-base.set",
"position": [
460,
480
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "spreadsheet-id",
"name": "spreadsheetId",
"type": "string",
"value": "REPLACE_WITH_YOUR_GOOGLE_SHEET_ID"
},
{
"id": "resume-url",
"name": "resumeUrl",
"type": "string",
"value": "https://drive.google.com/file/d/YOUR_RESUME_ID/view"
},
{
"id": "cover-letter",
"name": "coverLetterTemplate",
"type": "string",
"value": "Dear Hiring Manager,\n\nI am excited to apply for the {{position}} role at {{company}}. With my experience in software development and {{skills}}, I believe I would be a valuable addition to your team.\n\nI am particularly drawn to {{company}} because of your innovation in the tech industry. I would love to contribute to your continued success.\n\nBest regards,\nYour Name"
},
{
"id": "user-email",
"name": "userEmail",
"type": "string",
"value": "your-email@example.com"
}
]
}
},
"typeVersion": 3
},
{
"id": "read-jobs",
"name": "📖 Lire la feuille des offres",
"type": "n8n-nodes-base.googleSheets",
"position": [
680,
480
],
"parameters": {
"range": "A:J",
"keyRow": 1,
"dataMode": "autoMapInputData",
"sheetName": "Jobs",
"documentId": "={{ $json.spreadsheetId }}",
"requestMethod": "GET",
"authentication": "oAuth2"
},
"typeVersion": 4
},
{
"id": "filter-pending",
"name": "🎯 Filtrer les candidatures en attente",
"type": "n8n-nodes-base.filter",
"position": [
900,
480
],
"parameters": {
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "not-applied",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.Status }}",
"rightValue": "Not Applied"
},
{
"id": "has-url",
"operator": {
"type": "string",
"operation": "isNotEmpty"
},
"leftValue": "={{ $json.Job_URL }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2
},
{
"id": "split-jobs",
"name": "🔄 Traiter les offres une par une",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1120,
480
],
"parameters": {
"options": {
"reset": false
},
"batchSize": 1
},
"typeVersion": 3
},
{
"id": "prepare-data",
"name": "📝 Préparer les données de candidature",
"type": "n8n-nodes-base.set",
"position": [
1340,
480
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "job-platform",
"name": "platform",
"type": "string",
"value": "={{ $json.Job_URL.includes('linkedin.com') ? 'linkedin' : $json.Job_URL.includes('indeed.com') ? 'indeed' : 'generic' }}"
},
{
"id": "personalized-cover",
"name": "personalizedCoverLetter",
"type": "string",
"value": "={{ $('Configuration').first().json.coverLetterTemplate.replace('{{position}}', $json.Position).replace('{{company}}', $json.Company).replace('{{skills}}', 'relevant technical skills') }}"
},
{
"id": "application-date",
"name": "applicationDate",
"type": "string",
"value": "={{ $now.format('yyyy-MM-dd') }}"
},
{
"id": "resume-url",
"name": "resumeUrl",
"type": "string",
"value": "={{ $('Configuration').first().json.resumeUrl }}"
}
]
}
},
"typeVersion": 3
},
{
"id": "platform-router",
"name": "🔀 Router par plateforme",
"type": "n8n-nodes-base.switch",
"position": [
1560,
480
],
"parameters": {
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "linkedin-check",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.platform }}",
"rightValue": "linkedin"
}
]
}
},
"typeVersion": 3
},
{
"id": "linkedin-apply",
"name": "💼 Postuler via LinkedIn",
"type": "n8n-nodes-base.httpRequest",
"position": [
1780,
380
],
"parameters": {
"url": "https://api.linkedin.com/v2/jobs/applications",
"options": {
"retry": {
"enabled": true,
"maxTries": 3
},
"timeout": 30000
},
"sendBody": true,
"sendHeaders": true,
"requestMethod": "POST",
"authentication": "predefinedCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "jobId",
"value": "={{ $json.Job_ID }}"
},
{
"name": "coverLetter",
"value": "={{ $json.personalizedCoverLetter }}"
},
{
"name": "resumeUrl",
"value": "={{ $json.resumeUrl }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"nodeCredentialType": "linkedInOAuth2Api"
},
"typeVersion": 4
},
{
"id": "indeed-apply",
"name": "🔍 Postuler via Indeed",
"type": "n8n-nodes-base.httpRequest",
"position": [
1780,
580
],
"parameters": {
"url": "https://api.indeed.com/ads/applications",
"options": {
"retry": {
"enabled": true,
"maxTries": 3
},
"timeout": 30000
},
"sendBody": true,
"sendHeaders": true,
"requestMethod": "POST",
"authentication": "predefinedCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "jobkey",
"value": "={{ $json.Job_ID }}"
},
{
"name": "message",
"value": "={{ $json.personalizedCoverLetter }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"nodeCredentialType": "indeedApi"
},
"typeVersion": 4
},
{
"id": "process-result",
"name": "📊 Traiter le résultat de la candidature",
"type": "n8n-nodes-base.set",
"position": [
2000,
480
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "application-status",
"name": "applicationStatus",
"type": "string",
"value": "={{ $json.statusCode >= 200 && $json.statusCode < 300 ? 'Applied' : 'Failed' }}"
},
{
"id": "app-id",
"name": "applicationId",
"type": "string",
"value": "={{ $json.body?.applicationId || $json.body?.id || 'AUTO_' + $now.format('yyyyMMddHHmmss') }}"
},
{
"id": "status-notes",
"name": "statusNotes",
"type": "string",
"value": "={{ $json.statusCode >= 200 && $json.statusCode < 300 ? 'Application submitted successfully via ' + $('Prepare Application Data').first().json.platform : 'Application failed: ' + $json.statusCode }}"
},
{
"id": "job-data",
"name": "originalJobData",
"type": "object",
"value": "={{ $('Prepare Application Data').first().json }}"
}
]
}
},
"typeVersion": 3
},
{
"id": "update-status",
"name": "📝 Mettre à jour le statut de l'offre",
"type": "n8n-nodes-base.googleSheets",
"position": [
2220,
480
],
"parameters": {
"range": "D{{ $json.originalJobData.row_index }}:H{{ $json.originalJobData.row_index }}",
"keyRow": 1,
"values": {
"values": [
[
"={{ $json.applicationStatus }}",
"={{ $json.originalJobData.applicationDate }}",
"={{ $json.originalJobData.applicationDate }}",
"={{ $json.applicationId }}",
"={{ $json.statusNotes }}"
]
]
},
"dataMode": "autoMapInputData",
"sheetName": "Jobs",
"documentId": "={{ $('Configuration').first().json.spreadsheetId }}",
"requestMethod": "UPDATE",
"authentication": "oAuth2",
"valueInputMode": "raw"
},
"typeVersion": 4
},
{
"id": "send-notification",
"name": "📧 Envoyer une notification de candidature",
"type": "n8n-nodes-base.gmail",
"position": [
2440,
480
],
"parameters": {
"email": "={{ $('Configuration').first().json.userEmail }}",
"message": "<h3>Application Status Update</h3>\n<p><strong>Company:</strong> {{ $json.originalJobData.Company }}</p>\n<p><strong>Position:</strong> {{ $json.originalJobData.Position }}</p>\n<p><strong>Status:</strong> {{ $json.applicationStatus }}</p>\n<p><strong>Date:</strong> {{ $json.originalJobData.applicationDate }}</p>\n<p><strong>Platform:</strong> {{ $json.originalJobData.platform }}</p>\n<p><strong>Notes:</strong> {{ $json.statusNotes }}</p>\n<p><strong>Application ID:</strong> {{ $json.applicationId }}</p>",
"subject": "Job Application: {{ $json.originalJobData.Company }} - {{ $json.originalJobData.Position }}",
"operation": "sendEmail",
"emailFormat": "html"
},
"typeVersion": 2
},
{
"id": "status-tracking-info",
"name": "📊 Informations de suivi de statut",
"type": "n8n-nodes-base.stickyNote",
"position": [
380,
740
],
"parameters": {
"color": 7,
"width": 329,
"height": 204,
"content": "## 📈 Status Tracking Workflow\n\nThis section runs every 2 days to:\n- Check status of applied jobs\n- Update the spreadsheet\n- Send notifications for changes\n\n**Note:** Replace mock status checks with actual API calls to job platforms for real status updates."
},
"typeVersion": 1
},
{
"id": "status-trigger",
"name": "🕐 Déclencheur de vérification de statut",
"type": "n8n-nodes-base.cron",
"position": [
240,
980
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 10 */2 * *"
}
]
}
},
"typeVersion": 1
},
{
"id": "read-applied",
"name": "📖 Lire les offres postulées",
"type": "n8n-nodes-base.googleSheets",
"position": [
460,
980
],
"parameters": {
"range": "A:J",
"keyRow": 1,
"dataMode": "autoMapInputData",
"sheetName": "Jobs",
"documentId": "={{ $('Configuration').first().json.spreadsheetId }}",
"requestMethod": "GET",
"authentication": "oAuth2"
},
"typeVersion": 4
},
{
"id": "filter-applied",
"name": "🎯 Filtrer les offres postulées",
"type": "n8n-nodes-base.filter",
"position": [
680,
980
],
"parameters": {
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "applied-filter",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.Status }}",
"rightValue": "Applied"
}
]
}
},
"typeVersion": 2
},
{
"id": "split-status",
"name": "🔄 Vérifier le statut une par une",
"type": "n8n-nodes-base.splitInBatches",
"position": [
900,
980
],
"parameters": {
"options": {
"reset": false
},
"batchSize": 1
},
"typeVersion": 3
},
{
"id": "mock-status-check",
"name": "🔍 Vérification de statut simulée",
"type": "n8n-nodes-base.set",
"position": [
1120,
980
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "mock-status",
"name": "newStatus",
"type": "string",
"value": "={{ ['Applied', 'Under Review', 'Interview Scheduled', 'Rejected'][Math.floor(Math.random() * 4)] }}"
},
{
"id": "check-date",
"name": "checkDate",
"type": "string",
"value": "={{ $now.format('yyyy-MM-dd') }}"
},
{
"id": "status-notes",
"name": "statusNotes",
"type": "string",
"value": "Status checked automatically via API"
}
]
}
},
"typeVersion": 3
},
{
"id": "status-changed",
"name": "🔄 Vérifier si le statut a changé",
"type": "n8n-nodes-base.if",
"position": [
1340,
980
],
"parameters": {
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "status-changed",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $json.Status }}",
"rightValue": "={{ $json.newStatus }}"
}
]
}
},
"typeVersion": 2
},
{
"id": "update-changed",
"name": "📝 Mettre à jour le statut modifié",
"type": "n8n-nodes-base.googleSheets",
"position": [
1560,
980
],
"parameters": {
"range": "D{{ $json.row_index }}:F{{ $json.row_index }}",
"keyRow": 1,
"values": {
"values": [
[
"={{ $json.newStatus }}",
"={{ $json.Applied_Date }}",
"={{ $json.checkDate }}"
]
]
},
"dataMode": "autoMapInputData",
"sheetName": "Jobs",
"documentId": "={{ $('Configuration').first().json.spreadsheetId }}",
"requestMethod": "UPDATE",
"authentication": "oAuth2",
"valueInputMode": "raw"
},
"typeVersion": 4
},
{
"id": "send-status-update",
"name": "📧 Envoyer une mise à jour de statut",
"type": "n8n-nodes-base.gmail",
"position": [
1780,
980
],
"parameters": {
"email": "={{ $('Configuration').first().json.userEmail }}",
"message": "<h3>Application Status Changed</h3>\n<p><strong>Company:</strong> {{ $json.Company }}</p>\n<p><strong>Position:</strong> {{ $json.Position }}</p>\n<p><strong>Previous Status:</strong> {{ $json.Status }}</p>\n<p><strong>New Status:</strong> {{ $json.newStatus }}</p>\n<p><strong>Last Checked:</strong> {{ $json.checkDate }}</p>\n<p><strong>Notes:</strong> {{ $json.statusNotes }}</p>",
"subject": "Status Update: {{ $json.Company }} - {{ $json.Position }}",
"operation": "sendEmail",
"emailFormat": "html"
},
"typeVersion": 2
}
],
"settings": {
"executionOrder": "v1"
},
"updatedAt": "2025-01-15T00:00:00.000Z",
"versionId": "1",
"staticData": null,
"connections": {
"configuration": {
"main": [
[
{
"node": "read-jobs",
"type": "main",
"index": 0
}
]
]
},
"read-jobs": {
"main": [
[
{
"node": "filter-pending",
"type": "main",
"index": 0
}
]
]
},
"indeed-apply": {
"main": [
[
{
"node": "process-result",
"type": "main",
"index": 0
}
]
]
},
"read-applied": {
"main": [
[
{
"node": "filter-applied",
"type": "main",
"index": 0
}
]
]
},
"update-status": {
"main": [
[
{
"node": "send-notification",
"type": "main",
"index": 0
}
]
]
},
"platform-router": {
"main": [
[
{
"node": "linkedin-apply",
"type": "main",
"index": 0
}
],
[
{
"node": "indeed-apply",
"type": "main",
"index": 0
}
]
]
},
"mock-status-check": {
"main": [
[
{
"node": "status-changed",
"type": "main",
"index": 0
}
]
]
},
"linkedin-apply": {
"main": [
[
{
"node": "process-result",
"type": "main",
"index": 0
}
]
]
},
"filter-applied": {
"main": [
[
{
"node": "split-status",
"type": "main",
"index": 0
}
]
]
},
"status-trigger": {
"main": [
[
{
"node": "read-applied",
"type": "main",
"index": 0
}
]
]
},
"update-changed": {
"main": [
[
{
"node": "send-status-update",
"type": "main",
"index": 0
}
]
]
},
"split-status": {
"main": [
[
{
"node": "mock-status-check",
"type": "main",
"index": 0
}
]
]
},
"status-changed": {
"main": [
[
{
"node": "update-changed",
"type": "main",
"index": 0
}
]
]
},
"split-jobs": {
"main": [
[
{
"node": "prepare-data",
"type": "main",
"index": 0
}
]
]
},
"prepare-data": {
"main": [
[
{
"node": "platform-router",
"type": "main",
"index": 0
}
]
]
},
"daily-trigger": {
"main": [
[
{
"node": "configuration",
"type": "main",
"index": 0
}
]
]
},
"process-result": {
"main": [
[
{
"node": "update-status",
"type": "main",
"index": 0
}
]
]
},
"filter-pending": {
"main": [
[
{
"node": "split-jobs",
"type": "main",
"index": 0
}
]
]
}
},
"triggerCount": 2
}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é - Productivité personnelle, 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.
Workflows recommandés
VipinW
@vxi14Partager ce workflow