第一轮 Telegram 和 LinkedIn 快速通道 AI 招聘助手
这是一个HR、AI Summarization领域的自动化工作流,包含 55 个节点。主要使用 If、Set、Code、Wait、Merge 等节点。 AI候选人筛选流程:LinkedIn到Telegram,集成Gemini与Apify
- •Telegram Bot Token
- •Google Drive API 凭证
- •可能需要目标 API 的认证凭证
- •Google Sheets API 凭证
- •Google Gemini API Key
使用的节点 (55 个)
{
"id": "FQVkQc57GUYlurVw",
"meta": {
"instanceId": "90dd23d886c9cb675f452d0fb004af6ee783e4e974ef4384cbfad1854c68a875",
"templateCredsSetupCompleted": true
},
"name": "第一轮 Telegram 和 LinkedIn 快速通道 AI 招聘助手",
"tags": [
{
"id": "94yO3JL7wpOZjk3A",
"name": "AI Chatbot",
"createdAt": "2025-10-22T11:21:35.499Z",
"updatedAt": "2025-10-22T11:21:35.499Z"
},
{
"id": "PEnmqZaiZ8C9mjTU",
"name": "AI HR Automation",
"createdAt": "2025-09-14T13:05:40.150Z",
"updatedAt": "2025-09-14T13:05:40.150Z"
},
{
"id": "zuRVEfrAKpTf5tpR",
"name": "Telegram",
"createdAt": "2025-08-15T02:14:41.041Z",
"updatedAt": "2025-08-15T02:14:41.041Z"
}
],
"nodes": [
{
"id": "9914e5d9-f6dd-4a18-b6c5-02f995ef011f",
"name": "从文件提取",
"type": "n8n-nodes-base.extractFromFile",
"position": [
48,
-80
],
"parameters": {
"options": {},
"operation": "pdf"
},
"typeVersion": 1
},
{
"id": "1bca066f-1627-4351-9a0a-178c359cfb50",
"name": "下载选定的职位描述",
"type": "n8n-nodes-base.googleDrive",
"position": [
-304,
-256
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.output.jd_match.jd_file_id }}"
},
"options": {
"googleFileConversion": {
"conversion": {
"docsToFormat": "application/pdf"
}
}
},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "IjoB5flCkLlcfjdH",
"name": "Google Drive account"
}
},
"typeVersion": 3
},
{
"id": "e39f1a98-9266-4023-a819-878f817d2d98",
"name": "职位描述匹配智能体",
"type": "@n8n/n8n-nodes-langchain.agent",
"onError": "continueRegularOutput",
"position": [
-1936,
-272
],
"parameters": {
"text": "=## Candidate's Telegram Message (Prority JD matching method)\n\"{{ $('Receive Telegram Msg to Recruiter Bot').item.json.message.text }}\"\n\n## CANDIDATE LINKEDIN PROFILE (Fallback JD matching method if candidate's Telegram message does not state which role they're applying for)\n{{ JSON.stringify($json, null, 2) }}\n\n## AVAILABLE JOB DESCRIPTIONS:\nUse the Google Drvie tool to see the list of our current job description files and file IDs. They are each aptly named with a job title in the file name.\n\nAnalyze the Telegram message context first, and secondly the candidate's LinkedIn profile data above as a fallback method.\n- Select the SINGLE most appropriate job description if there is one that clearly relates to candidate's Telegram message. \nIF THE CANDIDATE'S TELEGRAM MESSAGE MENTIONS A ROLE THAT IS IDENTICAL OR CLOSELY RELATES TO A JD YOU SEE IN THE LIST PROVIDED, YOU MUST SELECT THAT JD.\n- OR, as the fallback method, select up to a maximum of 3 job descriptions that are a best match to the candidate's LinkedIn profile.\n\n\n## YOUR RESPONSE FORMAT\nReturn your response in this exact JSON format:\n\nFor a Telegram message match:\n {\n \"match_type\": \"telegram_msg_match\",\n \"jd_match\": {\n \"jd_filename\": \"Marketing Director JD\",\n \"jd_file_id\": \"1xxxxxxxxxxxxxxxxxxxxxx\",\n \"confidence\": \"high\"\n }\n }\n\nFor a LinkedIn profile match (up to a maximum of 3 best-match JDs):\n{\n \"match_type\": \"linkedin_profile_match\", \n \"jd_match\": [\n {\n \"jd_filename\": \"Marketing Director JD\",\n \"jd_file_id\": \"2xxxxxxxxxxxxxxxxxxxxxx\"\n },\n {\n \"jd_filename\": \"COO_JD.pdf\", \n \"jd_file_id\": \"3xxxxxxxxxxxxxxxxxxxxxx\"\n },\n {\n \"jd_filename\": \"Sales Enablement Lead - job description.pdf\",\n \"jd_file_id\": \"4xxxxxxxxxxxxxxxxxxxxxx\"\n }\n ]\n}",
"options": {
"systemMessage": "=You are an expert HR tech recruiter. Your task is to match a candidate with the most appropriate job description from as list of job descriptions I provide to you. \n\nAs a priority, you should first try to match a single JD based on the contents of the candidate's Telegram message where possible. \n\nIf the contents of their message do not clearly state a JD or specific role, then you should match up to 3 JDs based on the content of their LinkedIn profile as a fallback method - but you do not have to match always 3: it can be less JDs if there is just 1 or 2 JDs that are only the best fit.\n\n## COMPANY DESCRIPTION\nOur company specialises in providing AI and Automation workflow solutions for small businesses, and we use tools such as n8n, Zapier, OpenAI, Claude Code, Airtable, and more."
},
"promptType": "define",
"hasOutputParser": true
},
"executeOnce": false,
"typeVersion": 2.2
},
{
"id": "14c93c36-cdca-4650-846c-77eb9139d6b1",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2112,
-384
],
"parameters": {
"color": 2,
"width": 1536,
"height": 624,
"content": "## 职位描述(空缺)与候选人 LinkedIn 档案匹配"
},
"typeVersion": 1
},
{
"id": "5ab30ebc-fea5-46e1-a0aa-bf29046213a1",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2112,
272
],
"parameters": {
"width": 1504,
"height": 592,
"content": "## LinkedIn 档案分析与反馈"
},
"typeVersion": 1
},
{
"id": "b686e251-6ed4-4984-bbc4-283d52bed4e7",
"name": "详细职位描述匹配智能体",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-304,
-48
],
"parameters": {
"text": "=Compare this candidate's full LinkedIn profile against the detailed job descriptions provided. There will be a maximum of 3 separate job descriptions that were previously identified as being a best match for this candidate's profile.\n\nSelect the SINGLE best JD match by simply responding with the file name exactly like the input of each file name provided to you.\n\n\n## Candidate's LinkedIn profile\n{{ JSON.stringify($('Set Key LinkedIn Profile Data').item.json.linkedinProfileData, null, 2) }}\n\n\n\n## Pre-matched Job Descriptions\n\nJob Description 1: {{ $('Loop Over Items').all()[0].json.jd_filename }}\n{{ $('Loop Over Items').all()[0].json.text }}\n\n\n{% if $('Loop Over Items').all()[1] %}\nJob Description 2: {{ $('Loop Over Items').all()[1].json.jd_filename }}\n{{ $('Loop Over Items').all()[1].json.text }}\n{% endif %}\n\n\n{% if $('Loop Over Items').all()[2] %}\nJob Description 3: {{ $('Loop Over Items').all()[2].json.jd_filename }}\n{{ $('Loop Over Items').all()[2].json.text }}\n{% endif %}\n\n\n--\n\nSelect the best match and respond in this JSON format:\n{\n \"selected_jd\": {\n \"jd_filename\": \"exact_filename_here\"\n }\n}",
"options": {
"systemMessage": "=You are an expert HR tech recruiter. Your task is to match a candidate's profile based on their LinkedIn profile provided, with the best-fit job description provided from a maximum of 3 job descriptions.\n\n## COMPANY DESCRIPTION\nOur company specialises in providing AI and Automation workflow solutions for small businesses, and we use tools such as n8n, Zapier, OpenAI, Claude Code, Airtable, and more."
},
"promptType": "define",
"hasOutputParser": true
},
"executeOnce": true,
"typeVersion": 2.2
},
{
"id": "5487ce4d-0026-455f-9220-e3634e5b6f79",
"name": "遍历项目",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-1072,
-144
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "7ea5ec43-29b8-4815-96b1-8fad17f88cf8",
"name": "下载选定的职位描述1",
"type": "n8n-nodes-base.googleDrive",
"position": [
-896,
0
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.jd_file_id }}"
},
"options": {
"googleFileConversion": {
"conversion": {
"docsToFormat": "application/pdf"
}
}
},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "IjoB5flCkLlcfjdH",
"name": "Google Drive account"
}
},
"typeVersion": 3
},
{
"id": "a09b357e-9e1a-4beb-9a5b-f2f4339955e1",
"name": "从文件1提取",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-720,
0
],
"parameters": {
"options": {},
"operation": "pdf"
},
"typeVersion": 1
},
{
"id": "c5584a89-5766-4a40-ade5-c801c689f5ae",
"name": "访问职位描述文件",
"type": "n8n-nodes-base.googleDriveTool",
"position": [
-1840,
-64
],
"parameters": {
"filter": {
"folderId": {
"__rl": true,
"mode": "list",
"value": "1UWI0TanlIGOec_d3S2HJzDymT-51BxHm",
"cachedResultUrl": "https://drive.google.com/drive/folders/1UWI0TanlIGOec_d3S2HJzDymT-51BxHm",
"cachedResultName": "Job Descriptions"
}
},
"options": {},
"resource": "fileFolder"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "IjoB5flCkLlcfjdH",
"name": "Google Drive account"
}
},
"typeVersion": 3
},
{
"id": "5568dfe0-ef24-4335-8b78-4d189d0cc8a2",
"name": "为多个职位描述进行转换",
"type": "n8n-nodes-base.code",
"position": [
-1296,
-176
],
"parameters": {
"jsCode": "// Transform structure at input.output if it exists, or process for telegram_msg_match\n if ($json.output.match_type === \"linkedin_profile_match\") {\n // For linkedin_profile_match, map the array - FIX: use jd_match not linkedin_profile_match\n return $json.output.jd_match.map(jd => ({\n jd_filename: jd.jd_filename,\n jd_file_id: jd.jd_file_id\n }));\n } else {\n // For telegram_msg_match, return single item - FIX: use jd_match not telegram_msg_match\n return [{\n jd_filename: $json.output.jd_match.jd_filename,\n jd_file_id: $json.output.jd_match.jd_file_id\n }];\n }"
},
"typeVersion": 2
},
{
"id": "a6a3f28e-183e-460b-a587-3a89fafa1ca8",
"name": "便签6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-576,
-384
],
"parameters": {
"color": 2,
"width": 1344,
"height": 1248,
"content": ""
},
"typeVersion": 1
},
{
"id": "949885c6-2c82-4be6-92e7-7349faca7d89",
"name": "匹配选定的职位描述名称与全文",
"type": "n8n-nodes-base.code",
"position": [
48,
208
],
"parameters": {
"jsCode": "// Get the selected filename from the AI agent output\nconst selectedFilename = $json.output.selected_jd.jd_filename;\n\n// Get all the JD data from the loop output\nconst allJDs = $('Loop Over Items').all();\n\n// Find the matching JD by filename\nconst selectedJD = allJDs.find(jd => jd.json.jd_filename === selectedFilename);\n\nif (!selectedJD) {\n throw new Error(`No JD found with filename: ${selectedFilename}`);\n}\n\n// Return just the selected JD data\nreturn [{\n selected_jd_filename: selectedJD.json.jd_filename,\n selected_jd_file_id: selectedJD.json.jd_file_id,\n selected_jd_text: selectedJD.json.text\n}];"
},
"executeOnce": true,
"typeVersion": 2
},
{
"id": "b36268e4-98f0-4ac2-9e2a-708f5ac0b7eb",
"name": "招聘官评分智能体",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-1968,
448
],
"parameters": {
"text": "=Candidate's LinkedIn Profile:\n{{ JSON.stringify($('Set Key LinkedIn Profile Data').item.json.linkedinProfileData, null, 2) }}\n",
"options": {
"systemMessage": "=# Overview\nYou are an expert sales and technical recruiter specializing in AI, automation, and software roles. You have been given a job description and a candidate's LinkedIn profile. Your task is to analyze the LinkedIn profile data in relation to the job description and provide a detailed screening report.\n\nFocus specifically on how well the candidate matches the core requirements and ideal profile outlined in the job description. Evaluate both technical skill alignment and business-context understanding. Use reasoning grounded in the actual content of the resume and job post – avoid making assumptions.\n\n## Output\nYour output should follow this exact format:\n\nJob Description Matched:\nA simple direct copy of {{ $json.selected_jd_filename }}\n\nCandidate Strengths:\nList the top strengths or relevant qualifications the candidate brings to the table. Be specific.\n\nCandidate Weaknesses:\nList areas where the candidate is lacking or mismatched based on the job description.\n\nRisk Factor:\n- Assign a risk score (Low / Medium / High)\n- Explain the worst-case scenario if this candidate is hired.\n\nReward Factor:\n- Assign a reward score (Low / Medium / High)\n- Describe the best-case scenario – what value could this candidate unlock?\n- Does the candidate appear to be a short-term or long-term fit?\n\nOverall Fit Rating (0–10):\nAssign a number between 0 (terrible match) and 10 (perfect match). Do not give decimals.\n\nJustification for Rating:\nExplain clearly why this candidate received that score. Reference specific LinkedIn profile content and how it aligns or doesn't with the job description.\n\n\n## Job Description\n\nFilename: {{ $json.selected_jd_filename }}\n\nJD content:\n{{ $json.selected_jd_text }}\n"
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.2
},
{
"id": "6db7839e-719d-44c7-b3b5-17798299933a",
"name": "结构化输出解析器-1",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-1664,
-64
],
"parameters": {
"schemaType": "manual",
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"match_type\": {\n \"type\": \"string\",\n \"enum\": [\"telegram_msg_match\", \"linkedin_profile_match\"]\n },\n \"jd_match\": {\n \"oneOf\": [\n {\n \"type\": \"object\",\n \"properties\": {\n \"jd_filename\": {\"type\": \"string\"},\n \"jd_file_id\": {\"type\": \"string\"},\n \"confidence\": {\n \"type\": \"string\",\n \"enum\": [\"high\", \"medium\", \"low\"]\n }\n },\n \"required\": [\"jd_filename\", \"jd_file_id\", \"confidence\"]\n },\n {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"jd_filename\": {\"type\": \"string\"},\n \"jd_file_id\": {\"type\": \"string\"}\n },\n \"required\": [\"jd_filename\", \"jd_file_id\"]\n },\n \"minItems\": 1,\n \"maxItems\": 3\n }\n ]\n }\n },\n \"required\": [\"match_type\", \"jd_match\"]\n }"
},
"typeVersion": 1.3
},
{
"id": "a86fc69f-8052-4474-9d76-ee4988d2f461",
"name": "结构化输出解析器-3",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-1792,
688
],
"parameters": {
"schemaType": "manual",
"inputSchema": "{\n \"name\": \"linkedin_screening_evaluation\",\n \"description\": \"Analyzes a candidate's linkedin profile against a job description and output strengths, weaknesses, risk/reward assessment, and an overall fit score.\",\n \"type\": \"object\",\n \"properties\": {\n \"candidate_strengths\": {\n \"type\": \"array\",\n \"description\": \"A list of specific strengths or qualifications that match the job description. Do not include any special characters.\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"candidate_weaknesses\": {\n \"type\": \"array\",\n \"description\": \"A list of areas where the candidate falls short or lacks alignment with the job requirements. Do not include any special characters.\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"risk_factor\": {\n \"type\": \"object\",\n \"description\": \"An evaluation of the potential risks of hiring this candidate.\",\n \"properties\": {\n \"score\": {\n \"type\": \"string\",\n \"enum\": [\"Low\", \"Medium\", \"High\"],\n \"description\": \"The risk level of hiring this candidate.\"\n },\n \"explanation\": {\n \"type\": \"string\",\n \"description\": \"A brief explanation of the worst-case scenario if the candidate is hired.\"\n }\n },\n \"required\": [\"score\", \"explanation\"]\n },\n \"reward_factor\": {\n \"type\": \"object\",\n \"description\": \"An evaluation of the potential upside of hiring this candidate.\",\n \"properties\": {\n \"score\": {\n \"type\": \"string\",\n \"enum\": [\"Low\", \"Medium\", \"High\"],\n \"description\": \"The reward level of hiring this candidate.\"\n },\n \"explanation\": {\n \"type\": \"string\",\n \"description\": \"A description of the best-case scenario and whether the candidate is a short-term or long-term fit.\"\n }\n },\n \"required\": [\"score\", \"explanation\"]\n },\n \"selected_jd_filename\": {\n \"type\": \"string\",\n \"description\": \"The name of the job description file you are comparing the candidate's LinkedIn profile with.\"\n },\n \"overall_fit_rating\": {\n \"type\": \"integer\",\n \"description\": \"A rating from 0 to 10 indicating how well the candidate matches the job description.\",\n \"minimum\": 0,\n \"maximum\": 10\n },\n \"justification_for_rating\": {\n \"type\": \"string\",\n \"description\": \"A summary explaining why the candidate received the specific fit rating, referencing their LinkedIn profile and job description alignment.\"\n }\n },\n \"required\": [\n \"candidate_strengths\",\n \"candidate_weaknesses\",\n \"risk_factor\",\n \"reward_factor\",\n \"overall_fit_rating\",\n \"justification_for_rating\",\n \"selected_jd_filename\"\n ]\n}"
},
"typeVersion": 1.3
},
{
"id": "3e195903-7d10-47e3-91b2-17574b8dcacb",
"name": "结构化输出解析器-2",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-144,
160
],
"parameters": {
"schemaType": "manual",
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"selected_jd\": {\n \"type\": \"object\",\n \"properties\": {\n \"jd_filename\": {\n \"type\": \"string\",\n \"description\": \"Exact filename of the selected job description\"\n }\n },\n \"required\": [\"jd_filename\"]\n }\n },\n \"required\": [\"selected_jd\"]\n}"
},
"typeVersion": 1.3
},
{
"id": "083be177-e9dd-4469-b501-f76b8c498a11",
"name": "接收 Telegram 消息至招聘机器人",
"type": "n8n-nodes-base.telegramTrigger",
"position": [
-4064,
-256
],
"webhookId": "990ec284-de4f-41e4-a14e-48bd872f403a",
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"id": "3I2ktSZzfwUIQi2T",
"name": "Telegram account"
}
},
"typeVersion": 1.2
},
{
"id": "9fab2352-6fe9-4f12-b86a-c6623f716a03",
"name": "提取 LinkedIn 个人资料信息",
"type": "n8n-nodes-base.httpRequest",
"position": [
-2592,
0
],
"parameters": {
"url": "https://api.apify.com/v2/acts/dev_fusion~linkedin-profile-scraper/runs?token=YOUR_APIFY_API_TOKEN",
"method": "POST",
"options": {},
"jsonBody": "={\n \"profileUrls\": [\n \"{{ $json.possibleProfileUrl }}\"\n ]\n}",
"sendBody": true,
"specifyBody": "json"
},
"typeVersion": 4.2
},
{
"id": "148a5324-f33f-4848-a8d0-2568ece924a3",
"name": "LinkedIn 档案就绪?",
"type": "n8n-nodes-base.if",
"position": [
-3104,
256
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "06eeb15d-c309-4e6a-a790-8c4daf800dc4",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.data.status }}",
"rightValue": "SUCCEEDED"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "0d3015d5-4f7c-4352-b233-4666733bb816",
"name": "等待 LinkedIn 档案",
"type": "n8n-nodes-base.wait",
"position": [
-3568,
528
],
"webhookId": "bf94feb7-e453-4641-b579-9bc046c8f921",
"parameters": {
"amount": 15
},
"typeVersion": 1.1
},
{
"id": "97eea42e-0e47-4494-bceb-c0f172456fc6",
"name": "回复确认消息",
"type": "n8n-nodes-base.telegram",
"position": [
-2816,
-288
],
"webhookId": "3f8f3bcf-4833-4079-ade3-c59c2c39812b",
"parameters": {
"text": "=Hi {{ $('Receive Telegram Msg to Recruiter Bot').item.json.message.chat.first_name }} - Thanks for sharing your LinkedIn profile. We'll review your profile very shortly and let you know our thoughts plus any next steps.\n\nTalent @ YOUR COMPANY NAME",
"chatId": "={{ $('Receive Telegram Msg to Recruiter Bot').item.json.message.chat.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "3I2ktSZzfwUIQi2T",
"name": "Telegram account"
}
},
"typeVersion": 1.2
},
{
"id": "ad85be28-c5c8-4a52-98b4-772317740fc0",
"name": "递增循环计数器",
"type": "n8n-nodes-base.set",
"position": [
-3328,
528
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "75664d80-2196-45b8-ad86-d57e40a3a07c",
"name": "loopCount",
"type": "number",
"value": "={{ ($json.loopCount || 0) + 1 }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "4792c59c-a665-426f-990d-b44155792783",
"name": "初始化循环计数器以轮询完成状态",
"type": "n8n-nodes-base.set",
"position": [
-3936,
256
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "e1b85dbe-05b1-4886-bb4b-7dd62aa64e3a",
"name": "loopCount",
"type": "number",
"value": 0
}
]
}
},
"typeVersion": 3.4
},
{
"id": "7f0e5f13-db43-46ce-a9f2-d5608e0f07d9",
"name": "恢复循环计数器",
"type": "n8n-nodes-base.code",
"position": [
-3408,
256
],
"parameters": {
"jsCode": "// Get loopCount from the node that loops back\n let loopCount = 0;\n try {\n loopCount = $('Checked 10x for LinkedIn Profile Data?').item.json.loopCount || 0;\n } catch (e) {\n // First iteration - use Initialize\n loopCount = $('Initialize Loop Counter to Poll for Completion').item.json.loopCount || 0;\n }\n\n return {\n json: {\n ...$json, // HTTP response\n loopCount: loopCount // Add loopCount back\n }\n };"
},
"typeVersion": 2
},
{
"id": "3e963459-50fd-4326-a2e0-45890e1c10bc",
"name": "已检查 10 次 LinkedIn 档案数据?",
"type": "n8n-nodes-base.if",
"position": [
-3088,
528
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "9e701358-0ccd-48dc-a175-3e7cbfdebbcd",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.loopCount }}",
"rightValue": 10
}
]
}
},
"typeVersion": 2.2
},
{
"id": "fa9b7243-97ff-41a8-a5fc-50ef75e72ad3",
"name": "检查 LinkedIn 档案提取状态",
"type": "n8n-nodes-base.httpRequest",
"position": [
-3696,
256
],
"parameters": {
"url": "=https://api.apify.com/v2/acts/{{ $('Extract LinkedIn Profile Information').item.json.data.actId }}/runs/last?token=YOUR_APIFY_API_TOKEN",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "9f93b9f6-b381-4947-8034-dbf37e5ea8d0",
"name": "获取完全提取的 LinkedIn 档案数据",
"type": "n8n-nodes-base.httpRequest",
"position": [
-2832,
240
],
"parameters": {
"url": "=https://api.apify.com/v2/acts/{{ $json.data.actId }}/runs/last/dataset/items?token=YOUR_APIFY_API_TOKEN",
"options": {}
},
"executeOnce": true,
"typeVersion": 4.2
},
{
"id": "4c5e2b97-4c1c-40db-9d4f-89c51c03c939",
"name": "回复错误/重试消息",
"type": "n8n-nodes-base.telegram",
"position": [
-3584,
-64
],
"webhookId": "42323965-c322-46f4-9309-f7768eaefa09",
"parameters": {
"text": "=Hi {{ $json.message.chat.first_name }} - thanks for getting in touch - we're unable to verify the LinkedIn profile URL you shared. Can you double check it and try sending us your LinkedIn profile URL again?\n\nNote that the format should look like: https://www.linkedin.com/in/williamhgates\n\nTalent @ YOUR COMPANY NAME",
"chatId": "={{ $json.message.chat.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "3I2ktSZzfwUIQi2T",
"name": "Telegram account"
}
},
"typeVersion": 1.2
},
{
"id": "9075ffb4-1688-41ed-9e58-f21dd6223dd9",
"name": "设置关键 LinkedIn 档案数据",
"type": "n8n-nodes-base.set",
"position": [
-2384,
240
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "9745b346-6484-4b22-9fe6-fccd0446c60d",
"name": "linkedinProfileData",
"type": "object",
"value": "={{ $json }}"
},
{
"id": "a29a37a6-bef8-4c24-ac9d-f4a2f5528bba",
"name": "dateShared",
"type": "string",
"value": "={{ $now.toUTC().toFormat('yyyy-LL-dd HH:mm') }}"
}
]
}
},
"executeOnce": true,
"typeVersion": 3.4
},
{
"id": "3b89d395-f178-4163-8709-96e117c996ac",
"name": "设置职位描述数据",
"type": "n8n-nodes-base.set",
"position": [
-560,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "c1376530-e0d7-4ce5-abb7-bd5839a34ecb",
"name": "jd_filename",
"type": "string",
"value": "={{ $('Loop Over Items').item.json.jd_filename }}"
},
{
"id": "85efbcf5-b293-4058-aef6-8a6dfbed1c0a",
"name": "jd_file_id",
"type": "string",
"value": "={{ $('Loop Over Items').item.json.jd_file_id }}"
},
{
"id": "63d88a73-7144-458f-812b-f53ccd8fda49",
"name": "text",
"type": "string",
"value": "={{ $json.text }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "21723055-422d-4103-b65a-4811baa34300",
"name": "设置选定的职位描述格式",
"type": "n8n-nodes-base.set",
"position": [
528,
448
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "271dc7a2-e8c3-40f7-9e7c-04c4463490f0",
"name": "selected_jd_filename",
"type": "string",
"value": "={{ $('JD Match w/Telegram Msg?').item.json.output.email_match.jd_filename }}"
},
{
"id": "2e987315-7b9b-47ca-a2ca-400978944b7a",
"name": "selected_jd_file_id",
"type": "string",
"value": "={{ $('JD Match w/Telegram Msg?').item.json.output.email_match.jd_file_id }}"
},
{
"id": "f9d90d18-8193-46d0-a9b2-a3fe4edcd7e5",
"name": "selected_jd_text",
"type": "string",
"value": "={{ $json.text }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "87cebfda-e8b8-4e5d-9236-a1db16114fc5",
"name": "便签 3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-4192,
-384
],
"parameters": {
"color": 6,
"width": 2048,
"height": 1248,
"content": "## 通过 Telegram 获取 LinkedIn 档案"
},
"typeVersion": 1
},
{
"id": "8903e8c4-5ae9-4d61-a426-7ed450a96c43",
"name": "发送消息至内部人才群组",
"type": "n8n-nodes-base.telegram",
"position": [
-2592,
-288
],
"webhookId": "ac4316a1-1e1b-4f91-8a5e-d1d4e5d9bdd4",
"parameters": {
"text": "={{\n (() => {\n // Get the Telegram trigger payload safely (works even if it's pinned)\n const trig = $('Receive Telegram Msg to Recruiter Bot').first().json || {};\n const msg = trig.message || trig.update?.message || {};\n\n // Prefer \"from.username\"; fall back to \"chat.username\"\n const username = msg.from?.username ?? msg.chat?.username ?? '';\n const first = msg.chat?.first_name ?? msg.from?.first_name ?? '';\n const said = msg.text ?? '';\n\n // HTML escape for Parse Mode = HTML\n const esc = s => (s ?? '').toString().replace(/[&<>]/g, c => ({'&':'&','<':'<','>':'>'}[c]));\n\n return (\n`FYI - I've started the review of a new candidate's LinkedIn profile based on their message to me directly.\n\nName: ${esc(first)}\nTelegram Username: <code>${esc(username)}</code>\n\nHere's what they said:\n\"${esc(said)}\"\n\nI'll let you know here once the review is complete.`\n );\n })()\n}}",
"chatId": "YOUR_TELEGRAM_INTERNAL_GROUP_CHAT_ID",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "3I2ktSZzfwUIQi2T",
"name": "Telegram account"
}
},
"typeVersion": 1.2
},
{
"id": "0db07b5d-cdce-4020-8d78-77ce2508491b",
"name": "发送审查完成消息至人才群组",
"type": "n8n-nodes-base.telegram",
"position": [
-880,
432
],
"webhookId": "f50c285c-e6ea-4c19-a193-889c17c89a9e",
"parameters": {
"text": "={{\n (() => {\n const esc = s => (s ?? '').toString().replace(/[&<>]/g, c => ({'&':'&','<':'<','>':'>'}[c]));\n const first = esc($json[\"First Name\"]);\n const last = esc($json[\"Last Name\"]);\n const user = esc($json[\"Telegram Username\"]);\n const date = esc($json[\"Date\"]);\n const jd = esc($json[\"JD Match\"]);\n const fit = esc($json[\"Overall Fit\"]);\n const sub = esc($json[\"Submission ID\"]);\n const url = \"https://docs.google.com/spreadsheets/d/19ZzSG-MyFgdvruWhTozuimYBG-QSvaPhHmqMJqdmJpM/edit?usp=sharing\";\n\n return `We've completed the AI candidate screening for <b>${first} ${last}</b> (Telegram username: <code>${user}</code>), who shared their LinkedIn profile with us on ${date}.` +\n `\\n\\nWe matched this person with the JD: <b>${jd}</b>, and rated their overall fit for this role as <b>${fit}</b>/10.` +\n `\\n\\nFull details of our analysis of the candidate can be found under submission ID <code>${sub}</code> in this <a href=\"${url}\">Google Sheet</a>.`;\n })()\n}}",
"chatId": "=YOUR_TELEGRAM_INTERNAL_GROUP_CHAT_ID",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "3I2ktSZzfwUIQi2T",
"name": "Telegram account"
}
},
"typeVersion": 1.2
},
{
"id": "de46c695-e870-444e-903d-0efa2d60a94e",
"name": "Gemini 2.5 Pro-3",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
-2000,
688
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.5-pro"
},
"credentials": {
"googlePalmApi": {
"id": "etClcv7ej0yswPTF",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "77100aff-9497-4915-b803-b55733a0ecb3",
"name": "Gemini 2.5 Pro-2",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
-336,
160
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.5-pro"
},
"credentials": {
"googlePalmApi": {
"id": "etClcv7ej0yswPTF",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "e5af9a04-fa2a-45da-9758-a66b013114e9",
"name": "Gemini 2.5 Pro-1",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
-2000,
-64
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.5-pro"
},
"credentials": {
"googlePalmApi": {
"id": "etClcv7ej0yswPTF",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "2773b269-bddd-4ff2-8eb4-b626ee712698",
"name": "收集并设置最终数据",
"type": "n8n-nodes-base.set",
"position": [
-1376,
432
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "c4820f4c-f4ff-4cd8-9f62-ee9a959a6efd",
"name": "submission_ID",
"type": "string",
"value": "={{\n (\n ( $json?.linkedinProfileData?.lastName ?? 'unknown' ) + ''\n )\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '') // sanitize\n + '_' +\n new Date().toISOString().replace(/[-:TZ.]/g, '').slice(0,14) // UTC YYYYMMDDHHmmss\n}}"
},
{
"id": "51631060-f04b-4fc9-af2f-31133dad0eec",
"name": "telegram_username",
"type": "string",
"value": "={{ $('Receive Telegram Msg to Recruiter Bot').first().json?.message?.chat?.username }}"
},
{
"id": "1c3c43ee-89df-4dd9-8b42-138f68a52274",
"name": "email",
"type": "string",
"value": "={{ $json.linkedinProfileData.email }}"
},
{
"id": "94829fe4-ac08-4ad6-9ff2-0b3791aadb0b",
"name": "first_name",
"type": "string",
"value": "={{ $json.linkedinProfileData.firstName }}"
},
{
"id": "72dab19c-c074-4a63-ada4-b146648aeaba",
"name": "last_name",
"type": "string",
"value": "={{ $json.linkedinProfileData.lastName }}"
},
{
"id": "7e08a276-e356-4f5f-bf3d-9c259216dd00",
"name": "linkedin_profile_url",
"type": "string",
"value": "={{ $json.linkedinProfileData.linkedinUrl }}"
},
{
"id": "5fbe3149-a1f4-49a2-a6ff-6d97ee411703",
"name": "candidate_strengths",
"type": "string",
"value": "={{ $json.output.candidate_strengths.join(\"\\n\\n\") }}"
},
{
"id": "b0e86b60-1797-4c94-bf81-9a2746d41472",
"name": "candidate_weaknesses",
"type": "string",
"value": "={{ $json.output.candidate_weaknesses.join(\"\\n\\n\") }}"
},
{
"id": "dfd2141c-1e30-4587-9815-46f44b13db41",
"name": "risk_factor",
"type": "string",
"value": "={{ $json.output.risk_factor.score }}\n\n{{ $json.output.risk_factor.explanation }}"
},
{
"id": "738ce192-3f62-42b6-8330-9f0021685491",
"name": "=reward_factor",
"type": "string",
"value": "={{ $json.output.reward_factor.score }}\n\n{{ $json.output.reward_factor.explanation }}"
},
{
"id": "c77fc627-e03c-49d0-8a17-05da4166e566",
"name": "selected_jd_filename",
"type": "string",
"value": "={{ $json.output.selected_jd_filename }}"
},
{
"id": "0fda6a01-7100-4f3f-8387-4192f725754c",
"name": "overall_fit_rating",
"type": "string",
"value": "={{ $json.output.overall_fit_rating }}"
},
{
"id": "1304faef-8725-49e4-97d1-9475b5abd40a",
"name": "justification_for_rating",
"type": "string",
"value": "={{ $json.output.justification_for_rating }}"
}
]
}
},
"executeOnce": true,
"typeVersion": 3.4
},
{
"id": "c38679d4-d14d-4b39-894b-1aaee12d8e78",
"name": "合并",
"type": "n8n-nodes-base.merge",
"position": [
-1600,
432
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "637c9812-3f39-419d-8210-b60b025b92c8",
"name": "在 Google 表格中添加候选人分析",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1136,
432
],
"parameters": {
"columns": {
"value": {
"Date": "={{ $now.setZone('UTC').format('yyyy-MM-dd HH:mm') }}",
"JD Match": "={{ $json.selected_jd_filename }}",
"Last Name": "={{ $json.last_name }}",
"Strengths": "={{ $json.candidate_strengths }}",
"First Name": "={{ $json.first_name }}",
"Weaknesses": "={{ $json.candidate_weaknesses }}",
"Overall Fit": "={{ $json.overall_fit_rating }}",
"Risk Factor": "={{ $json.risk_factor }}",
"Justification": "={{ $json.justification_for_rating }}",
"Reward Factor": "={{ $json.reward_factor }}",
"Submission ID": "={{ $json.submission_ID }}",
"Email (if known)": "={{ $json.email }}",
"Telegram Username": "={{ $json.telegram_username }}",
"LinkedIn Profile URL": "={{ $json.linkedin_profile_url }}"
},
"schema": [
{
"id": "Submission ID",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Submission ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "LinkedIn Profile URL",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "LinkedIn Profile URL",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "First Name",
"type": "string",
"display": true,
"required": false,
"displayName": "First Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Last Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Last Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Email (if known)",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Email (if known)",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Telegram Username",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Telegram Username",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Strengths",
"type": "string",
"display": true,
"required": false,
"displayName": "Strengths",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Weaknesses",
"type": "string",
"display": true,
"required": false,
"displayName": "Weaknesses",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Risk Factor",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Risk Factor",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Reward Factor",
"type": "string",
"display": true,
"required": false,
"displayName": "Reward Factor",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "JD Match",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "JD Match",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Overall Fit",
"type": "string",
"display": true,
"required": false,
"displayName": "Overall Fit",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Justification",
"type": "string",
"display": true,
"required": false,
"displayName": "Justification",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/19ZzSG-MyFgdvruWhTozuimYBG-QSvaPhHmqMJqdmJpM/edit#gid=0",
"cachedResultName": "LinkedIn Profile AI Candidate Screening"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "19ZzSG-MyFgdvruWhTozuimYBG-QSvaPhHmqMJqdmJpM",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/19ZzSG-MyFgdvruWhTozuimYBG-QSvaPhHmqMJqdmJpM/edit?usp=drivesdk",
"cachedResultName": "LinkedIn Profile AI Candidate Screening"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "TjOctR8CYkO1SVp8",
"name": "Google Sheets account 2"
}
},
"typeVersion": 4.7
},
{
"id": "c3be847a-df8b-4947-ac45-b0b7b7356f1d",
"name": "启动消息已发送 + 有效的 LinkedIn 档案 URL?",
"type": "n8n-nodes-base.if",
"position": [
-3840,
-256
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a1a72753-9507-46bd-b14e-2179fcf176b1",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $json.message.text }}",
"rightValue": "/start"
},
{
"id": "b6681835-d6d7-4645-81bb-069885672a5b",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.message.text }}",
"rightValue": "linkedin.com/in/"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "90e80421-d74a-40a5-a632-656177579795",
"name": "垃圾邮件检查:已发送 <4 个 LinkedIn 档案?",
"type": "n8n-nodes-base.if",
"position": [
-3152,
-272
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "62ba6eb7-dd7e-4965-88c6-febd5fda4b83",
"operator": {
"type": "number",
"operation": "lte"
},
"leftValue": "={{ $items(\"Get All Rows Matching Telegram Username\").length }}",
"rightValue": 3
}
]
}
},
"executeOnce": false,
"typeVersion": 2.2
},
{
"id": "0687fa9f-2c46-4858-a4a1-4e1783204719",
"name": "回复 - 发送过多 LinkedIn URL 消息",
"type": "n8n-nodes-base.telegram",
"position": [
-3152,
-48
],
"webhookId": "42323965-c322-46f4-9309-f7768eaefa09",
"parameters": {
"text": "=Hi {{ $('Receive Telegram Msg to Recruiter Bot').item.json.message.chat.first_name }} - Apologies - we've detected that you have sent us more than 3 LinkedIn profile URLs either recently or in the past.\n\nWe put this limit in place to help prevent spam.\n\nPlease get in touch with us directly if you have an additional genuine job application you'd like to submit: talent@yourcompany.com\n\nTalent @ YOUR COMPANY NAME",
"chatId": "={{ $('Receive Telegram Msg to Recruiter Bot').item.json.message.from.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"credentials": {
"telegramApi": {
"id": "3I2ktSZzfwUIQi2T",
"name": "Telegram account"
}
},
"typeVersion": 1.2
},
{
"id": "d132d927-781d-4bd2-aca1-ff77d4e0f134",
"name": "获取所有匹配 Telegram 用户名的行",
"type": "n8n-nodes-base.googleSheets",
"position": [
-3584,
-272
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "={{ $json.message.chat.username }}",
"lookupColumn": "Telegram Username"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/19ZzSG-MyFgdvruWhTozuimYBG-QSvaPhHmqMJqdmJpM/edit#gid=0",
"cachedResultName": "LinkedIn Profile AI Candidate Screening"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "19ZzSG-MyFgdvruWhTozuimYBG-QSvaPhHmqMJqdmJpM",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/19ZzSG-MyFgdvruWhTozuimYBG-QSvaPhHmqMJqdmJpM/edit?usp=drivesdk",
"cachedResultName": "LinkedIn Profile AI Candidate Screening"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "TjOctR8CYkO1SVp8",
"name": "Google Sheets account 2"
}
},
"executeOnce": false,
"typeVersion": 4.7
},
{
"id": "543325a6-3cf2-42f5-a64b-95be550296c6",
"name": "统计匹配 Telegram 用户名的行数",
"type": "n8n-nodes-base.summarize",
"position": [
-3360,
-272
],
"parameters": {
"options": {},
"fieldsToSummarize": {
"values": [
{
"field": "Telegram Username"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "6c09a56b-05c8-4e0d-bc7e-dc485dcdb744",
"name": "获取干净的 LinkedIn URL",
"type": "n8n-nodes-base.code",
"position": [
-2816,
-48
],
"parameters": {
"jsCode": "// Function node: extract canonical /in/<slug> profile URL\nconst trig = $('Receive Telegram Msg to Recruiter Bot').first().json || {};\nconst msg = trig.message || trig.update?.message || trig.channel_post || {};\nconst txt = ((msg.text ?? msg.caption ?? '') + '');\n\n// 1) Collect candidates from Telegram entities (most reliable)\nlet candidates = [];\nconst entities = msg.entities ?? msg.caption_entities ?? [];\nfor (const e of entities) {\n if (e.type === 'url') {\n const start = e.offset ?? 0;\n const end = start + (e.length ?? 0);\n candidates.push(txt.slice(start, end));\n } else if (e.type === 'text_link' && e.url) {\n candidates.push(e.url);\n }\n}\n// 2) Fallback: scan the text\nif (!candidates.length) {\n candidates = [...txt.matchAll(/https?:\\/\\/[^\\s<>()]+/gi)].map(m => m[0]);\n}\n\n// 3) Sanitize + extract /in/<slug> (supports /m/in/ and /mwlite/in/)\nconst sanitize = s =>\n (s || '')\n .replace(/[\\p{Z}\\p{C}]+/gu, '') // remove whitespace & control chars (incl. \\n, NBSP, ZWSP)\n .replace(/[)\\].,;!?]+$/, ''); // drop trailing punctuation\n\nconst IN_PROFILE = /linkedin\\.com\\/(?:mwlite\\/|m\\/)?in\\/([A-Za-z0-9._%-]+)/i;\n\nfor (const raw0 of candidates) {\n const raw = sanitize(raw0);\n const m = raw.match(IN_PROFILE);\n if (!m) continue;\n\n const slug = decodeURIComponent(m[1]).replace(/\\/+$/, '');\n if (!slug) continue;\n\n return [{\n json: {\n isLinkedIn: true,\n slug,\n possibleProfileUrl: `https://www.linkedin.com/in/${slug}`,\n sourceUrl: raw\n }\n }];\n}\n\n// Nothing matched\nreturn [{ json: { isLinkedIn: false } }];"
},
"typeVersion": 2
},
{
"id": "8ed28114-ce30-4aab-9847-334a152caac8",
"name": "职位描述匹配与 Telegram 消息?",
"type": "n8n-nodes-base.if",
"position": [
-1504,
-272
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "dde6fee9-e053-49de-aacf-b63f33fabec3",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.output.match_type }}",
"rightValue": "telegram_msg_match"
}
]
}
},
"executeOnce": true,
"typeVersion": 2.2
},
{
"id": "dfcbb685-4a0b-4592-bbdc-a21edc17e7d8",
"name": "便签 5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-3376,
-1328
],
"parameters": {
"color": 7,
"width": 512,
"height": 912,
"content": "## 示例输出"
},
"typeVersion": 1
},
{
"id": "9f0beee4-1ee4-4071-8105-caf6a597edd3",
"name": "便签8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-4192,
-1152
],
"parameters": {
"color": 7,
"width": 784,
"height": 736,
"content": "## 故障排除"
},
"typeVersion": 1
},
{
"id": "2090e260-0749-4ae7-a74a-2d9773416e37",
"name": "便签7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-5264,
-1152
],
"parameters": {
"color": 7,
"width": 1040,
"height": 2544,
"content": "# **第一轮 Telegram + LinkedIn AI 招聘助手**"
},
"typeVersion": 1
},
{
"id": "72520805-103e-4ad9-a009-f412f850250f",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2864,
-1184
],
"parameters": {
"color": 7,
"width": 512,
"height": 768,
"content": "\n\n"
},
"typeVersion": 1
},
{
"id": "ff7070b9-31cb-434e-9019-6b94b59479d5",
"name": "便签12",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2352,
-1184
],
"parameters": {
"color": 7,
"width": 512,
"height": 768,
"content": ""
},
"typeVersion": 1
},
{
"id": "15541650-4176-4810-94a2-a517760f2f00",
"name": "## 试试看!",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1840,
-1232
],
"parameters": {
"color": 7,
"width": 512,
"height": 816,
"content": "### Telegram messages from AI recruiter bot in internal group chat\n\n"
},
"typeVersion": 1
},
{
"id": "be19b3fa-1201-4e8a-a100-5283c633f962",
"name": "便签 14",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1328,
-1184
],
"parameters": {
"color": 7,
"width": 512,
"height": 768,
"content": ""
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"callerPolicy": "workflowsFromSameOwner",
"errorWorkflow": "orVeCnK9KH8GxfmT",
"executionOrder": "v1"
},
"versionId": "2878311a-efcf-40a1-8661-5ddea30fb0a2",
"connections": {
"Merge": {
"main": [
[
{
"node": "Gather and Set Final Data",
"type": "main",
"index": 0
}
]
]
},
"Set JD Data": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Access JD Files": {
"ai_tool": [
[
{
"node": "JD Matching Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[
{
"node": "Detailed JD Matching Agent",
"type": "main",
"index": 0
}
],
[
{
"node": "Download Selected JD1",
"type": "main",
"index": 0
}
]
]
},
"Gemini 2.5 Pro-1": {
"ai_languageModel": [
[
{
"node": "JD Matching Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Gemini 2.5 Pro-2": {
"ai_languageModel": [
[
{
"node": "Detailed JD Matching Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Gemini 2.5 Pro-3": {
"ai_languageModel": [
[
{
"node": "Recruiter Scoring Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Extract from File": {
"main": [
[
{
"node": "Set Selected JD Format",
"type": "main",
"index": 0
}
]
]
},
"JD Matching Agent": {
"main": [
[
{
"node": "JD Match w/Telegram Msg?",
"type": "main",
"index": 0
}
]
]
},
"Extract from File1": {
"main": [
[
{
"node": "Set JD Data",
"type": "main",
"index": 0
}
]
]
},
"Download Selected JD": {
"main": [
[
{
"node": "Extract from File",
"type": "main",
"index": 0
}
]
]
},
"Restore Loop Counter": {
"main": [
[
{
"node": "LinkedIn Profile Ready?",
"type": "main",
"index": 0
}
]
]
},
"Download Selected JD1": {
"main": [
[
{
"node": "Extract from File1",
"type": "main",
"index": 0
}
]
]
},
"Increment Loop Counter": {
"main": [
[
{
"node": "Checked 10x for LinkedIn Profile Data?",
"type": "main",
"index": 0
}
]
]
},
"Set Selected JD Format": {
"main": [
[
{
"node": "Recruiter Scoring Agent",
"type": "main",
"index": 0
}
]
]
},
"Grab Clean LinkedIn URL": {
"main": [
[
{
"node": "Extract LinkedIn Profile Information",
"type": "main",
"index": 0
}
]
]
},
"LinkedIn Profile Ready?": {
"main": [
[
{
"node": "Get Fully Extracted LinkedIn Profile Data",
"type": "main",
"index": 0
}
],
[
{
"node": "Wait for LinkedIn Profile",
"type": "main",
"index": 0
}
]
]
},
"Recruiter Scoring Agent": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"JD Match w/Telegram Msg?": {
"main": [
[
{
"node": "Download Selected JD",
"type": "main",
"index": 0
}
],
[
{
"node": "Transform for Multiple JDs",
"type": "main",
"index": 0
}
]
]
},
"Gather and Set Final Data": {
"main": [
[
{
"node": "Add Candidate Analysis in GSheet",
"type": "main",
"index": 0
}
]
]
},
"Wait for LinkedIn Profile": {
"main": [
[
{
"node": "Increment Loop Counter",
"type": "main",
"index": 0
}
]
]
},
"Detailed JD Matching Agent": {
"main": [
[
{
"node": "Match Selected JD Name with Full Text",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser-1": {
"ai_outputParser": [
[
{
"node": "JD Matching Agent",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Structured Output Parser-2": {
"ai_outputParser": [
[
{
"node": "Detailed JD Matching Agent",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Structured Output Parser-3": {
"ai_outputParser": [
[
{
"node": "Recruiter Scoring Agent",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Transform for Multiple JDs": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Reply with Confirmation Msg": {
"main": [
[
{
"node": "Send Msg to Internal Talent Group",
"type": "main",
"index": 0
}
]
]
},
"Set Key LinkedIn Profile Data": {
"main": [
[
{
"node": "JD Matching Agent",
"type": "main",
"index": 0
},
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Add Candidate Analysis in GSheet": {
"main": [
[
{
"node": "Send Review Completed Msg to Talent Group",
"type": "main",
"index": 0
}
]
]
},
"Extract LinkedIn Profile Information": {
"main": [
[
{
"node": "Initialize Loop Counter to Poll for Completion",
"type": "main",
"index": 0
}
]
]
},
"Count Rows Matching Telegram Username": {
"main": [
[
{
"node": "Spam Check: Sent <4 LinkedIn Profiles?",
"type": "main",
"index": 0
}
]
]
},
"Match Selected JD Name with Full Text": {
"main": [
[
{
"node": "Recruiter Scoring Agent",
"type": "main",
"index": 0
}
]
]
},
"Receive Telegram Msg to Recruiter Bot": {
"main": [
[
{
"node": "Start Msg Sent + Valid LinkedIn Profile URL?",
"type": "main",
"index": 0
}
]
]
},
"Checked 10x for LinkedIn Profile Data?": {
"main": [
[],
[
{
"node": "Check LinkedIn Profile Extraction Status",
"type": "main",
"index": 0
}
]
]
},
"Get All Rows Matching Telegram Username": {
"main": [
[
{
"node": "Count Rows Matching Telegram Username",
"type": "main",
"index": 0
}
]
]
},
"Spam Check: Sent <4 LinkedIn Profiles?": {
"main": [
[
{
"node": "Grab Clean LinkedIn URL",
"type": "main",
"index": 0
},
{
"node": "Reply with Confirmation Msg",
"type": "main",
"index": 0
}
],
[
{
"node": "Reply - Too Many LinkedIn URLs Sent Msg",
"type": "main",
"index": 0
}
]
]
},
"Check LinkedIn Profile Extraction Status": {
"main": [
[
{
"node": "Restore Loop Counter",
"type": "main",
"index": 0
}
]
]
},
"Get Fully Extracted LinkedIn Profile Data": {
"main": [
[
{
"node": "Set Key LinkedIn Profile Data",
"type": "main",
"index": 0
}
]
]
},
"Start Msg Sent + Valid LinkedIn Profile URL?": {
"main": [
[
{
"node": "Get All Rows Matching Telegram Username",
"type": "main",
"index": 0
}
],
[
{
"node": "Reply with Error/Try Again Msg",
"type": "main",
"index": 0
}
]
]
},
"Initialize Loop Counter to Poll for Completion": {
"main": [
[
{
"node": "Check LinkedIn Profile Extraction Status",
"type": "main",
"index": 0
}
]
]
}
}
}如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
这是一个高级难度的工作流,适用于HR、AI Summarization等场景。适合高级用户,包含 16+ 个节点的复杂工作流
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
Dean Pike
@deanjpSaving 20+ hours weekly for growing companies by putting their client-facing and back-office operations on autopilot. As the Founder of TidyCurve, we build AI agents and workflow automations that replace critical repetitive work: from lead generation and customer support, to marketing, recruitment, and onboarding. We deploy scalable solutions in 4-8 weeks at a fraction of enterprise costs - backed by a 60-day 3x ROI guarantee.
分享此工作流