Verwendung von HTTP Last-Modified, um abgelaufene Stellenangebote aus Google Sheets zu prüfen und Aktualisierungsbenachrichtigungen zu erhalten
Dies ist ein HR, Miscellaneous, Multimodal AI-Bereich Automatisierungsworkflow mit 19 Nodes. Hauptsächlich werden If, Set, Code, Wait, Gmail und andere Nodes verwendet. Automatisierung von Erinnerungen abgelaufener Stellenanzeigen durch Google Sheets, HTTP-Prüfung und Gmail
- •Google-Konto + Gmail API-Anmeldedaten
- •Möglicherweise sind Ziel-API-Anmeldedaten erforderlich
- •Google Sheets API-Anmeldedaten
Verwendete Nodes (19)
{
"id": "Et2vjObBEUPt72Ff",
"meta": {
"instanceId": "14e4c77104722ab186539dfea5182e419aecc83d85963fe13f6de862c875ebfa",
"templateCredsSetupCompleted": true
},
"name": "Job post expiry & refresh reminders from Google Sheets using HTTP Last‑Modified checks",
"tags": [],
"nodes": [
{
"id": "86114cf9-db36-4ed0-bd20-cead6465ca95",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-60,
-40
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "10 32 10 * * *"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "70241c9f-d0df-4907-9a77-045436521635",
"name": "Fetch Job URLs",
"type": "n8n-nodes-base.googleSheets",
"position": [
320,
-40
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Job Posts"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "1n_AIqOd10Q0ErQZSO4q4LBMekwgsR4cP7EW2q9nEzdk"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "K51JQLS2WHFWzap5",
"name": "Google Sheets account 7"
}
},
"executeOnce": false,
"notesInFlow": false,
"retryOnFail": false,
"typeVersion": 4.6,
"alwaysOutputData": true
},
{
"id": "d21a1bde-5c2f-45cc-b729-7cbf9d378d1d",
"name": "Filter Invalid Rows",
"type": "n8n-nodes-base.if",
"position": [
480,
-40
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "67a2d579-8bab-4da0-b6a2-d38acb936935",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "{{ $json.job_url }}",
"rightValue": ""
},
{
"id": "10c7e27f-331d-4df6-99cf-442c346074af",
"operator": {
"type": "string",
"operation": "regex"
},
"leftValue": "={{ $json.recruiter_email }}",
"rightValue": "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"
},
{
"id": "43158fe0-b3f9-4b5b-8d86-9a2d16ac5c21",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.recruiter_email }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "e6bb385d-a4b3-48b7-995e-8ad55a06357b",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
1320,
40
],
"parameters": {
"url": "={{$json.job_url}}",
"method": "HEAD",
"options": {
"timeout": 5000
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "User-Agent",
"value": "={{ ($json[\"USER_AGENT\"] || \"n8n-job-checker/1.0\").replace(/\\n/g, \"\").trim() }}"
}
]
}
},
"retryOnFail": false,
"typeVersion": 4.2
},
{
"id": "48022cb5-72dd-45f8-aabf-b90c55310dd3",
"name": "Wait Before HTTP",
"type": "n8n-nodes-base.wait",
"position": [
1120,
40
],
"webhookId": "7b536af6-1208-4fb7-9072-4b58c7840905",
"parameters": {},
"typeVersion": 1.1
},
{
"id": "85d9b757-910b-4fef-874f-abea9ebbae81",
"name": "Is Age ≥ THRESHOLD_DAYS?",
"type": "n8n-nodes-base.if",
"position": [
1940,
40
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "f38b35c0-457f-478c-94bb-78dfb95f34fd",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.age_days }}",
"rightValue": "={{ 30 }}"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "d26e7e33-fc11-4674-81a7-8e8335998570",
"name": "Gmail",
"type": "n8n-nodes-base.gmail",
"onError": "continueRegularOutput",
"position": [
2220,
20
],
"webhookId": "69c3daba-371f-4a5b-93e2-6332e40ea0dd",
"parameters": {
"sendTo": "={{ $json.recruiter_email }}",
"message": "=<p>Hi {{ $json.recruiter_name }},</p>\n<p>This is a kind reminder that the following job post appears to be <strong>{{ $json.age_days }} days old</strong>:</p>\n<p><a href=\"{{ $json.job_url }}\">{{ $json.job_url }}</a></p>\n<p>Last Modified: <strong>{{ $json.last_modified }}</strong></p>\n<p>If the position is still open, we recommend refreshing or updating the post to ensure visibility and relevance.</p>\n<p>Thank you!</p>\n<p><em>— Hiring Ops Bot</em></p>",
"options": {},
"subject": "={{'Gentle Reminder: Update Your Job Post (${json.age_days} days old)' }}"
},
"credentials": {
"gmailOAuth2": {
"id": "GsAjl8kiLaQnkjoK",
"name": "Gmail account 10"
}
},
"typeVersion": 2.1
},
{
"id": "1d6141d4-a6b8-425f-8543-c3ae6207a12d",
"name": "calculate Age",
"type": "n8n-nodes-base.code",
"position": [
1760,
40
],
"parameters": {
"jsCode": "const lastModifiedStr = $input.item.json.last_modified;\n\nlet ageDays = 0;\n\nif (lastModifiedStr && lastModifiedStr !== 'Unknown') {\n try {\n const lastModified = new Date(lastModifiedStr);\n const now = new Date();\n const diffMs = now.getTime() - lastModified.getTime();\n ageDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n } catch (error) {\n console.log('Error parsing date:', error);\n ageDays = 0;\n }\n}\n\nreturn [{\n ...$input.item.json,\n age_days: ageDays\n}];"
},
"typeVersion": 2
},
{
"id": "8056958e-6330-4938-b2b2-939e3a08779e",
"name": "Log Invalid Rows",
"type": "n8n-nodes-base.set",
"position": [
700,
60
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "cbd19052-996c-432a-bdd4-40c6ba089dce",
"name": "reason",
"type": "string",
"value": "={{ $json.job_url ? ($json.recruiter_email ? ($json.recruiter_name ? 'Unknown validation error' : 'Missing recruiter name') : 'Invalid email format') : 'Missing job URL' }}"
},
{
"id": "2dc2f6ba-926a-4283-b2ec-d8d8d41201f4",
"name": "row_data",
"type": "string",
"value": "={{ JSON.stringify($json) }}"
},
{
"id": "4e3c204a-7096-4b8f-9b34-bb1af2158718",
"name": "status",
"type": "string",
"value": "SKIPPED"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "566fd940-f6bd-4f8c-8d7e-1e86b375ff63",
"name": "Check Weekend",
"type": "n8n-nodes-base.code",
"position": [
880,
-220
],
"parameters": {
"jsCode": "// Check if we should skip weekends\nconst includeWeekends = $('configuration sheet').item.json.INCLUDE_WEEKENDS;\nconst today = new Date();\nconst dayOfWeek = today.getDay(); // 0 = Sunday, 6 = Saturday\n\nif (!includeWeekends && (dayOfWeek === 0 || dayOfWeek === 6)) {\n return {\n json: {\n ...$input.item.json,\n status: 'SKIPPED_WEEKEND',\n skip_reason: 'Weekend execution disabled'\n }\n };\n}\n\nreturn {\n json: {\n ...$input.item.json,\n status: 'PROCESSING'\n }\n};"
},
"typeVersion": 2
},
{
"id": "055be0ef-82ba-42fa-a8e8-88dc89227746",
"name": "Weekend Filter",
"type": "n8n-nodes-base.if",
"position": [
1120,
-200
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "e9e590cf-531f-46d8-ae6a-0307b83e73c3",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "PROCESSING"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "cb2ed435-62d6-47c6-80fe-b9073738fa85",
"name": "Log weekend skip",
"type": "n8n-nodes-base.code",
"position": [
1220,
-500
],
"parameters": {
"jsCode": "return {\n json: {\n ...$input.item.json,\n logged_reason: 'Execution skipped - weekend and INCLUDE_WEEKENDS is false'\n }\n};"
},
"typeVersion": 2
},
{
"id": "084d89b8-3ea1-4b73-95cc-990c47d418c3",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-160,
-240
],
"parameters": {
"width": 300,
"content": "## CONFIGURATION HUB\nTHRESHOLD_DAYS = 30 (change to test)\n- DRY_RUN = false (set true for testing)\n- SPREADSHEET_ID = your sheet ID\n- INCLUDE_WEEKENDS = true"
},
"typeVersion": 1
},
{
"id": "b54e6d67-d203-4970-850b-aee5e262b1c0",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
400,
-220
],
"parameters": {
"width": 280,
"content": "## 🚨 DATA VALIDATION CHECKPOINT\n- Non-empty job_url\n- Valid email format\n- Non-empty recruiter_name"
},
"typeVersion": 1
},
{
"id": "49dd1f84-ad4c-460c-8848-915bf955f965",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
820,
-400
],
"parameters": {
"content": "## WEEKEND LOGIC \nIf INCLUDE_WEEKENDS = false:\n- Saturday/Sunday → status = 'SKIPPED_WEEKEND'\n- Weekdays → status = 'PROCESSING'"
},
"typeVersion": 1
},
{
"id": "7cb61d6a-8db3-499e-ae0b-4375e3f66eb1",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1220,
200
],
"parameters": {
"width": 280,
"height": 180,
"content": "## 🌐 HEAD REQUEST FOR HEADERS \nFetches Last-Modified header from job URLs\n⏱️ Timeout: 10 seconds\n🔄 Retries: 2 attempts\n📡 User-Agent: n8n-job-checker/1."
},
"typeVersion": 1
},
{
"id": "245d21f0-55f0-4a2e-8345-fce982d24044",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1700,
200
],
"parameters": {
"width": 260,
"height": 180,
"content": "## AGE CALCULATION ENGINE\n- Parse last_modified date\n- Compare with current date \n- Return difference in days\n- If error → age_days = 0"
},
"typeVersion": 1
},
{
"id": "6d313a45-5953-434d-aae0-02db2d324502",
"name": "configuration sheet",
"type": "n8n-nodes-base.set",
"position": [
140,
-40
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "1e96273a-d891-44c4-b433-2a11840b8c63",
"name": "SPREADSHEET_ID",
"type": "string",
"value": "1n_AIqOd10Q0ErQZSO4q4LBMekwgsR4cP7EW2q9nEzdk"
},
{
"id": "0aae4a91-f153-4493-a9a8-9a2023e4f158",
"name": "SOURCE_SHEET",
"type": "string",
"value": "Job Posts"
},
{
"id": "802cb08e-cfec-4a40-9236-afea62476136",
"name": "TIMEZONE",
"type": "string",
"value": "Asia/Kolkata"
},
{
"id": "708470ef-5283-4440-9db7-4bd9336ed468",
"name": "THRESHOLD_DAYS",
"type": "number",
"value": 30
},
{
"id": "2cfbcdc6-7b00-4f6c-baf4-a9b37016ac8c",
"name": "USER_AGENT",
"type": "string",
"value": "n8n-job-checker/1.0"
},
{
"id": "639af2e4-08f4-4153-9dc0-dc5abac95346",
"name": "HTTP_TIMEOUT_SECONDS",
"type": "number",
"value": 10
},
{
"id": "4fcad7fb-adeb-4c7a-a165-20a2c5ae3788",
"name": "HTTP_RETRIES",
"type": "number",
"value": 2
},
{
"id": "1ea69c95-e131-45ca-8e4a-ee005608a66e",
"name": "RATE_LIMIT_HTTP_SECONDS",
"type": "number",
"value": 5
},
{
"id": "b8ca4dcd-cf18-4732-8b33-c9341d38811c",
"name": "RATE_LIMIT_EMAIL_SECONDS",
"type": "number",
"value": 2
},
{
"id": "fbaed34b-a618-45ec-883c-7ee89dc2932f",
"name": "SMTP_FROM",
"type": "string",
"value": "hiring-ops@company.com"
},
{
"id": "b3f745cb-b5d2-43e9-a7a1-803fc0646274",
"name": "SUBJECT_TEMPLATE",
"type": "string",
"value": "Please review your stale job post"
},
{
"id": "03bb79a9-6115-402d-a88a-de24bdaf6016",
"name": "HTML_TEMPLATE",
"type": "string",
"value": "<p>Hello {{recruiter_name}},</p><p>Your job post at {{job_url}} is {{age_days}} days old (last updated on {{last_modified}}). Consider updating it.</p>"
},
{
"id": "7fa7d589-8e71-4de4-80bc-fe8bd2c91f1f",
"name": "TEXT_TEMPLATE",
"type": "string",
"value": "Hi {{recruiter_name}}, your job {{job_url}} is {{age_days}} days old. Last updated on {{last_modified}}."
},
{
"id": "4355e287-bbe4-4e82-a2bd-1cd086dc79db",
"name": "INCLUDE_WEEKENDS",
"type": "boolean",
"value": true
},
{
"id": "74a3dd62-e07d-4878-8ca6-ea6c5fc603d8",
"name": "DRY_RUN",
"type": "boolean",
"value": false
}
]
}
},
"typeVersion": 3.4
},
{
"id": "b39b18bf-b1d6-4ddb-bed9-02907d288347",
"name": "configure mapping",
"type": "n8n-nodes-base.set",
"position": [
1560,
40
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "f576e9b1-c210-4f5f-bfcc-0e82d08e776a",
"name": "last_modified",
"type": "string",
"value": "={{ $json.headers && $json.headers['last-modified'] ? $json.headers['last-modified'] : 'Unknown' }}"
},
{
"id": "0ca59df2-775d-4a56-bd38-2b40d7ee3400",
"name": "recruiter_email",
"type": "string",
"value": "=={{ $json.recruiter_email }}"
},
{
"id": "7bfbd56a-df82-4c80-aff1-b0916c09c8ef",
"name": "recruiter_name",
"type": "string",
"value": "={{ $json.recruiter_name }}"
},
{
"id": "f0246fc4-54a2-442d-9d27-17e3e9f23edf",
"name": "job_url",
"type": "string",
"value": "={{ $json.job_url }}"
}
]
}
},
"typeVersion": 3.4
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "db387692-2684-4f88-9ec4-793201e5eeec",
"connections": {
"d26e7e33-fc11-4674-81a7-8e8335998570": {
"main": [
[]
]
},
"e6bb385d-a4b3-48b7-995e-8ad55a06357b": {
"main": [
[
{
"node": "b39b18bf-b1d6-4ddb-bed9-02907d288347",
"type": "main",
"index": 0
}
]
]
},
"566fd940-f6bd-4f8c-8d7e-1e86b375ff63": {
"main": [
[
{
"node": "055be0ef-82ba-42fa-a8e8-88dc89227746",
"type": "main",
"index": 0
}
]
]
},
"1d6141d4-a6b8-425f-8543-c3ae6207a12d": {
"main": [
[
{
"node": "85d9b757-910b-4fef-874f-abea9ebbae81",
"type": "main",
"index": 0
}
]
]
},
"70241c9f-d0df-4907-9a77-045436521635": {
"main": [
[
{
"node": "d21a1bde-5c2f-45cc-b729-7cbf9d378d1d",
"type": "main",
"index": 0
}
]
]
},
"055be0ef-82ba-42fa-a8e8-88dc89227746": {
"main": [
[
{
"node": "48022cb5-72dd-45f8-aabf-b90c55310dd3",
"type": "main",
"index": 0
}
],
[
{
"node": "cb2ed435-62d6-47c6-80fe-b9073738fa85",
"type": "main",
"index": 0
}
]
]
},
"8056958e-6330-4938-b2b2-939e3a08779e": {
"main": [
[]
]
},
"86114cf9-db36-4ed0-bd20-cead6465ca95": {
"main": [
[
{
"node": "6d313a45-5953-434d-aae0-02db2d324502",
"type": "main",
"index": 0
}
]
]
},
"48022cb5-72dd-45f8-aabf-b90c55310dd3": {
"main": [
[
{
"node": "e6bb385d-a4b3-48b7-995e-8ad55a06357b",
"type": "main",
"index": 0
}
]
]
},
"b39b18bf-b1d6-4ddb-bed9-02907d288347": {
"main": [
[
{
"node": "1d6141d4-a6b8-425f-8543-c3ae6207a12d",
"type": "main",
"index": 0
}
]
]
},
"d21a1bde-5c2f-45cc-b729-7cbf9d378d1d": {
"main": [
[
{
"node": "566fd940-f6bd-4f8c-8d7e-1e86b375ff63",
"type": "main",
"index": 0
}
],
[
{
"node": "8056958e-6330-4938-b2b2-939e3a08779e",
"type": "main",
"index": 0
}
]
]
},
"6d313a45-5953-434d-aae0-02db2d324502": {
"main": [
[
{
"node": "70241c9f-d0df-4907-9a77-045436521635",
"type": "main",
"index": 0
}
]
]
},
"85d9b757-910b-4fef-874f-abea9ebbae81": {
"main": [
[
{
"node": "d26e7e33-fc11-4674-81a7-8e8335998570",
"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?
Experte - Personalwesen, Verschiedenes, 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