第一轮 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

カテゴリー

ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下のJSON設定をn8nにインポートして、このワークフローを使用できます
{
  "id": "FQVkQc57GUYlurVw",
  "meta": {
    "instanceId": "90dd23d886c9cb675f452d0fb004af6ee783e4e974ef4384cbfad1854c68a875",
    "templateCredsSetupCompleted": true
  },
  "name": "First-Round Telegram and LinkedIn Fast Track AI Recruiter Assistant",
  "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": "Download Selected JD",
      "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": "JD Matching エージェント",
      "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": "## Job Description (Vacany) Matching with Candidate's LinkedIn Profile"
      },
      "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 Profile Analysis and Feedback"
      },
      "typeVersion": 1
    },
    {
      "id": "b686e251-6ed4-4984-bbc4-283d52bed4e7",
      "name": "Detailed JD Matching エージェント",
      "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": "Download Selected JD1",
      "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": "Access JD Files",
      "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": "Transform for Multiple JDs",
      "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": "Match Selected JD Name with Full Text",
      "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": "Recruiter Scoring エージェント",
      "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": "Structured 出力パーサー-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": "Structured 出力パーサー-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": "Structured 出力パーサー-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": "Receive Telegram Msg to Recruiter Bot",
      "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": "Extract LinkedIn Profile Information",
      "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 Profile Ready?",
      "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": "待機 for LinkedIn Profile",
      "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": "Reply with Confirmation Msg",
      "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": "Increment Loop Counter",
      "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": "Initialize Loop Counter to Poll for Completion",
      "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": "Restore Loop Counter",
      "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": "Checked 10x for LinkedIn Profile Data?",
      "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": "Check LinkedIn Profile Extraction Status",
      "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": "Get Fully Extracted LinkedIn Profile Data",
      "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": "Reply with Error/Try Again Msg",
      "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": "設定 Key LinkedIn Profile Data",
      "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": "設定 JD Data",
      "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": "設定 Selected JD Format",
      "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": "## Get LinkedIn Profile via Telegram"
      },
      "typeVersion": 1
    },
    {
      "id": "8903e8c4-5ae9-4d61-a426-7ed450a96c43",
      "name": "Send Msg to Internal Talent Group",
      "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 => ({'&':'&amp;','<':'&lt;','>':'&gt;'}[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": "Send Review Completed Msg to Talent Group",
      "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 => ({'&':'&amp;','<':'&lt;','>':'&gt;'}[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": "Gather and 設定 Final Data",
      "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": "Add Candidate Analysis in GSheet",
      "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": "開始 Msg Sent + Valid LinkedIn Profile 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": "Spam Check: Sent  <4 LinkedIn Profiles?",
      "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": "Reply - Too Many LinkedIn URLs Sent Msg",
      "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": "Get All Rows Matching Telegram Username",
      "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": "Count Rows Matching Telegram Username",
      "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": "Grab Clean 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": "JD Match w/Telegram Msg?",
      "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": "## Sample Outputs\n### [Google Sheets - LinkedIn AI Candidate Screening - sample](https://docs.google.com/spreadsheets/d/19ZzSG-MyFgdvruWhTozuimYBG-QSvaPhHmqMJqdmJpM/edit?usp=sharing)\n\n\n### Telegram messages between AI recruiter bot and job applicant\n\n![](https://i.postimg.cc/7L1rTsv8/telegram5.jpg)\n\n"
      },
      "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": "## Troubleshooting\n  * **Telegram bot not responding**: Ensure bot token is correct in \"Receive Telegram Msg to Recruiter Bot\" node, and users have sent `/start` to your bot at least once\n  * **\"LinkedIn profile URL invalid\" error**: Check that candidates are sending full URLs in format `https://www.linkedin.com/in/username` (not shortened links or text without URL)\n  * **Apify extraction failing**: Verify Apify API token is correctly set in all three HTTP Request nodes (\"Extract LinkedIn        \n  Profile Information\", \"Check LinkedIn Profile Extraction Status\", \"Get Fully Extracted LinkedIn Profile Data\")\n  * **LinkedIn extraction timeout**: Increase polling attempts in \"Checked 10x for LinkedIn Profile Data?\" node (currently 10) or increase wait time in \"Wait for LinkedIn Profile\" node (currently 15 seconds)\n  * **Spam check blocking valid users**: Check \"Get All Rows Matching Telegram Username\" node is pointing to correct Google Sheet, and adjust limit in \"Spam Check: Sent <4 LinkedIn Profiles?\" node if needed\n  * **JD matching returns no results**: Check \"Access JD Files\" node folder ID points to your Job Descriptions folder, and JD 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 all three AI agent nodes (\"JD Matching Agent\", \"Detailed JD Matching Agent\", \"Recruiter Scoring Agent\")\n  * **\"Can't find matching JD\"**: Ensure candidate's Telegram message mentions role name OR their LinkedIn profile clearly indicates relevant experience for available JDs\n  * **Google Sheets errors**: Verify sheet name is \"LinkedIn Profile AI Candidate Screening\" and column headers exactly match workflow expectations (Submission ID, Date, LinkedIn Profile URL, First Name, Last Name, etc.)\n  * **Telegram group notifications not appearing**: Verify chat ID is correct in \"Send Msg to Internal Talent Group\" and \"Send Review Completed Msg to Talent Group\" nodes (use negative number for group chats, e.g., `-4954246611`)\n  * **Missing candidate data in Google Sheets**: LinkedIn profile may be incomplete - verify Apify successfully extracted data by checking \"Get Fully Extracted LinkedIn Profile Data\" node output\n  * **Loop counter not working**: Check \"Restore Loop Counter\" code node references correct node names (\"Checked 10x for LinkedIn Profile Data?\" and \"Initialize Loop Counter to Poll for Completion\")\n  * **401/403 API errors**: Re-authorize all OAuth2 credentials (Google Drive, Google Sheets) and verify Apify and Telegram API tokens are valid\n  * **AI analysis quality issues**: Edit system prompts in \"JD Matching Agent\", \"Detailed JD Matching Agent\", and \"Recruiter Scoring Agent\" nodes to refine screening criteria and provide more context about your hiring needs\n  * **Gemini API rate limit errors**: Check your usage at [Google AI Studio](https://aistudio.google.com/) and consider upgrading to paid tier if exceeding free tier limits (see [rate limits documentation](https://ai.google.dev/gemini-api/docs/rate-limits))"
      },
      "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": "# **First-Round Telegram + LinkedIn AI Recruiter Assistant**\n  *LinkedIn URL → Scrape → Match → Screen → Decide, all automated*\n\n  This workflow automatically processes candidate LinkedIn profiles shared via Telegram, intelligently matches them to job descriptions, performs AI-powered screening analysis, and sends actionable summaries to your team in Telegram.\n\n  ### Good to know\n  - Handles LinkedIn profile scraping via Apify API (extracts full profile data including experience, education, skills)\n  - Built-in spam prevention: limits users to 3 LinkedIn profile submissions\n  - Two-stage JD matching: prioritizes role mentioned in candidate's Telegram message, falls back to LinkedIn profile 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 - check latest pricing at [Google AI Pricing](https://ai.google.dev/pricing) and [rate limits documentation](https://ai.google.dev/gemini-api/docs/rate-limits))\n  - Automatic polling mechanism checks Apify extraction status up to 10 times (15-second intervals)\n  - Complete audit trail logged in Google Sheets with unique submission IDs\n\n  ## Who's it for\n  Hiring teams and recruiters who want to streamline first-round screening for candidates who share LinkedIn profiles directly. Perfect for companies accepting applications via messaging platforms (Telegram, WhatsApp, etc.), especially useful fortech-savvy audiences and remote/global hiring.\n\n  ## How it works\n  1. Telegram bot receives message containing LinkedIn profile URL from candidate\n  2. Validates URL format and checks spam prevention (max 3 submissions per Telegram username)\n  3. Sends confirmation message to candidate and notifies internal talent team via Telegram group\n  4. Extracts clean LinkedIn URL and initiates Apify scraping job\n  5. Polls Apify API up to 10 times (15-second intervals) until profile extraction completes\n  6. AI agent matches candidate to best-fit job description by analyzing Telegram message context first (if candidate mentioned a role), or LinkedIn profile content as fallback (selects up to 3 potential JD matches)\n  7. If multiple JDs matched, second AI agent selects the single best fit based on detailed profile analysis\n  8. AI recruiter agent analyzes LinkedIn profile against selected JD and generates structured screening report (strengths,\n  weaknesses, risk/reward factors, overall fit score 0-10 with justification)\n  9. Logs complete analysis to Google Sheets tracker with unique submission ID\n  10. Sends formatted summary to Telegram group with candidate details, matched JD, and overall fit score\n\n  ## Requirements\n  - Telegram Bot Token ([Create bot via @BotFather](https://t.me/botfather))\n  - Apify account with API token ([Sign up for free tier](https://apify.com/))\n  - Google Drive account (OAuth2)\n  - Google Sheets account (OAuth2)\n  - Google Gemini API key ([Get free key here](https://makersuite.google.com/app/apikey))\n  - Google Drive folder for Job Descriptions (as PDFs or Google Docs)\n  - Telegram group for internal talent team notifications\n\n  ## How to set up\n  1. **Create Telegram bot and internal Telegram chat group with new bot**:\n     - Message [@BotFather](https://t.me/botfather) on Telegram\n     - Send `/newbot` and follow instructions to create your bot\n     - Save the API token provided\n     - Create Telegram group chat and invite your new bot + invite the @GetIDs bot\n     - Note down the group chat ID ([How to get group chat ID](https://docs.google.com/document/d/1fGM9sZM_QcH8WU33mUYZeT5vyhjRq0S4WlsU0opcxTQ/edit?usp=sharing))\n\n  2. **Setup Apify**:\n     - Sign up at [Apify](https://apify.com/)\n     - Get your API token from Settings\n     - Note: Free tier includes sufficient scraping credits for testing and production ($0.01 per successful LinkedIn profile enriched, a free monthly limit of $5.00) - [LinkedIn profile scraper \"actor\" details](https://apify.com/dev_fusion/linkedin-profile-scraper)\n\n  3. **Create Google Sheet**:\n     - Create new sheet named \"LinkedIn Profile AI Candidate Screening\"\n     - Add columns: Submission ID, Date, LinkedIn Profile URL, First Name, Last Name, Email (if known), Telegram Username, Strengths, Weaknesses, Risk Factor, Reward Factor, JD Match, Overall Fit, Justification\n     - Copy the spreadsheet ID from URL\n\n  4. **Setup Google Drive folder**:\n     - Create folder named \"Job Descriptions\"\n     - Upload your JD files (PDFs or Google Docs) with clear, descriptive filenames\n     - Copy the folder ID from URL\n\n  5. **Configure workflow nodes**:\n     - In \"Receive Telegram Msg to Recruiter Bot\" node: Add Telegram API credentials\n     - In \"Extract LinkedIn Profile Information\" node: Replace `YOUR_APIFY_API_TOKEN` with your Apify token\n     - In \"Check LinkedIn Profile Extraction Status\" node: Replace `YOUR_APIFY_API_TOKEN` with your Apify token\n     - In \"Get Fully Extracted LinkedIn Profile Data\" node: Replace `YOUR_APIFY_API_TOKEN` with your Apify token\n     - In \"Access JD Files\" node: Update folder ID to your \"Job Descriptions\" folder\n     - In \"Get All Rows Matching Telegram Username\" node: Select your Google Sheet\n     - In \"Add Candidate Analysis in GSheet\" node: Select your Google Sheet and verify column mappings\n     - In \"Send Msg to Internal Talent Group\" node: Update chat ID to your Telegram group chat ID\n     - In \"Send Review Completed Msg to Talent Group\" node: Update chat ID and Google Sheet URL\n\n  6. **Add your company description**:\n     - In \"JD Matching Agent\" system message: Replace company description with your details\n     - In \"Detailed JD Matching Agent\" system message: Replace company description with your details\n     - In \"Recruiter Scoring Agent\" system message: Update company description\n\n  7. **Test the workflow**:\n     - Send a LinkedIn profile URL to your bot from Telegram\n     - Monitor execution to ensure all nodes run successfully\n     - Check Google Sheets for logged results\n\n  8. **Activate workflow**\n\n  ## Customizing this workflow\n  - **Change spam limits**: Edit \"Spam Check: Sent <4 LinkedIn Profiles?\" node to adjust maximum submissions (currently 3)\n  - **Adjust polling attempts**: Edit \"Checked 10x for LinkedIn Profile Data?\" node to change maximum polling attempts (currently 10) or modify wait time in \"Wait for LinkedIn Profile\" node (currently 15 seconds)\n  - **Change JD matching logic**: Edit \"JD Matching Agent\" node prompt to adjust how LinkedIn profiles are matched to roles (e.g., weight current role vs. overall experience)\n  - **Modify screening criteria**: Edit \"Recruiter Scoring Agent\" node system message to focus on specific qualities (culture fit, leadership potential, technical depth, industry experience, etc.)\n  - **Add more messaging platforms**: Add nodes to support WhatsApp, Discord, or other messaging platforms using similar URL-based triggers\n  - **Customize Telegram messages**: Edit notification nodes to change formatting, add emojis, or 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) and trigger different notification paths\n  - **Add candidate responses**: Connect nodes to automatically message candidates back via Telegram (confirmation, rejection, interview invite)\n  - **Add interview scheduling**: For approved candidates, send Telegram message with Cal.com or Calendly link so they can book their interview\n  - **Enrich with additional data**: Add nodes to cross-reference candidate data with other sources (GitHub, Twitter/X, company websites)\n  - **Multi-language support**: Add translation nodes to support candidates submitting profiles in different languages\n  - **Add human approval step**: Create buttons in Telegram group messages for instant Approve/Reject decisions that update Google Sheets\n\n\n**Pro tip**: Add your Telegram bot to your company's careers page with instructions like: \"Want fast-track screening? Share your LinkedIn profile with our AI recruiter: [@YourBotName](https://t.me/YourBotName)\""
      },
      "typeVersion": 1
    },
    {
      "id": "72520805-103e-4ad9-a009-f412f850250f",
      "name": "付箋11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2864,
        -1184
      ],
      "parameters": {
        "color": 7,
        "width": 512,
        "height": 768,
        "content": "![](https://i.postimg.cc/rpG2thBv/telegram4.jpg)\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": "![](https://i.postimg.cc/8Cdgry22/telegram3.jpg)"
      },
      "typeVersion": 1
    },
    {
      "id": "15541650-4176-4810-94a2-a517760f2f00",
      "name": "付箋13",
      "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![](https://i.postimg.cc/1z01NWkb/telegram2.jpg)"
      },
      "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": "![](https://i.postimg.cc/3wQHNMcz/telegram1.jpg)"
      },
      "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
          }
        ]
      ]
    },
    "c5584a89-5766-4a40-ade5-c801c689f5ae": {
      "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": "7ea5ec43-29b8-4815-96b1-8fad17f88cf8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e5af9a04-fa2a-45da-9758-a66b013114e9": {
      "ai_languageModel": [
        [
          {
            "node": "JD Matching Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "77100aff-9497-4915-b803-b55733a0ecb3": {
      "ai_languageModel": [
        [
          {
            "node": "Detailed JD Matching Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "de46c695-e870-444e-903d-0efa2d60a94e": {
      "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": "8ed28114-ce30-4aab-9847-334a152caac8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from File1": {
      "main": [
        [
          {
            "node": "Set JD Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1bca066f-1627-4351-9a0a-178c359cfb50": {
      "main": [
        [
          {
            "node": "Extract from File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7f0e5f13-db43-46ce-a9f2-d5608e0f07d9": {
      "main": [
        [
          {
            "node": "148a5324-f33f-4848-a8d0-2568ece924a3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7ea5ec43-29b8-4815-96b1-8fad17f88cf8": {
      "main": [
        [
          {
            "node": "Extract from File1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ad85be28-c5c8-4a52-98b4-772317740fc0": {
      "main": [
        [
          {
            "node": "3e963459-50fd-4326-a2e0-45890e1c10bc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Selected JD Format": {
      "main": [
        [
          {
            "node": "Recruiter Scoring Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6c09a56b-05c8-4e0d-bc7e-dc485dcdb744": {
      "main": [
        [
          {
            "node": "9fab2352-6fe9-4f12-b86a-c6623f716a03",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "148a5324-f33f-4848-a8d0-2568ece924a3": {
      "main": [
        [
          {
            "node": "9f93b9f6-b381-4947-8034-dbf37e5ea8d0",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait for LinkedIn Profile",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Recruiter Scoring Agent": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "8ed28114-ce30-4aab-9847-334a152caac8": {
      "main": [
        [
          {
            "node": "1bca066f-1627-4351-9a0a-178c359cfb50",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "5568dfe0-ef24-4335-8b78-4d189d0cc8a2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gather and Set Final Data": {
      "main": [
        [
          {
            "node": "637c9812-3f39-419d-8210-b60b025b92c8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for LinkedIn Profile": {
      "main": [
        [
          {
            "node": "ad85be28-c5c8-4a52-98b4-772317740fc0",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Detailed JD Matching Agent": {
      "main": [
        [
          {
            "node": "949885c6-2c82-4be6-92e7-7349faca7d89",
            "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
          }
        ]
      ]
    },
    "5568dfe0-ef24-4335-8b78-4d189d0cc8a2": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "97eea42e-0e47-4494-bceb-c0f172456fc6": {
      "main": [
        [
          {
            "node": "8903e8c4-5ae9-4d61-a426-7ed450a96c43",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Key LinkedIn Profile Data": {
      "main": [
        [
          {
            "node": "JD Matching Agent",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "637c9812-3f39-419d-8210-b60b025b92c8": {
      "main": [
        [
          {
            "node": "0db07b5d-cdce-4020-8d78-77ce2508491b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9fab2352-6fe9-4f12-b86a-c6623f716a03": {
      "main": [
        [
          {
            "node": "4792c59c-a665-426f-990d-b44155792783",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "543325a6-3cf2-42f5-a64b-95be550296c6": {
      "main": [
        [
          {
            "node": "90e80421-d74a-40a5-a632-656177579795",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "949885c6-2c82-4be6-92e7-7349faca7d89": {
      "main": [
        [
          {
            "node": "Recruiter Scoring Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "083be177-e9dd-4469-b501-f76b8c498a11": {
      "main": [
        [
          {
            "node": "Start Msg Sent + Valid LinkedIn Profile URL?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3e963459-50fd-4326-a2e0-45890e1c10bc": {
      "main": [
        [],
        [
          {
            "node": "fa9b7243-97ff-41a8-a5fc-50ef75e72ad3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d132d927-781d-4bd2-aca1-ff77d4e0f134": {
      "main": [
        [
          {
            "node": "543325a6-3cf2-42f5-a64b-95be550296c6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "90e80421-d74a-40a5-a632-656177579795": {
      "main": [
        [
          {
            "node": "6c09a56b-05c8-4e0d-bc7e-dc485dcdb744",
            "type": "main",
            "index": 0
          },
          {
            "node": "97eea42e-0e47-4494-bceb-c0f172456fc6",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "0687fa9f-2c46-4858-a4a1-4e1783204719",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fa9b7243-97ff-41a8-a5fc-50ef75e72ad3": {
      "main": [
        [
          {
            "node": "7f0e5f13-db43-46ce-a9f2-d5608e0f07d9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9f93b9f6-b381-4947-8034-dbf37e5ea8d0": {
      "main": [
        [
          {
            "node": "Set Key LinkedIn Profile Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start Msg Sent + Valid LinkedIn Profile URL?": {
      "main": [
        [
          {
            "node": "d132d927-781d-4bd2-aca1-ff77d4e0f134",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "4c5e2b97-4c1c-40db-9d4f-89c51c03c939",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4792c59c-a665-426f-990d-b44155792783": {
      "main": [
        [
          {
            "node": "fa9b7243-97ff-41a8-a5fc-50ef75e72ad3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
よくある質問

このワークフローの使い方は?

上記のJSON設定コードをコピーし、n8nインスタンスで新しいワークフローを作成して「JSONからインポート」を選択、設定を貼り付けて認証情報を必要に応じて変更してください。

このワークフローはどんな場面に適していますか?

上級 - 人事, AI要約

有料ですか?

このワークフローは完全無料です。ただし、ワークフローで使用するサードパーティサービス(OpenAI APIなど)は別途料金が発生する場合があります。

ワークフロー情報
難易度
上級
ノード数55
カテゴリー2
ノードタイプ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で表示

このワークフローを共有

カテゴリー

カテゴリー: 34