
Smart LinkedIn Job Filtering with Google Gemini, CV Matching, and Google Maps
描述
分类
📊 Productivity🤖 AI & Machine Learning
使用的节点
n8n-nodes-base.ifn8n-nodes-base.ifn8n-nodes-base.ifn8n-nodes-base.ifn8n-nodes-base.ifn8n-nodes-base.setn8n-nodes-base.noOpn8n-nodes-base.noOpn8n-nodes-base.supabasen8n-nodes-base.telegram
价格免费
浏览量0
最后更新11/28/2025
workflow.json
{
"meta": {
"instanceId": "afca6c018fd85ecd6bb793dc620b1f9d2de9ea7edb2532dd2708b1a0cf01d640",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "0d1ee8d1-e28c-47e6-9d60-185de0d0dcc2",
"name": "Config",
"type": "n8n-nodes-base.set",
"position": [
-416,
16
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "171ff4c5-b238-4b4c-8a27-a5a9564bd673",
"name": "MyCV",
"type": "string",
"value": "YOUR FULL TEXT CV HERE!"
},
{
"id": "2be3ae0b-02f0-40c7-955f-e71b7a2881bc",
"name": "JobKeywords",
"type": "string",
"value": "AI Integration"
},
{
"id": "b062eed9-9fbd-4f45-9117-0ccd4b5d53db",
"name": "ExperienceLevel",
"type": "string",
"value": "mid_senior"
},
{
"id": "5808ab43-3551-42a0-b677-535b29bebf6c",
"name": "JobsToScrape",
"type": "number",
"value": 20
},
{
"id": "9076e2c5-2e23-41f5-bb73-04ab4534b960",
"name": "HomeLocation",
"type": "string",
"value": "Breda, Netherlands"
},
{
"id": "12b91df8-f52d-41b8-b18d-5d378942281f",
"name": "MaxCommuteMinutes",
"type": "number",
"value": 75
},
{
"id": "5d06b164-8c25-4e3d-8739-1900d9a4c7db",
"name": "TargetLanguage",
"type": "string",
"value": "English"
},
{
"id": "934fbe29-f5f0-4ca1-97ad-4e2c28e46b92",
"name": "Under10Applicants",
"type": "string",
"value": false
},
{
"id": "3f789658-2cfd-4c3e-9d7c-749d9e79fa65",
"name": "ActorId",
"type": "string",
"value": "apimaestro~linkedin-jobs-scraper-api"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "671cf8fb-b319-4e82-99ae-181f89aa936b",
"name": "Scrape LinkenIn Jobs",
"type": "n8n-nodes-base.httpRequest",
"position": [
-192,
16
],
"parameters": {
"url": "=https://api.apify.com/v2/acts/{{ $json.ActorId }}/run-sync-get-dataset-items",
"method": "POST",
"options": {},
"jsonBody": "={\n \"date_posted\": \"day\",\n \"experienceLevel\": {{ $json.ExperienceLevel.toJsonString() }},\n \"keywords\": {{ $json.JobKeywords.toJsonString() }},\n \"limit\": {{ $json.JobsToScrape }},\n \"under_10_applicants\": {{ $json.Under10Applicants.toJsonString() }},\n \"sort\": \"relevant\",\n \"location\": \"91000000\",\n \"page_number\": 1\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth"
},
"credentials": {
"httpBearerAuth": {
"id": "Fu6O8UOTEpfPXgyP",
"name": "Apify"
}
},
"typeVersion": 4.2
},
{
"id": "47daec05-16be-4502-a183-a444b534bada",
"name": "Done!",
"type": "n8n-nodes-base.noOp",
"position": [
224,
-320
],
"parameters": {},
"typeVersion": 1
},
{
"id": "f09488e4-11b0-456c-92f2-e6804b64ea75",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
544,
272
],
"parameters": {
"jsonSchemaExample": "{\n\"jobLanguage\": \"English\",\n\"confirmed_seniority\": \"mid_senior\",\n\"is_match\": true\n}"
},
"typeVersion": 1.3
},
{
"id": "62f689ec-b638-4feb-8ada-74ff30cddf13",
"name": "If Seniority Match",
"type": "n8n-nodes-base.if",
"position": [
880,
32
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "d1f7b9b9-4fd1-44d2-b799-5fae8bcee7be",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.output.confirmed_seniority }}",
"rightValue": "={{ $('Config').item.json.ExperienceLevel }}"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "3ec3aea3-2639-4afb-a261-f81eaf0c13af",
"name": "Deconstruct Job Data",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
384,
32
],
"parameters": {
"text": "=You are an expert HR data analyst. Your task is to validate the seniority level of a job posting based on its full description.\n\nThe job was originally tagged with the seniority level: \"{{ $('Config').item.json.ExperienceLevel }}\"\n\nAnalyze the full job description below and determine if this tag is accurate.\n\nReturn ONLY a valid JSON object with these fields:\n- \"jobLanguage\": The primary language of the text.\n- \"confirmed_seniority\": The most accurate seniority level based on your analysis of the text. You MUST choose one from: [\"internship\", \"entry\", \"associate\", \"mid_senior\", \"director\", \"executive\"].\n- \"is_match\": A boolean (true/false) indicating if your confirmed_seniority matches the original tag.\n\nJob Description:\n\"\"\"\n{{ $('Items Loop').first().json.description }}\n\"\"\"",
"options": {},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.2
},
{
"id": "78600425-b859-4c2b-b416-669bd7f6f4ce",
"name": "If Language Match",
"type": "n8n-nodes-base.if",
"position": [
1136,
16
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "09fadd6c-b339-4173-84f4-aa0b50e3706c",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $('Config').item.json.TargetLanguage.toLowerCase().split(', ').includes($('Deconstruct Job Data').item.json.output.jobLanguage.toLowerCase()) }}",
"rightValue": "={{ $json.output.jobLanguage.toLowerCase() }}"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "1c49665e-3444-4528-85e2-5fa2f6f1547a",
"name": "Google Gemini",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
368,
272
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"id": "vppVWKsiofTY92Ht",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "fd7deb25-14f0-42dc-bb6f-c02a5dcd9314",
"name": "If is not Remote",
"type": "n8n-nodes-base.if",
"position": [
1392,
0
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "95ad2f86-418a-4e1d-99df-75ef6037b072",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $('Items Loop').first().json.work_type.toLowerCase() }}",
"rightValue": "remote"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "9500741a-7fff-41ec-ba2c-3d3690b3e779",
"name": "Get Commute Time",
"type": "n8n-nodes-base.httpRequest",
"position": [
1744,
-224
],
"parameters": {
"url": "=https://maps.googleapis.com/maps/api/directions/json",
"options": {},
"sendQuery": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpQueryAuth",
"queryParameters": {
"parameters": [
{
"name": "origin",
"value": "={{ $('Config').item.json.HomeLocation }}"
},
{
"name": "destination",
"value": "={{ $('Items Loop').first().json.location }}"
}
]
}
},
"credentials": {
"httpQueryAuth": {
"id": "p2ihhJSPgggiFXnI",
"name": "Google Direction Key"
}
},
"typeVersion": 4.2
},
{
"id": "d8b75d80-fbd0-4a4a-b4ac-35843bbc5e48",
"name": "Is Commute Acceptable",
"type": "n8n-nodes-base.if",
"position": [
1952,
-224
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "6717790e-4c69-434c-afcc-d33cbe362789",
"operator": {
"type": "number",
"operation": "lte"
},
"leftValue": "={{ $json.routes[0].legs[0].duration.value }}",
"rightValue": "={{ $('Config').item.json.MaxCommuteMinutes * 60 }}"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "c2b71945-4bf2-48b4-be34-104bbf7e8208",
"name": "Google Gemini Deep Analysis",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
2464,
240
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"id": "vppVWKsiofTY92Ht",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "a09b3dc1-a6d2-402d-be2e-1dcd2c7d05a1",
"name": "Structured Output Parser Deep Analysis",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
2656,
240
],
"parameters": {
"jsonSchemaExample": "{\n \"summary\": \"A 2-bullet point summary.\",\n \"key_skills\": [\"skill1\",\"skill2\"],\n \"match_score\": 5,\n \"salaryInfo\": \"The extracted salary range\",\n \"reasoning\": \"A one-sentence explanation for the score.\"\n}"
},
"typeVersion": 1.3
},
{
"id": "b114ccb2-6d92-4e70-bd6b-dbf96379974b",
"name": "Save Data",
"type": "n8n-nodes-base.supabase",
"position": [
3056,
16
],
"parameters": {
"tableId": "job_tracker",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "jobTitle",
"fieldValue": "={{ $('Items Loop').first().json.job_title }}"
},
{
"fieldId": "companyName",
"fieldValue": "={{ $('Items Loop').first().json.company }}"
},
{
"fieldId": "matchScore",
"fieldValue": "={{ $json.output.match_score }}"
},
{
"fieldId": "aiSummary",
"fieldValue": "={{ $json.output.summary }}"
},
{
"fieldId": "jobURL",
"fieldValue": "={{ $('Items Loop').first().json.job_url }}"
},
{
"fieldId": "salaryInfo",
"fieldValue": "={{ $json.output.salaryInfo }}"
},
{
"fieldId": "aiReasoning",
"fieldValue": "={{ $json.output.reasoning }}"
},
{
"fieldId": "applyURL",
"fieldValue": "={{ $('Items Loop').first().json.apply_url }}"
}
]
}
},
"credentials": {
"supabaseApi": {
"id": "0Oe2tNApQI5QNswJ",
"name": "Supabase account"
}
},
"typeVersion": 1
},
{
"id": "7f9b8050-305b-4bf0-a587-3816d7d11723",
"name": "If Has High Match Score",
"type": "n8n-nodes-base.if",
"position": [
3264,
16
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "64d17e00-bada-41e9-918c-f507a1e59df9",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $('AI Deep Analysis').item.json.output.match_score }}",
"rightValue": 8
}
]
}
},
"typeVersion": 2.2
},
{
"id": "96b8e300-cb29-4ded-ad55-8b6c4cedacae",
"name": "AI Deep Analysis",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2480,
16
],
"parameters": {
"text": "=Here is the candidate's resume and the job description. Please perform your analysis.\n---\n**Candidate's Resume:**\n\"\"\"\n{{ $('Config').first().json.MyCV }}\n\"\"\"\n---\n**Job Description:**\n\"\"\"\n{{ $('Items Loop').first().json.description }}\n\"\"\"",
"options": {
"systemMessage": "=You are an expert career coach and HR specialist. Your task is to analyze a candidate's resume against a job description and provide a detailed, structured analysis.\n\nReturn ONLY a valid JSON object with the following structure:\n{\n \"summary\": \"A 2-bullet point summary of the role's main responsibilities.\",\n \"key_skills\": [\"An array of the top 5 most important skills required for this job.\"],\n \"match_score\": \"An integer from 1 to 10 of how well the resume matches the job requirements.\",\n \"salaryInfo\": \"The extracted salary range or the string 'Not specified' if no salary is mentioned.\",\n \"reasoning\": \"A one-sentence explanation for the score, highlighting a key strength or a potential gap in the resume.\"\n}"
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.2
},
{
"id": "ad6f8535-342b-4db8-b0d9-9b761c56ed62",
"name": "Items Loop",
"type": "n8n-nodes-base.splitInBatches",
"position": [
16,
16
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "b6beecb9-3cee-4647-9995-942cedc77b42",
"name": "Send a Notification",
"type": "n8n-nodes-base.telegram",
"position": [
3568,
0
],
"webhookId": "57ac8c41-a3bc-4b4e-8e22-adab496b2df0",
"parameters": {
"text": "=🔥 <b>High-Match Job Found! ({{ $('AI Deep Analysis').item.json.output.match_score }}/10)</b>\n\n<b>{{ $('Items Loop').item.json.job_title }}</b> at <b>{{ $('Items Loop').item.json.company }}</b>\n\n<b>AI Reasoning:</b>\n<i>{{ $('AI Deep Analysis').item.json.output.reasoning }}</i>\n\n<b>Key Skills:</b>\n<code>{{ $('AI Deep Analysis').item.json.output.key_skills.join(', ') }}</code>\n\n<b>Salary:</b> <code>{{ $('AI Deep Analysis').item.json.output.salaryInfo }}</code>\n\n<a href=\"{{ $('Items Loop').item.json.apply_url }}\">Apply Here</a> | <a href=\"{{ $('Items Loop').item.json.job_url }}\">View Job Description</a>",
"chatId": "-4932341035",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "RDdscBadRkYP5zeG",
"name": "Telegram (n8n)"
}
},
"typeVersion": 1.2
},
{
"id": "191a6567-4fda-46c1-aeb8-9a1d75742a39",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-704,
-80
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 9
}
]
}
},
"typeVersion": 1.2
},
{
"id": "15d4435b-5cd8-4081-af0b-0159d70ba342",
"name": "Manual Executing",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-704,
112
],
"parameters": {},
"typeVersion": 1
},
{
"id": "175efaf6-2194-45e3-99f7-634d75fd7941",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1520,
-416
],
"parameters": {
"color": 5,
"width": 704,
"height": 960,
"content": "## ⚙️ Workflow Configuration\n\nThis node is the **central control panel** for the workflow. All settings are managed here.\n\n### **MyCV**\nPaste the full text of your CV/resume here. This is used by the AI to compare your skills against the job requirements.\n\n### **JobKeywords**\nSearch keywords for jobs (e.g., \"engineer\", \"product manager\").\n\n### **JobsToScrape**\nThe maximum number of relevant job postings to scrape in each run.\n\n### **HomeLocation**\nYour home city and country (e.g., \"Breda, Netherlands\"). This is used as the starting point for calculating commute times for hybrid or onsite jobs.\n\n### **MaxCommuteMinutes**\nYour personal maximum one-way commute time in minutes. The workflow will filter out any jobs that require a longer travel time.\n\n### **TargetLanguage**\nYour preferred language for job postings. The workflow will filter out any jobs not written in this language. You can list multiple languages, separated by a comma.\n\n### **ExperienceLevel**\nThe seniority level you are looking for. The AI will validate this against the job description.\n\nThe value can be:\n```\n\"\" → (Any)\n\"internship\" → (Internship)\n\"entry\" → (Entry Level)\n\"associate\" → (Associate)\n\"mid_senior\" → (Mid-Senior Level)\n\"director\" → (Director)\n\"executive\" → (Executive)\n```\n### **Under10Applicants**\nSet to `true` if you only want to see jobs with fewer than 10 applicants. Set to `false` to see all jobs."
},
"typeVersion": 1
},
{
"id": "59daed62-8690-42a8-a3e4-ec59269a0271",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
224,
-160
],
"parameters": {
"color": 3,
"width": 560,
"height": 576,
"content": "## 🤖 AI Triage: The First Filter\nThis AI Agent acts as a quick HR screener. It reads the full job description and extracts key structured data (language, seniority, is match) that we use for the initial filtering steps. This is a fast and cheap way to eliminate bad fits."
},
"typeVersion": 1
},
{
"id": "43c45ff1-6d5a-4513-9370-1e524e443659",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1632,
-416
],
"parameters": {
"color": 4,
"width": 544,
"height": 432,
"content": "## 📍 Geolocation Check\nThis branch handles non-remote jobs. It uses the Google Maps API to calculate the real commute time from the `HomeLocation` set in the config. Only jobs with a commute time under my `MaxCommuteMinutes` will pass this filter."
},
"typeVersion": 1
},
{
"id": "6f4f06c5-9d2a-43d9-8c7d-2521885731e7",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
2288,
-160
],
"parameters": {
"color": 6,
"width": 592,
"height": 560,
"content": "## 🧠 AI Deep Analysis: The CV Match\nThis is the core intelligence of the co-pilot. For the highly-qualified jobs that passed all filters, this AI Agent compares the job description against my full CV (from the Config node). It generates a detailed summary, key skills, and a personalized match score."
},
"typeVersion": 1
},
{
"id": "20bae697-5188-4a27-80ab-27f71b3b9168",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2976,
-160
],
"parameters": {
"width": 752,
"height": 352,
"content": "## ✅ Action & Alerting\nThe final step. All qualified jobs are saved to the Supabase database. If the AI match_score is above the configured threshold (e.g., 8/10), a real-time, detailed alert is sent to my Telegram."
},
"typeVersion": 1
},
{
"id": "d3b4a1c4-7f39-4d9f-95c9-381d91ed9e68",
"name": "To The Next",
"type": "n8n-nodes-base.noOp",
"position": [
3792,
272
],
"parameters": {},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"Config": {
"main": [
[
{
"node": "Scrape LinkenIn Jobs",
"type": "main",
"index": 0
}
]
]
},
"Save Data": {
"main": [
[
{
"node": "If Has High Match Score",
"type": "main",
"index": 0
}
]
]
},
"Items Loop": {
"main": [
[
{
"node": "Done!",
"type": "main",
"index": 0
}
],
[
{
"node": "Deconstruct Job Data",
"type": "main",
"index": 0
}
]
]
},
"To The Next": {
"main": [
[
{
"node": "Items Loop",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini": {
"ai_languageModel": [
[
{
"node": "Deconstruct Job Data",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"AI Deep Analysis": {
"main": [
[
{
"node": "Save Data",
"type": "main",
"index": 0
}
]
]
},
"Get Commute Time": {
"main": [
[
{
"node": "Is Commute Acceptable",
"type": "main",
"index": 0
}
]
]
},
"If is not Remote": {
"main": [
[
{
"node": "Get Commute Time",
"type": "main",
"index": 0
}
],
[
{
"node": "AI Deep Analysis",
"type": "main",
"index": 0
}
]
]
},
"Manual Executing": {
"main": [
[
{
"node": "Config",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Config",
"type": "main",
"index": 0
}
]
]
},
"If Language Match": {
"main": [
[
{
"node": "If is not Remote",
"type": "main",
"index": 0
}
],
[
{
"node": "Items Loop",
"type": "main",
"index": 0
}
]
]
},
"If Seniority Match": {
"main": [
[
{
"node": "If Language Match",
"type": "main",
"index": 0
}
],
[
{
"node": "Items Loop",
"type": "main",
"index": 0
}
]
]
},
"Send a Notification": {
"main": [
[
{
"node": "To The Next",
"type": "main",
"index": 0
}
]
]
},
"Deconstruct Job Data": {
"main": [
[
{
"node": "If Seniority Match",
"type": "main",
"index": 0
}
]
]
},
"Scrape LinkenIn Jobs": {
"main": [
[
{
"node": "Items Loop",
"type": "main",
"index": 0
}
]
]
},
"Is Commute Acceptable": {
"main": [
[
{
"node": "AI Deep Analysis",
"type": "main",
"index": 0
}
],
[
{
"node": "Items Loop",
"type": "main",
"index": 0
}
]
]
},
"If Has High Match Score": {
"main": [
[
{
"node": "Send a Notification",
"type": "main",
"index": 0
}
],
[
{
"node": "To The Next",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "Deconstruct Job Data",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Google Gemini Deep Analysis": {
"ai_languageModel": [
[
{
"node": "AI Deep Analysis",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Structured Output Parser Deep Analysis": {
"ai_outputParser": [
[
{
"node": "AI Deep Analysis",
"type": "ai_outputParser",
"index": 0
}
]
]
}
}
}