8
n8n 中文网amn8n.com

第一轮快速通道AI招聘助手

高级

这是一个自动化工作流,包含 50 个节点。主要使用 If, Set, Code, Merge, Slack 等节点。 通过Gemini AI分析从Gmail到Slack和Google Sheets的快速简历筛选

前置要求
  • Slack Bot Token 或 Webhook URL
  • Google Drive API 凭证
  • 可能需要目标 API 的认证凭证
  • Google 账号和 Gmail API 凭证
  • Google Sheets API 凭证
  • Google Gemini API Key

分类

-
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "qDFNsMCGATg1FRWI",
  "meta": {
    "instanceId": "90dd23d886c9cb675f452d0fb004af6ee783e4e974ef4384cbfad1854c68a875",
    "templateCredsSetupCompleted": true
  },
  "name": "第一轮快速通道 AI 招聘助手",
  "tags": [],
  "nodes": [
    {
      "id": "67ba2250-7192-46bb-ae03-3f52e52d1212",
      "name": "触发 Google Docs 转换",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1920,
        -208
      ],
      "parameters": {
        "url": "={{ $json.headers.location }}",
        "method": "PUT",
        "options": {
          "response": {
            "response": {
              "fullResponse": true
            }
          }
        },
        "sendBody": true,
        "sendQuery": true,
        "contentType": "binaryData",
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "fields",
              "value": "=id,name,mimeType,webViewLink,parents"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "={{ ( (b => {\n  const fn = (b?.fileName || '').toLowerCase();\n  const mt = (b?.mimeType || '').toLowerCase();\n  if (fn.endsWith('.doc')) return 'application/msword';\n  if (fn.endsWith('.docx')) return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';\n  if (mt && mt !== 'application/octet-stream') return mt;\n  return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';\n})(Object.values($binary || {})[0] || {})).replace(/[\\u0000-\\u001F\\u007F]+/g,'').trim() }}"
            }
          ]
        },
        "inputDataFieldName": "={{ Object.keys($binary || {})[0] }}",
        "nodeCredentialType": "googleDriveOAuth2Api"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "IjoB5flCkLlcfjdH",
          "name": "Google Drive account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "51864d3b-8a5d-472b-9d69-61f3c0b810fb",
      "name": "流式处理 Doc/Docx 文件",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2320,
        -112
      ],
      "parameters": {
        "url": "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&supportsAllDrives=true",
        "method": "POST",
        "options": {
          "response": {
            "response": {
              "fullResponse": true
            }
          }
        },
        "jsonBody": "={\n  \"name\": \"{{ ( () => {\n    const sender = ($json.from?.value?.[0]?.name || '').toString().trim().replace(/[\\r\\n]+/g,'');\n    const fallback = (Object.values($binary||{})[0]?.fileName || 'document').replace(/\\\\.[^/.]+$/,'');\n    const who = sender || fallback;\n\n    const parts = new Intl.DateTimeFormat('en-GB', {\n      timeZone: 'UTC',\n      year: 'numeric', month: '2-digit', day: '2-digit',\n      hour: '2-digit', minute: '2-digit', second: '2-digit',\n      hour12: false\n    }).formatToParts(new Date());\n\n    const p = {}; parts.forEach(x => p[x.type] = x.value);\n    const date = `${p.year}-${p.month}-${p.day}`; // YYYY-MM-DD\n    const time = `${p.hour}${p.minute}${p.second}`;\n\n    return `${who} - CV - ${date}_${time}`.replace(/_{2,}/g,'_').trim();\n  })() }}\",\n  \"mimeType\": \"application/vnd.google-apps.document\",\n  \"parents\": [\"YOUR_FOLDER_ID_HERE\"]\n}\n",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "=application/json; charset=UTF-8"
            }
          ]
        },
        "nodeCredentialType": "googleDriveOAuth2Api"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "IjoB5flCkLlcfjdH",
          "name": "Google Drive account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "64ce3d1c-ac9d-4562-bbf1-4250f50fb555",
      "name": "保留简历文件",
      "type": "n8n-nodes-base.code",
      "position": [
        -2320,
        -288
      ],
      "parameters": {
        "jsCode": "// simply pass the incoming items untouched so downstream Merge gets original binary\nreturn items;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "18fa7d4c-12b3-45a3-8aac-e756f2c08ef5",
      "name": "合并",
      "type": "n8n-nodes-base.merge",
      "position": [
        -2096,
        -208
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "c3d0d223-88c6-4af6-8e43-454c779c3a60",
      "name": "标准化",
      "type": "n8n-nodes-base.set",
      "position": [
        -992,
        48
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "b4b5c9c5-fe76-40eb-b234-48c042f0baa7",
              "name": "cv_text",
              "type": "string",
              "value": "={{ $json.cv_text }}"
            },
            {
              "id": "e6933fbf-fcf7-48cc-a763-9ca67de28322",
              "name": "cv_webviewlink",
              "type": "string",
              "value": "={{ $json.cv_webviewlink }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "f3219f5d-cda5-41b6-94fc-743d0b1e8279",
      "name": "从文件提取",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        1296,
        -80
      ],
      "parameters": {
        "options": {},
        "operation": "pdf"
      },
      "typeVersion": 1
    },
    {
      "id": "bdc929ce-fc8e-4779-b0e1-f74965bfd44e",
      "name": "信息提取器",
      "type": "@n8n/n8n-nodes-langchain.informationExtractor",
      "position": [
        -512,
        448
      ],
      "parameters": {
        "text": "={{ $('Standardize').first().json.cv_text }}",
        "options": {},
        "attributes": {
          "attributes": [
            {
              "name": "First Name",
              "required": true,
              "description": "First name of the candidtae"
            },
            {
              "name": "Last Name",
              "required": true,
              "description": "Last name of the candidate"
            },
            {
              "name": "Email Address",
              "description": "Email address of the candidate"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "73b50c74-acf9-4e0e-8881-0b5860a19136",
      "name": "在表格中追加行",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -176,
        448
      ],
      "parameters": {
        "columns": {
          "value": {
            "CV": "={{ $('Standardize').first().json.cv_webviewlink }}",
            "Date": "={{ $now.setZone('UTC').format('yyyy-MM-dd HH:mm') }}",
            "Email": "={{ $json.output['Email Address'] }}",
            "JD Match": "={{ $('Recruiter Scoring Agent').item.json.output.selected_jd_filename }}",
            "Last Name": "={{ $json.output['Last Name'] }}",
            "Strengths": "={{ $('Recruiter Scoring Agent').item.json.output.candidate_strengths.join(\"\\n\\n\") }}",
            "First Name": "={{ $json.output['First Name'] }}",
            "Weaknesses": "={{ $('Recruiter Scoring Agent').item.json.output.candidate_weaknesses.join(\"\\n\\n\") }}",
            "Overall Fit": "={{ $('Recruiter Scoring Agent').item.json.output.overall_fit_rating }}",
            "Risk Factor": "={{ $('Recruiter Scoring Agent').item.json.output.risk_factor.score }}  \n\n{{ $('Recruiter Scoring Agent').item.json.output.risk_factor.explanation }}",
            "Justification": "={{ $('Recruiter Scoring Agent').item.json.output.justification_for_rating }}",
            "Reward Factor": "={{ $('Recruiter Scoring Agent').item.json.output.reward_factor.score }}\n\n{{ $('Recruiter Scoring Agent').item.json.output.reward_factor.explanation }}",
            "Submission ID": "={{ \n  (( $json.output?.['Last Name'] || 'unknown' ) + '')\n    .toLowerCase()\n    .replace(/[^a-z0-9]+/g, '')    // sanitize\n  + '_' +\n  new Date().toISOString().replace(/[-:TZ.]/g, '').slice(0,14) // UTC YYYYMMDDHHmmss\n}}",
            "Sent From Email": "={{ $('Receive CV via Email').first().json.from.value[0].address }}"
          },
          "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": "CV",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "CV",
              "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",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sent From Email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Sent From Email",
              "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
            },
            {
              "id": "TC Decision",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "TC Decision",
              "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/1ZNXqOSfSusmQxmCbNQ61Y-Ln9l0jCTzSfRc-JA_y9Oo/edit#gid=0",
          "cachedResultName": "1. AI Candidate Screening"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1ZNXqOSfSusmQxmCbNQ61Y-Ln9l0jCTzSfRc-JA_y9Oo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ZNXqOSfSusmQxmCbNQ61Y-Ln9l0jCTzSfRc-JA_y9Oo/edit?usp=drivesdk",
          "cachedResultName": "AI Candidate Screening"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "TjOctR8CYkO1SVp8",
          "name": "Google Sheets account 2"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "8e9c7f2c-3cb6-44cb-936f-27bd5e1f3dd7",
      "name": "获取网页链接",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1728,
        -208
      ],
      "parameters": {
        "url": "=https://www.googleapis.com/drive/v3/files/{{ $json.body.id }}?fields=id,name,mimeType,webViewLink,webContentLink,parents",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googleDriveOAuth2Api"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "IjoB5flCkLlcfjdH",
          "name": "Google Drive account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "341f3daf-bffa-4388-97a0-457334d61774",
      "name": "下载简历 - PDF",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -1840,
        208
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "IjoB5flCkLlcfjdH",
          "name": "Google Drive account"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "56d16d49-6123-482b-b2a5-ea1919fc3ce2",
      "name": "下载简历 - GDoc 转为 PDF",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -1536,
        -208
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {
          "googleFileConversion": {
            "conversion": {
              "docsToFormat": "application/pdf"
            }
          }
        },
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "IjoB5flCkLlcfjdH",
          "name": "Google Drive account"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "7b7210cb-fde5-4f8f-a4ba-b68af8711f17",
      "name": "切换 - 文件类型",
      "type": "n8n-nodes-base.switch",
      "position": [
        -2624,
        48
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Doc-Docx",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "f3cab524-be2f-44ad-bc73-664ee982e4ff",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ (Object.values($binary || {})[0]?.mimeType || '').toLowerCase() }}",
                    "rightValue": "={{ \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\" || \"application/msword\" }}"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "PDF",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "dac4774b-bbf3-4033-a144-15802529d97a",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ (Object.values($binary || {})[0]?.mimeType || '').toLowerCase() }}",
                    "rightValue": "application/pdf"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "10b57b25-585c-4e27-8024-945763f66d99",
      "name": "上传简历 - PDF",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -2144,
        208
      ],
      "parameters": {
        "name": "={{ $('Receive CV via Email').item.json.from.value[0].name + ' - CV - ' + (()=>{const parts=new Intl.DateTimeFormat('en-GB',{timeZone:'UTC',year:'numeric',month:'2-digit',day:'2-digit',hour:'2-digit',minute:'2-digit',second:'2-digit',hour12:false}).formatToParts(new Date());const p={};parts.forEach(x=>p[x.type]=x.value);return `${p.year}-${p.month}-${p.day}_${p.hour}${p.minute}${p.second}`;})() }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "1tabXACSCjelI0y82m7M7TKlvm0ta6_06",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1tabXACSCjelI0y82m7M7TKlvm0ta6_06",
          "cachedResultName": "Candidate CVs"
        },
        "inputDataFieldName": "={{ Object.keys($binary || {})[0] }}"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "IjoB5flCkLlcfjdH",
          "name": "Google Drive account"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "8616f65e-71e2-453c-bfd8-cda7c512fe35",
      "name": "从 PDF 下载中提取",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -1344,
        -208
      ],
      "parameters": {
        "options": {},
        "operation": "pdf"
      },
      "typeVersion": 1
    },
    {
      "id": "59848ee7-40b0-4d99-8b27-49088f249fbb",
      "name": "从 PDF 提取",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -1536,
        208
      ],
      "parameters": {
        "options": {},
        "operation": "pdf"
      },
      "typeVersion": 1
    },
    {
      "id": "7461a572-e6c2-4e6a-b63c-88788e1c5a1e",
      "name": "下载选定的职位描述",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        944,
        -256
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.output.email_match.jd_file_id }}"
        },
        "options": {
          "googleFileConversion": {
            "conversion": {
              "docsToFormat": "application/pdf"
            }
          }
        },
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "IjoB5flCkLlcfjdH",
          "name": "Google Drive account"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "19be4be4-3335-4f53-9bb2-103c9a1e5cca",
      "name": "通过邮件接收简历",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        -2848,
        48
      ],
      "parameters": {
        "simple": false,
        "filters": {
          "labelIds": [
            "Label_5882671977694855295"
          ]
        },
        "options": {
          "downloadAttachments": true,
          "dataPropertyAttachmentsPrefixName": "cv_"
        },
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        }
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "51mlyK2w5LA9QaKi",
          "name": "Gmail account"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "0fae31aa-69ea-4176-9b4c-f4ab7fa2fdf1",
      "name": "职位描述匹配代理",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "onError": "continueRegularOutput",
      "position": [
        -672,
        -272
      ],
      "parameters": {
        "text": "=## Candidate's Email (Prority JD matching method)\nEMAIL SUBJECT: {{ $('Receive CV via Email').item.json.subject }}\nEMAIL BODY: {{ $('Receive CV via Email').item.json.text }}\n\n## CANDIDATE CV (Fallback JD matching method if candidate's email does not state which role they're applying for)\n{{ $json.cv_text }}\n\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 email context first, and secondly the candidate's CV as a fallback method.\n- Select the SINGLE most appropriate job description if there is one that clearly relates to candidate's email contents. IF EMAIL SUBJECT OR BODY 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 CV and profile.\n\n\n## YOUR RESPONSE FORMAT\nReturn your response in this exact JSON format:\n\nFor email match:\n{\n  \"match_type\": \"email_match\",\n  \"email_match\": {\n    \"jd_filename\": \"Marketing Director JD\",\n    \"jd_file_id\": \"1xxxxxxxxxxxxxxxxxxxxxx\",\n    \"confidence\": \"high\"\n  }\n}\n\nFor CV match (up to a maximum of 3 best-match JDs):\n{\n  \"match_type\": \"cv_match\", \n  \"cv_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 candidate's email (subject line and message) where possible. \n\nIf the contents of their email do not clearly state a JD or specific role, then you should match up to 3 JDs based on the content of their CV 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": "99f8d6a6-3820-4744-8011-e15f66a4b133",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2432,
        112
      ],
      "parameters": {
        "color": 5,
        "width": 1472,
        "height": 320,
        "content": "## 通过 PDF 格式获取简历"
      },
      "typeVersion": 1
    },
    {
      "id": "56eb1d87-b1cd-469a-ac19-8b71fe8735c6",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2432,
        -384
      ],
      "parameters": {
        "color": 6,
        "width": 1472,
        "height": 464,
        "content": "## 通过 Word/Doc/D"
      },
      "typeVersion": 1
    },
    {
      "id": "5ce6b66d-301e-45b0-a8a8-b2fdee67d833",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -928,
        -384
      ],
      "parameters": {
        "color": 2,
        "width": 1712,
        "height": 624,
        "content": "## Job Description (Vacany) Matching with Candidate's CV"
      },
      "typeVersion": 1
    },
    {
      "id": "abd2b59f-381e-4f73-9fea-561466127101",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -928,
        272
      ],
      "parameters": {
        "width": 1392,
        "height": 560,
        "content": "## 3. CV Analysis and Feedback"
      },
      "typeVersion": 1
    },
    {
      "id": "8e857a30-d21e-4753-b8f0-ecd834f5b195",
      "name": "Detailed JD Matching Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        944,
        -48
      ],
      "parameters": {
        "text": "=Compare this candidate's full CV 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 CV\n{{ $('Standardize').item.json.cv_text }}\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 CV 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": false,
      "typeVersion": 2.2
    },
    {
      "id": "98c0d280-0aca-48e8-aaaa-86be4e2bde45",
      "name": "遍历项目",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        128,
        -144
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "e8a4e7f4-b26a-4853-a23e-2710ce09cc51",
      "name": "Download Selected JD1",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        304,
        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": "1e55c3ab-4dc4-42fa-990b-26600f5f4d9e",
      "name": "Extract from File1",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        464,
        0
      ],
      "parameters": {
        "options": {},
        "operation": "pdf"
      },
      "typeVersion": 1
    },
    {
      "id": "eaea53b0-fd3e-4d16-bfd9-d6d7c93f3e0e",
      "name": "Gemini 2.5 Flash",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -736,
        -80
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "id": "etClcv7ej0yswPTF",
          "name": "Google Gemini(PaLM) Api account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f0311480-1820-4229-89d6-87634e1aae32",
      "name": "Access JD Files",
      "type": "n8n-nodes-base.googleDriveTool",
      "position": [
        -576,
        -80
      ],
      "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": "74d68403-76d4-4970-bd17-8bdeab243e8f",
      "name": "Transform for Multiple JDs",
      "type": "n8n-nodes-base.code",
      "position": [
        -96,
        -176
      ],
      "parameters": {
        "jsCode": "// Transform the AI agent output for looping\nif ($json.output.match_type === \"cv_match\") {\n  // Return each JD as a separate item for the loop\n  return $json.output.cv_match.map(jd => ({\n    jd_filename: jd.jd_filename,\n    jd_file_id: jd.jd_file_id\n  }));\n} else {\n  // For email match, return single item\n  return [{\n    jd_filename: $json.output.email_match.jd_filename,\n    jd_file_id: $json.output.email_match.jd_file_id\n  }];\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "203a733c-9916-420e-91b1-e8704f666ed5",
      "name": "JD Match w/Email?",
      "type": "n8n-nodes-base.if",
      "position": [
        -304,
        -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": "email_match"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "19dcdeaa-edf5-4a8d-8060-ebcd6cb32c8b",
      "name": "便签6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        496,
        -384
      ],
      "parameters": {
        "color": 2,
        "width": 1296,
        "height": 1216,
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "423054a7-88f1-410e-bc0e-c2801f706acf",
      "name": "设置",
      "type": "n8n-nodes-base.set",
      "position": [
        624,
        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": "4b7440a0-2382-4afb-ab4e-ca58146b1d56",
      "name": "Set as Selected JD Format",
      "type": "n8n-nodes-base.set",
      "position": [
        1552,
        448
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "271dc7a2-e8c3-40f7-9e7c-04c4463490f0",
              "name": "selected_jd_filename",
              "type": "string",
              "value": "={{ $('JD Match w/Email?').item.json.output.email_match.jd_filename }}"
            },
            {
              "id": "2e987315-7b9b-47ca-a2ca-400978944b7a",
              "name": "selected_jd_file_id",
              "type": "string",
              "value": "={{ $('JD Match w/Email?').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": "e376226f-f68d-41f6-b38c-3268f5c4b970",
      "name": "Match Selected JD Name with Full Text",
      "type": "n8n-nodes-base.code",
      "position": [
        1296,
        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}];"
      },
      "typeVersion": 2
    },
    {
      "id": "642dac3e-e494-4f70-ae54-ea5dab98cea2",
      "name": "Gemini 2.5 Pro-1",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        912,
        160
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-2.5-pro"
      },
      "credentials": {
        "googlePalmApi": {
          "id": "etClcv7ej0yswPTF",
          "name": "Google Gemini(PaLM) Api account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "450ddf83-b4ad-4834-9286-29b63c4552f6",
      "name": "Gemini 2.5 Flash-1",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -512,
        672
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "id": "etClcv7ej0yswPTF",
          "name": "Google Gemini(PaLM) Api account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "44889a9c-1185-4aaa-b14b-864a4599b2b7",
      "name": "Standardize Web Link and CV Text (PDF)",
      "type": "n8n-nodes-base.set",
      "position": [
        -1168,
        208
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "f7a58896-424f-46a5-8849-a75f89bf20b0",
              "name": "cv_webviewlink",
              "type": "string",
              "value": "={{ $('Upload CV - PDF').item.json.webViewLink }}"
            },
            {
              "id": "0e202a35-b3c6-4c2d-893e-ad986d00ef6c",
              "name": "cv_text",
              "type": "string",
              "value": "={{ $json.text }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "8132c536-2de6-440c-8202-fc7cec6ceccb",
      "name": "Standardize Web Link and CV Text (GDoc)",
      "type": "n8n-nodes-base.set",
      "position": [
        -1168,
        -208
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "1c868154-561f-4897-8828-e12c66dba01b",
              "name": "cv_webviewlink",
              "type": "string",
              "value": "={{ $('Get Web Link').item.json.webViewLink }}"
            },
            {
              "id": "0a02aa8c-b464-44c1-a962-bbddcde33fa9",
              "name": "cv_text",
              "type": "string",
              "value": "={{ $json.text }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "d8af1a95-21f4-4ee8-8de5-9a6387e2475f",
      "name": "Send Candidate Screening Confirmation",
      "type": "n8n-nodes-base.slack",
      "position": [
        32,
        448
      ],
      "webhookId": "4cf3a198-5cdd-495f-aad3-aa28f0441063",
      "parameters": {
        "select": "channel",
        "blocksUi": "={\n\t\"blocks\": [\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"I've just completed the screening of a new candidate, who sent their CV moments ago. I've intelligently matched the candidate with the JD we have -- either through the candidate directly applying for this role, or selecting the best matched JD if they didn't apply for a specific role.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"I've provided the following *Overall Fit* score and *Justification*:\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"divider\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"table\",\n\t\t\t\"rows\": [\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"rich_text\",\n\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"type\": \"rich_text_section\",\n\t\t\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\t\"text\": \"Name\",\n\t\t\t\t\t\t\t\t\t\t\"style\": {\n\t\t\t\t\t\t\t\t\t\t\t\"bold\": true\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"rich_text\",\n\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"type\": \"rich_text_section\",\n\t\t\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\t\"text\": \"CV\",\n\t\t\t\t\t\t\t\t\t\t\"style\": {\n\t\t\t\t\t\t\t\t\t\t\t\"bold\": true\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"rich_text\",\n\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"type\": \"rich_text_section\",\n\t\t\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\t\"text\": \"Job Role Matched\",\n\t\t\t\t\t\t\t\t\t\t\"style\": {\n\t\t\t\t\t\t\t\t\t\t\t\"bold\": true\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"rich_text\",\n\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"type\": \"rich_text_section\",\n\t\t\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\t\"text\": \"Overall Fit\",\n\t\t\t\t\t\t\t\t\t\t\"style\": {\n\t\t\t\t\t\t\t\t\t\t\t\"bold\": true\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"rich_text\",\n\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"type\": \"rich_text_section\",\n\t\t\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\t\"text\": \"{{ $json['First Name'] }} {{ $json['Last Name'] }}\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"rich_text\",\n\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"type\": \"rich_text_section\",\n\t\t\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"type\": \"link\",\n\t\t\t\t\t\t\t\t\t\t\"url\": \"{{ $json.CV }}\",\n\t\t\t\t\t\t\t\t\t\t\"text\": \"CV - {{ $json['First Name'] }} {{ $json['Last Name'] }}\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"rich_text\",\n\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"type\": \"rich_text_section\",\n\t\t\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\t\"text\": \"{{ $json['JD Match'] }}\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"rich_text\",\n\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"type\": \"rich_text_section\",\n\t\t\t\t\t\t\t\t\"elements\": [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\t\t\t\"text\": \"{{ $json['Overall Fit'] }}/10\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"type\": \"divider\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"context\",\n\t\t\t\"elements\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\t\"text\": \"_Submission ID: {{ $json['Submission ID'] }}_\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"<https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit?usp=sharing|View the full analysis in the AI Candidate Screening sheet>\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"actions\",\n\t\t\t\"elements\": [\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"button\",\n\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\"text\": \"Proceed w/Candidate\",\n\t\t\t\t\t\t\"emoji\": true\n\t\t\t\t\t},\n\t\t\t\t\t\"value\": \"{\\\"action\\\":\\\"proceed_candidate\\\",\\\"submission_id\\\":\\\"{{ $json['Submission ID'] }}\\\",\\\"candidate_name\\\":\\\"{{ $json['First Name'] }} {{ $json['Last Name'] }}\\\",\\\"email\\\":\\\"{{ $json.Email }}\\\",\\\"cv_url\\\":\\\"{{ $json.CV }}\\\",\\\"jd_match\\\":\\\"{{ $json['JD Match'] }}\\\",\\\"overall_fit\\\":\\\"{{ $json['Overall Fit'] }}\\\",\\\"first_name\\\":\\\"{{ $json['First Name'] }}\\\",\\\"last_name\\\":\\\"{{ $json['Last Name'] }}\\\"}\",\n\t\t\t\t\t\"action_id\": \"proceed_action\",\n\t\t\t\t\t\"style\": \"primary\",\n\t\t\t\t\t\"confirm\": {\n\t\t\t\t\t\t\"title\": {\n\t\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\t\"text\": \"Confirm Proceed\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\t\t\t\"text\": \"Are you sure you want to **proceed** with this candidate?\\n\\nThis will:\\n• Move them to the next interview stage\\n• Update the screening spreadsheet\\n• Notify the hiring team\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"confirm\": {\n\t\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\t\"text\": \"Yes, Proceed\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"deny\": {\n\t\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\t\"text\": \"Cancel\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"button\",\n\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\"text\": \"Reject Candidate\",\n\t\t\t\t\t\t\"emoji\": true\n\t\t\t\t\t},\n\t\t\t\t\t\"value\": \"{\\\"action\\\":\\\"reject_candidate\\\",\\\"submission_id\\\":\\\"{{ $json['Submission ID'] }}\\\",\\\"candidate_name\\\":\\\"{{ $json['First Name'] }} {{ $json['Last Name'] }}\\\",\\\"email\\\":\\\"{{ $json.Email }}\\\",\\\"cv_url\\\":\\\"{{ $json.CV }}\\\",\\\"jd_match\\\":\\\"{{ $json['JD Match'] }}\\\",\\\"overall_fit\\\":\\\"{{ $json['Overall Fit'] }}\\\",\\\"first_name\\\":\\\"{{ $json['First Name'] }}\\\",\\\"last_name\\\":\\\"{{ $json['Last Name'] }}\\\"}\",\n\t\t\t\t\t\"action_id\": \"reject_action\",\n\t\t\t\t\t\"style\": \"danger\",\n\t\t\t\t\t\"confirm\": {\n\t\t\t\t\t\t\"title\": {\n\t\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\t\"text\": \"Confirm Rejection\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"text\": {\n\t\t\t\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\t\t\t\"text\": \"Are you sure you want to **reject** this candidate?\\n\\nThis will:\\n• Mark them as rejected in the system\\n• Update the screening spreadsheet\\n• Send the candidate a friendly rejection email\\n• This action cannot be undone\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"confirm\": {\n\t\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\t\"text\": \"Yes, Reject\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"deny\": {\n\t\t\t\t\t\t\t\"type\": \"plain_text\",\n\t\t\t\t\t\t\t\"text\": \"Cancel\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t]\n}\n",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09G7DR7X52",
          "cachedResultName": "talent"
        },
        "messageType": "block",
        "otherOptions": {
          "includeLinkToWorkflow": false
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "id": "qXwPqfkNoVV9HIr1",
          "name": "TidyCurve DJP"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "5a0b4b2c-1c67-4fd1-b72d-d047ad727cb5",
      "name": "Recruiter Scoring Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -832,
        448
      ],
      "parameters": {
        "text": "=Candidate's CV (Resume):\n{{ $('Standardize').first().json.cv_text }}\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 resume. Your task is to analyze the resume 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 resume 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": "37f0cded-a0bd-4f8c-9512-54cd1312d171",
      "name": "Gemini 2.5 Pro-2",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -848,
        672
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-2.5-pro"
      },
      "credentials": {
        "googlePalmApi": {
          "id": "etClcv7ej0yswPTF",
          "name": "Google Gemini(PaLM) Api account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6b175b49-903b-4682-b610-1bfaa97c9623",
      "name": "便签7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3840,
        -880
      ],
      "parameters": {
        "color": 7,
        "width": 912,
        "height": 1536,
        "content": "# **First-Round Fast Track AI Recruiter Assistant**\n  *CV → Match → Screen → Decide, all automated*\n\n  This workflow automatically processes candidate CVs from email, intelligently matches them to job descriptions, performs\n  AI-powered screening analysis, and sends actionable summaries to your team in Slack.\n\n  **Good to know**\n  - Handles both PDF and Word document CVs automatically\n  - Two-stage JD matching: prioritizes role mentioned in candidate's email, falls back to CV analysis if needed\n  - Uses Google Gemini API for AI screening (generous free tier and rate limits, typically enough to avoid paying for API requests, but check latest pricing at [Google AI Pricing](https://ai.google.dev/pricing))\n  - All CVs stored in Google Drive with standardized naming (candidate name + date/time)\n  - Complete audit trail logged in Google Sheets\n\n  ## Who's it for\n  Hiring teams and recruiters who want to automate first-round CV screening while maintaining quality. Perfect for companies        \n  receiving high volumes of applications across multiple roles, especially in tech, sales, or automation-focused positions.\n\n  ## How it works\n  1. Gmail monitors inbox for CVs with specific label and downloads attachments\n  2. Detects file type (PDF or Word) and converts/standardizes format for text extraction\n  3. AI agent matches candidate to best-fit job description by analyzing email context first (if candidate mentioned a role), or    \n   CV content as fallback (selects up to 3 potential JD matches)\n  4. If multiple JDs matched, second AI agent selects the single best fit\n  5. AI recruiter agent analyzes CV against selected JD and generates structured screening report (strengths, weaknesses,\n  risk/reward factors, overall fit score 0-10 with justification)\n  6. Extracts candidate details (name, email) from CV text\n  7. Logs complete analysis to Google Sheets tracker\n  8. Sends formatted summary to Slack with Proceed/Reject action buttons for instant team decisions\n\n  ## Requirements\n  - Gmail account with API access\n  - Google Drive account (OAuth2)\n  - Google Sheets account (OAuth2)\n  - Slack workspace with bot permissions\n  - Google Gemini API key ([Get free key here](https://makersuite.google.com/app/apikey))\n  - Google Drive folders: one for CVs, one for Job Descriptions (as PDFs or Google Docs)\n\n  ## How to set up\n  1. Add credentials: Gmail OAuth2, Google Drive OAuth2, Google Sheets OAuth2, Slack OAuth2, Google Gemini API\n  2. Create Gmail label (e.g., \"CV-Screening\") for incoming candidate emails\n  3. In \"Receive CV via Email\" node: select your Gmail label for filtering\n  4. Create two Google Drive folders: \"Candidate CVs\" and \"Job Descriptions\"\n  5. In \"Upload CV - PDF\" and \"Stream Doc/Docx File\" nodes: update folder ID to your \"Candidate CVs\" folder\n  6. In \"Access JD Files\" node: update folder ID to your \"Job Descriptions\" folder\n  7. Create Google Sheet named \"AI Candidate Screening\" with columns matching the [sample AI Candidate Screening sheet](https://docs.google.com/spreadsheets/d/16HebkHqsM2ZE_IdJzQk1mDE3i2-HwsUqa5gEwXaF-7A/edit?usp=sharing)       \n  8. In \"Append row in sheet\" node: select your Google Sheet\n  9. In \"Send Candidate Screening Confirmation\" node: select your Slack channel and enter your Google Sheet ID in the Blocks section\n  10. Activate workflow\n\n  ## Customizing this workflow\n  - **Change JD matching logic**: Edit \"JD Matching Agent\" node prompt to adjust how CVs are matched to roles (e.g., weight\n  technical skills vs. experience).\n  - **Change \"Company Description\" in AI prompts**: Insert your \"Company Description\" in System Message sections in \"JD Matching Agent\" and \"Detailed JD Matching Agent\" nodes\n  - **Modify screening criteria**: Edit \"Recruiter Scoring Agent\" node system message to focus on specific qualities (culture       \n  fit, leadership, technical depth, etc.)\n  - **Add more storage locations**: Add nodes to save CVs to other systems (Notion, Airtable, ATS platforms)\n  - **Customize Slack message**: Edit \"Send Candidate Screening Confirmation\" node to change formatting, add more context, or       \n  include additional candidate data\n  - **Auto-proceed logic**: Add IF node after screening to auto-proceed candidates with fit score above threshold (e.g., 8+/10)     \n  - **Add email responses**: Connect nodes to automatically email candidates (confirmation, rejection, interview invite)\n  - **Add human-in-the-loop**: Sub-workflow triggered by Slack response or email response, to update Sheet with approve/reject status\n- **Add candidate email responses + interview scheduling**: For approved candidates, trigger email to candidate with Cal.com or Calendly link so they can book their interview"
      },
      "typeVersion": 1
    },
    {
      "id": "3fc25e0b-d3a9-428b-8d75-a684a397301a",
      "name": "便签4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2896,
        464
      ],
      "parameters": {
        "color": 7,
        "width": 544,
        "height": 192,
        "content": "## Acknowledgments\n  This workflow was inspired by [Nate Herk's YouTube demonstration](https://www.youtube.com/watch?v=M0s6O8xtVUE) on building a resume analysis system. This implementation builds upon that foundation by adding dynamic job description matching (initial + detailed JD matching agents), Slack Block Kit integration with interactive buttons, updated Google Drive API methods for document handling, and enhanced candidate data capture in Google Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "5d1d64c0-df2b-4b9d-b7af-46ae3619e5d9",
      "name": "便签8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2896,
        -880
      ],
      "parameters": {
        "color": 7,
        "width": 864,
        "height": 464,
        "content": " ## Quick Troubleshooting\n  * **No CVs being processed**: Check Gmail label is correctly set in \"Receive CV via Email\" node and emails are being labeled      \n  * **Word documents failing**: Verify \"Stream Doc/Docx File\" node has correct parent folder ID and Google Drive credentials        \n  authorized\n  * **JD matching returns no results**: Check \"Access JD Files\" node folder ID points to your Job Descriptions folder, and JD       \n  files are named clearly (e.g., \"Marketing Director JD.pdf\")\n * **JD matching is not relevant for my company**: Update the \"Company Description\" in the System Messages in the \"JD Matching Agent\" and \"Detailed JD Matching Agent\" nodes\n  * **\"Can't find matching JD\"**: Ensure candidate's email mentions role name OR their CV clearly indicates relevant experience     \n  for available JDs\n  * **Google Sheets errors**: Verify sheet name is \"AI Candidate Screening\" and column headers exactly match workflow\n  expectations (Submission ID, Date, CV, First Name, etc.)\n  * **Slack message not appearing**: Re-authorize Slack credentials and confirm channel ID in \"Send Candidate Screening\n  Confirmation\" node\n  * **Missing candidate name/email**: CV text must be readable - check PDF extraction quality or try converting complex CVs to      \n  simpler format\n  * **401/403 API errors**: Re-authorize all OAuth2 credentials (Gmail, Google Drive, Google Sheets, Slack)\n  * **AI analysis quality issues**: Edit system prompts in \"JD Matching Agent\" and \"Recruiter Scoring Agent\" nodes to refine        \n  screening criteria"
      },
      "typeVersion": 1
    },
    {
      "id": "c3bcef58-069f-4193-b6d9-f3cafdb30677",
      "name": "Structured Output Parser-1",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -416,
        -80
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"match_type\": {\n      \"type\": \"string\",\n      \"enum\": [\"email_match\", \"cv_match\"],\n      \"description\": \"Whether the match was found in email or requires CV analysis\"\n    },\n    \"email_match\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"jd_filename\": {\n          \"type\": \"string\",\n          \"description\": \"Exact filename of the matched JD (PDF or Google Doc)\"\n        },\n        \"jd_file_id\": {\n          \"type\": \"string\",\n          \"description\": \"Google Drive file ID for downloading the JD file\"\n        },\n        \"confidence\": {\n          \"type\": \"string\",\n          \"enum\": [\"high\", \"medium\", \"low\"],\n          \"description\": \"Confidence level of the email-based match\"\n        }\n      },\n      \"required\": [\"jd_filename\", \"jd_file_id\", \"confidence\"]\n    },\n    \"cv_match\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"jd_filename\": {\n            \"type\": \"string\",\n            \"description\": \"JD filename to download and analyze (PDF or Google Doc)\"\n          },\n          \"jd_file_id\": {\n            \"type\": \"string\",\n            \"description\": \"Google Drive file ID for downloading the JD file\"\n          }\n        },\n        \"required\": [\"jd_filename\", \"jd_file_id\"]\n      },\n      \"minItems\": 1,\n      \"maxItems\": 3,\n      \"description\": \"Up to a maximum of 3 JD files for detailed analysis, but 1-2 JD files is also fine if you do not think there are 3 JD files relevant\"\n    }\n  },\n  \"required\": [\"match_type\"],\n  \"oneOf\": [\n    {\n      \"properties\": {\n        \"match_type\": {\"const\": \"email_match\"}\n      },\n      \"required\": [\"email_match\"]\n    },\n    {\n      \"properties\": {\n        \"match_type\": {\"const\": \"cv_match\"}  \n      },\n      \"required\": [\"cv_match\"]\n    }\n  ]\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "3977e0ec-5ba4-4a31-94c3-1efb5d3e2e2c",
      "name": "Structured Output Parser-3",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -672,
        672
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"name\": \"resume_screening_evaluation\",\n  \"description\": \"Analyzes a candidate's resume against a job description and outputs 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.\",\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.\",\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 CV 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 resume 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": "dfadca1a-95df-4d34-ae7b-3f17192aad61",
      "name": "Structured Output Parser-2",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1104,
        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": "1f546e0e-264d-41bd-a7a4-f22607ecc53d",
      "name": "便签5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2000,
        -864
      ],
      "parameters": {
        "color": 7,
        "width": 960,
        "height": 448,
        "content": "## Sample Outputs\n- [Google Sheets - AI Candidate Screening - sample](https://docs.google.com/spreadsheets/d/16HebkHqsM2ZE_IdJzQk1mDE3i2-HwsUqa5gEwXaF-7A/edit?usp=sharing)\n![](https://i.postimg.cc/HkHfhQCW/Screenshot-2025-10-16-145031.png)"
      },
      "typeVersion": 1
    },
    {
      "id": "51a70bcd-6c2e-4f4f-b35b-7ced5501e505",
      "name": "便签9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1072,
        -816
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 400,
        "content": "![](https://i.postimg.cc/HxhmGjtj/Screenshot-2025-10-16-145423.png)"
      },
      "typeVersion": 1
    },
    {
      "id": "5247f09d-2836-49b0-9f6a-a26261213b41",
      "name": "便签10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -432,
        -848
      ],
      "parameters": {
        "color": 7,
        "width": 800,
        "height": 432,
        "content": "- Slack confirmation message\n![](https://i.postimg.cc/mgwGLcgw/Screenshot-2025-10-16-135446.png)"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": "orVeCnK9KH8GxfmT",
    "executionOrder": "v1"
  },
  "versionId": "7d2443dc-a590-4148-ac8e-14b5643cde3d",
  "connections": {
    "Set": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Trigger Google Docs Conversion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Standardize": {
      "main": [
        [
          {
            "node": "JD Matching Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Web Link": {
      "main": [
        [
          {
            "node": "Download CV - GDoc as PDF",
            "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
          }
        ]
      ]
    },
    "Upload CV - PDF": {
      "main": [
        [
          {
            "node": "Download CV - PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from PDF": {
      "main": [
        [
          {
            "node": "Standardize Web Link and CV Text (PDF)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini 2.5 Flash": {
      "ai_languageModel": [
        [
          {
            "node": "JD Matching Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Gemini 2.5 Pro-1": {
      "ai_languageModel": [
        [
          {
            "node": "Detailed JD Matching Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Gemini 2.5 Pro-2": {
      "ai_languageModel": [
        [
          {
            "node": "Recruiter Scoring Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Preserve CV file": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download CV - PDF": {
      "main": [
        [
          {
            "node": "Extract from PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from File": {
      "main": [
        [
          {
            "node": "Set as Selected JD Format",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JD Match w/Email?": {
      "main": [
        [
          {
            "node": "Download Selected JD",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Transform for Multiple JDs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JD Matching Agent": {
      "main": [
        [
          {
            "node": "JD Match w/Email?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from File1": {
      "main": [
        [
          {
            "node": "Set",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini 2.5 Flash-1": {
      "ai_languageModel": [
        [
          {
            "node": "Information Extractor",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Switch - File Type": {
      "main": [
        [
          {
            "node": "Stream Doc/Docx File",
            "type": "main",
            "index": 0
          },
          {
            "node": "Preserve CV file",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Upload CV - PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append row in sheet": {
      "main": [
        [
          {
            "node": "Send Candidate Screening Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Selected JD": {
      "main": [
        [
          {
            "node": "Extract from File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Receive CV via Email": {
      "main": [
        [
          {
            "node": "Switch - File Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Stream Doc/Docx File": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Download Selected JD1": {
      "main": [
        [
          {
            "node": "Extract from File1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Information Extractor": {
      "main": [
        [
          {
            "node": "Append row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Recruiter Scoring Agent": {
      "main": [
        [
          {
            "node": "Information Extractor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download CV - GDoc as PDF": {
      "main": [
        [
          {
            "node": "Extract from PDF Download",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from PDF Download": {
      "main": [
        [
          {
            "node": "Standardize Web Link and CV Text (GDoc)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set as Selected JD Format": {
      "main": [
        [
          {
            "node": "Recruiter Scoring Agent",
            "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
          }
        ]
      ]
    },
    "Trigger Google Docs Conversion": {
      "main": [
        [
          {
            "node": "Get Web Link",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Match Selected JD Name with Full Text": {
      "main": [
        [
          {
            "node": "Recruiter Scoring Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Candidate Screening Confirmation": {
      "main": [
        []
      ]
    },
    "Standardize Web Link and CV Text (PDF)": {
      "main": [
        [
          {
            "node": "Standardize",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Standardize Web Link and CV Text (GDoc)": {
      "main": [
        [
          {
            "node": "Standardize",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

高级

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量50
分类-
节点类型18
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
Dean Pike

Dean Pike

@deanjp

Saving 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.

外部链接
在 n8n.io 查看

分享此工作流