8
n8n 한국어amn8n.com

Slack 후보자 평가를 위한 AI 기반 챗봇 구축

고급

이것은AI Chatbot, Multimodal AI분야의자동화 워크플로우로, 29개의 노드를 포함합니다.주로 If, Code, Slack, Webhook, GoogleDrive 등의 노드를 사용하며. AI 이력서 분석 및 후보자 평가: Slack과 Google 스프레드시트 통합

사전 요구사항
  • Slack Bot Token 또는 Webhook URL
  • HTTP Webhook 엔드포인트(n8n이 자동으로 생성)
  • Google Drive API 인증 정보
  • 대상 API의 인증 정보가 필요할 수 있음
  • Google Sheets API 인증 정보
  • OpenAI API Key
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
  "id": "u6seZCMlUCt4sZqF",
  "meta": {
    "instanceId": "4a2e6764ba7a6bc9890d9225f4b21d570ce88fc9bd57549c89057fcee58fed0f",
    "templateId": "1961",
    "templateCredsSetupCompleted": true
  },
  "name": "Building an AI-Powered Chatbot for Candidate Evaluation on Slack",
  "tags": [],
  "nodes": [
    {
      "id": "97989831-3fc6-4954-ac55-8e0950081b7a",
      "name": "사용자 메시지인가?",
      "type": "n8n-nodes-base.if",
      "position": [
        -3312,
        880
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "1def7344-ce55-450d-a85a-468f746fe31f",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.body.event.type }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "afa6b192-1e25-46b6-8fdc-81dff9a37e74",
      "name": "작업 없음, 아무것도 하지 않음",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -3088,
        976
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "4a7ec607-1706-4357-aa89-4c44faa98fb8",
      "name": "웹훅",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -3536,
        880
      ],
      "webhookId": "db3bf3da-b9b7-4823-8c5d-14f5de0272da",
      "parameters": {
        "path": "slack-gilfoyle",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode"
      },
      "typeVersion": 2
    },
    {
      "id": "04301600-3371-4fba-b2a6-509bfd3809f9",
      "name": "파일에서 추출",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -2640,
        688
      ],
      "parameters": {
        "options": {},
        "operation": "pdf",
        "binaryPropertyName": "=data"
      },
      "typeVersion": 1
    },
    {
      "id": "1f49b4bf-5a06-42cc-8566-440639d15aeb",
      "name": "Slack에서 후보자 프로필 다운로드",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2864,
        688
      ],
      "parameters": {
        "url": "={{ $json.body.event.files[0].url_private_download }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        },
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "slackOAuth2Api"
      },
      "credentials": {
        "slackOAuth2Api": {
          "id": "4JSKt9sIRV1KGswQ",
          "name": "Slack account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "04940f53-05e2-4dbb-8bbe-2c6104cf978b",
      "name": "json 파서",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -2160,
        912
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"AppliedPosition\": \"Position Name\",\n  \"JobDescription\": \"Job Description URL\",\n  \"Profile\": {\n    \"full_name\": \"\",\n    \"job_title\": \"\",\n    \"summary\": \"\",\n    \"contact\": {\n      \"email\": \"\",\n      \"phone\": \"\",\n      \"address\": \"\",\n      \"linkedin\": \"\",\n      \"website\": \"\"\n    },\n    \"education\": [\n      {\n        \"degree\": \"\",\n        \"field_of_study\": \"\",\n        \"institution\": \"\",\n        \"location\": \"\",\n        \"start_year\": \"\",\n        \"end_year\": \"\"\n      }\n    ],\n    \"certifications\": [\n      {\n        \"name\": \"\",\n        \"issuer\": \"\",\n        \"date_obtained\": \"\",\n        \"expiration_date\": \"\"\n      }\n    ],\n    \"work_experience\": [\n      {\n        \"company\": \"\",\n        \"position\": \"\",\n        \"location\": \"\",\n        \"start_date\": \"\",\n        \"end_date\": \"\",\n        \"responsibilities\": [\n          \"\"\n        ],\n        \"achievements\": [\n          \"\"\n        ]\n      }\n    ],\n    \"skills\": {\n      \"technical_skills\": [\n        \"\"\n      ],\n      \"soft_skills\": [\n        \"\"\n      ],\n      \"languages\": [\n        {\n          \"language\": \"\",\n          \"proficiency\": \"\"\n        }\n      ],\n      \"tools_and_technologies\": [\n        \"\"\n      ]\n    },\n    \"projects\": [\n      {\n        \"name\": \"\",\n        \"description\": \"\",\n        \"technologies_used\": [\n          \"\"\n        ],\n        \"role\": \"\",\n        \"duration\": \"\"\n      }\n    ],\n    \"awards\": [\n      {\n        \"title\": \"\",\n        \"issuer\": \"\",\n        \"date\": \"\",\n        \"description\": \"\"\n      }\n    ],\n    \"volunteer_experience\": [\n      {\n        \"organization\": \"\",\n        \"role\": \"\",\n        \"description\": \"\",\n        \"start_date\": \"\",\n        \"end_date\": \"\"\n      }\n    ],\n    \"additional_information\": {\n      \"availability\": \"\",\n      \"preferred_location\": \"\",\n      \"salary_expectation\": \"\",\n      \"work_authorization\": \"\",\n      \"other_notes\": \"\"\n    }\n  }\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "0609ac69-6003-4948-a847-d6e3fcb326da",
      "name": "gpt4-1 모델",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -2416,
        912
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "PPSwAKeLQYgAPobT",
          "name": "OpenAi account"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "7091e495-668b-4fed-a5f9-de2333908a3d",
      "name": "파일 다운로드",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -1952,
        688
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $json.output.JobDescription }}"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "fC471es5gk5Mm900",
          "name": "Google Drive account"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "d3067e57-7b79-4dff-bbdd-31ae43228a34",
      "name": "직무 설명서 추출",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -1728,
        688
      ],
      "parameters": {
        "options": {},
        "operation": "pdf"
      },
      "typeVersion": 1
    },
    {
      "id": "cc30fbc4-c777-4556-a89c-3d782bedc7cf",
      "name": "HR 전문가 에이전트",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        -1504,
        688
      ],
      "parameters": {
        "text": "=Evaluate the candidate for the following job:\n\n--- Job Description ---\nPosition: {{ $('Profile Analyzer Agent').item.json.output.AppliedPosition }}\nJob Description: {{ $('Extract Job Description').item.json.text }}\n------------------------\n\nBelow is the extracted candidate profile:\n{{ $('Profile Analyzer Agent').item.json.output.Profile.toJsonString() }}",
        "messages": {
          "messageValues": [
            {
              "message": "You are a professional AI hiring assistant tasked with evaluating job candidates based on their structured resume data and a provided job description. Your goal is to assess the candidate’s suitability for the role, identifying key matches and gaps in skills, experience, and qualifications.  You will receive: - `candidate_profile`: a JSON object containing extracted information from the candidate's resume. - `job_description`: a plain text description of the role.  Your job is to: 1. Parse and understand the key job requirements (e.g., required skills, years of experience, qualifications). 2. Match the candidate's profile to the job requirements. 3. Provide a structured evaluation with ratings and reasoning.  Always be objective, use professional language, and format your output clearly using markdown."
            }
          ]
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.5
    },
    {
      "id": "9e39fb8d-e66b-4767-a04b-c35a5cbd37f7",
      "name": "프로필 분석기 에이전트",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -2384,
        688
      ],
      "parameters": {
        "text": "=Please extract all relevant information from this candiadte:\nCV Content:\n===\n{{ $json[\"text\"] }}\n===\nAnd extract applied position from message below:\n{{ $('Webhook').item.json.body.event.text }}\nGiven the tool to get postions from google sheet, conclude final applied position name follw name in the sheet and the job description URL",
        "options": {
          "systemMessage": "You are a smart and reliable assistant for the HR team. Your job is to help evaluate job applicants by processing two main inputs:\n\n1. The candidate’s **user profile** (provided as a block of plain text).\n2. The **request message** (typically a short Slack or email message from a recruiter asking for evaluation).\n\nYou also have access to a **Google Sheets tool** containing a table that maps position names (e.g., \"AI Engineer\") to job details such as:\n- Job title\n- Job description URL\n\n---\n\nYour task is to:\n1. Parse and extract the **candidate’s name, email (if any), and core skills or summary** from the user profile.\n2. From the request message, identify the **applied position**.\n3. Use the Sheets tool to look up and return:\n   - The **applied position** (standardized from the sheet)\n   - The corresponding **Job Description URL**\n\n---\n\nOutput Format:\n- **Candidate Profile**: [Parsed name, email, and summary from resume]\n- **Applied Position**: [From sheet, matched using request message]\n- **Job Description URL**: [From sheet, based on position]\n\nIf the job title from the request is unclear or not found, return a helpful clarification message instead of making assumptions.\n\n---\n\nBe concise, structured, and ensure accurate matching when referencing job titles from the sheet."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "executeOnce": true,
      "typeVersion": 2.1
    },
    {
      "id": "3b996554-5e83-4ffe-9142-f52883e15573",
      "name": "평가 시트 업데이트",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -880,
        784
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "overall_fit_score",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "overall_fit_score",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "recommendation",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "recommendation",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "required_experience",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "required_experience",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "skill_match",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "skill_match",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "education_certifications",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "education_certifications",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "soft_skills_traits",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "soft_skills_traits",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "strengths",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "strengths",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "concerns_or_gaps",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "concerns_or_gaps",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "final_notes",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "final_notes",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [
            "output"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/1gpuTL7iK2LoDJAdHE-LBFiBEU6hLqSTxWjThMJyi7SY/edit?usp=drive_link"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "L670Nly6gZGo71br",
          "name": "Google Sheets account 2"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "2f406e89-d1d9-458a-839a-f9c612184714",
      "name": "열 매핑",
      "type": "n8n-nodes-base.code",
      "position": [
        -1104,
        688
      ],
      "parameters": {
        "jsCode": "const evalResult = $input.first().json.output\nreturn [\n  {\n    json: {\n      full_name: $('Profile Analyzer Agent').first().json.output.Profile.full_name,\n      email: $('Profile Analyzer Agent').first().json.output.Profile.contact.email || \"Email not available\",\n      phone: $('Profile Analyzer Agent').first().json.output.Profile.contact.phone ||  \"Phone not available\",\n      position: $('Profile Analyzer Agent').first().json.output.AppliedPosition,\n      overall_fit_score: evalResult.overall_fit_score,\n      recommendation: evalResult.recommendation,\n      strengths: evalResult.strengths.join(', '),\n      concerns_or_gaps: evalResult.concerns_or_gaps.join(', '),\n      final_notes: evalResult.final_notes,\n      submitted_date: $now.toFormat(\"yyyyLLdd-HHmmss\")\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "14ddc37b-9286-46a8-bdeb-d333db447d24",
      "name": "gpt-4-1 모델 2",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -1472,
        912
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "PPSwAKeLQYgAPobT",
          "name": "OpenAi account"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "74430118-e4d3-4966-8703-c2ffa483b895",
      "name": "json 파서 2",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -1344,
        912
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"overall_fit_score\": 0,\n  \"recommendation\": \"\", \n  \"job_match_summary\": {\n    \"required_experience\": \"\",\n    \"skill_match\": \"\",\n    \"education_certifications\": \"\",\n    \"soft_skills_traits\": \"\"\n  },\n  \"strengths\": [\n    \"\"\n  ],\n  \"concerns_or_gaps\": [\n    \"\"\n  ],\n  \"final_notes\": \"\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "83a9bea2-1012-4ad6-a6db-145c74086b30",
      "name": "조건문",
      "type": "n8n-nodes-base.if",
      "position": [
        -3088,
        784
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "aa58b881-6e48-488b-a96c-9a85b1504a6e",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.body.event.files[0].id }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "d8a4b76d-1bbd-4fee-b024-ffa824829558",
      "name": "언급된 채널에 결과 전송",
      "type": "n8n-nodes-base.slack",
      "position": [
        -656,
        592
      ],
      "webhookId": "6d1ea29f-86ba-42df-ae9f-3dd510510dae",
      "parameters": {
        "text": "=🎯 *Candidate Evaluation Update*\n\nHi <@{{ $json.id }}>,  \nWe've completed the initial screening and have a qualified candidate for the {{ $('Map Columns').item.json.position }} position:\n\n👤 *Candidate:* {{ $('Map Columns').item.json.full_name }}\n📝 *Summary:*  \n• *Fit Score:* {{ $('Map Columns').item.json.overall_fit_score }}/10  \n• *Recommendation:* {{ $('Map Columns').item.json.recommendation }}\n• *Key Strengths:* {{ $('Map Columns').item.json.strengths }}\n👉 Please advise on next steps (e.g., schedule technical interview, team round, etc.).",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Webhook').item.json.body.event.channel }}"
        },
        "otherOptions": {
          "mrkdwn": true
        }
      },
      "credentials": {
        "slackApi": {
          "id": "Yi3LKjrxH5dH4v1r",
          "name": "BOT Token"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "e41b4a81-7feb-45df-bbe8-ad006e6ebdb8",
      "name": "프로필이 누락되었음을 사용자에게 알림",
      "type": "n8n-nodes-base.slack",
      "position": [
        -2864,
        880
      ],
      "webhookId": "6d1ea29f-86ba-42df-ae9f-3dd510510dae",
      "parameters": {
        "text": "=🗂️ Got it — just one more thing!\nI can help read the candidate profile you mentioned, but it looks like I didn’t catch the file in your last message.\n👉 Please upload the file first, wait for it to finish uploading, and then press Enter to send your message.\nThat way, I can grab the profile and help you out right away! 😊",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Webhook').item.json.body.event.channel }}"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "id": "Yi3LKjrxH5dH4v1r",
          "name": "BOT Token"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "64818e9c-f6d3-4b05-8297-b7b9089044ca",
      "name": "가능한 포지션 조회",
      "type": "n8n-nodes-base.googleSheetsTool",
      "position": [
        -2288,
        912
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/15CZPMbxmz-RVYji1fev_6vYeEwpPa3MjewGEPf6aSoA/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "15CZPMbxmz-RVYji1fev_6vYeEwpPa3MjewGEPf6aSoA",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/15CZPMbxmz-RVYji1fev_6vYeEwpPa3MjewGEPf6aSoA/edit?usp=drivesdk",
          "cachedResultName": "Positions"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "L670Nly6gZGo71br",
          "name": "Google Sheets account 2"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "64560334-5db8-4d2d-b5e7-ad4b865cb0bd",
      "name": "사용자 정보 가져오기",
      "type": "n8n-nodes-base.slack",
      "position": [
        -880,
        592
      ],
      "webhookId": "5299729f-620c-4984-80be-001f1d7e9740",
      "parameters": {
        "user": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Webhook').item.json.body.event.files[0].user }}"
        },
        "resource": "user",
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "id": "4JSKt9sIRV1KGswQ",
          "name": "Slack account"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "7e1f48d9-ae9c-43e2-ae89-09d207e3a33f",
      "name": "스티키 노트",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4672,
        -224
      ],
      "parameters": {
        "color": 4,
        "width": 1056,
        "height": 2432,
        "content": "# Building an AI-Powered Chatbot for Candidate Evaluation on Slack\n[![Watch the video](https://wisestackai.s3.ap-southeast-1.amazonaws.com/building-an-ai-powered-chatbot-for-candidate-evaluation-on-slack.jpg)](https://www.youtube.com/watch?v=NAn5BSr15Ks)\n> This workflow connects a Slack chatbot with AI agents and Google Sheets to automate candidate resume evaluation. It extracts resume details, identifies the applied job from the message, fetches the correct job description, and provides a summarized evaluation via Slack and tracking sheet. Perfect for HR teams using Slack.\n\n## **Who’s it for**\nThis workflow is designed for:\n- **HR Teams**, **Recruiters**, and **Hiring Managers**  \n- Working in software or tech companies using **Slack**, **Google Sheets**, and **n8n**\n- Who want to **automate candidate evaluation** based on uploaded profiles and applied job positions\n\n## **How it works / What it does**\nThis workflow is triggered when a **Slack user mentions the HR bot** and attaches a **candidate profile PDF**.\nThe workflow performs the following steps:\n1. **Trigger from Slack Mention**  \n   - A user mentions the bot in Slack with a message like:  \n     `@HRBot Please evaluate this candidate for the AI Engineer role.`  \n     (with PDF attached)\n2. **Input Validation**  \n   - If no file is attached, the bot replies:  \n     _\"Please upload the candidate profile file before sending the message.\"_\n3. **Extract Candidate Profile**  \n   - Downloads the attached PDF from Slack  \n   - Uses `Extract from File` to parse the resume into text\n4. **Profile Analysis (AI Agent)**  \n   - Sends the resume text and message to the `Profile Analyzer Agent`\n   - Identifies:\n     - Candidate name, email, and summary\n     - Applied position (from message)\n   - Looks up the **Job Description PDF URL** using Google Sheets\n5. **Job Description Retrieval**  \n   - Downloads and parses the matching JD PDF\n6. **HR Evaluation (AI Agent)**  \n   - Sends both the **candidate profile** and **job description** to `HR Expert Agent`\n   - Receives a summarized **fit evaluation** and insights\n7. **Output and Logging**  \n   - Sends evaluation result back to Slack in the original thread  \n   - Updates a **Google Sheet** with evaluation data for tracking\n\n## **How to set up**\n1. **Slack Setup**\n   - Create a Slack bot and install it into your workspace\n   - Enable the `app_mention` event and generate a **bot token**\n   - Connect Slack to n8n using **Slack Bot credentials**\n2. **Google Sheets Setup**\n   - Create a sheet mapping `Position Title → Job Description URL`\n   - Create another sheet for logging evaluation results\n3. **n8n Setup**\n   - Add a **Webhook Trigger** for Slack mentions\n   - Connect Slack, Google Sheets, and GPT-4 credentials\n   - Set up agents (`Profile Analyzer Agent`, `HR Expert Agent`) with appropriate prompts\n4. **Deploy & Test**\n   - Mention your bot in Slack with a message and file\n   - Confirm the reply and entry in the evaluation tracking sheet\n\n## **Requirements**\n\n- n8n (self-hosted or cloud)\n- Slack App with Bot Token\n- OpenAI or Azure OpenAI account (for GPT-4)\n- Google Sheets (2 sheets: job mapping + evaluation log)\n- Candidate profiles in PDF format\n- Defined job titles and descriptions\n\n## **How to customize the workflow**\n\nYou can easily adapt this workflow to your team’s needs:\n| Customization Area       | How to Customize                                                                 |\n|--------------------------|----------------------------------------------------------------------------------|\n| Job Mapping Source       | Replace Google Sheet with Airtable or Notion DB                                 |\n| JD Format                | Use Markdown or inline descriptions instead of PDF                              |\n| Evaluation Output Format | Change from Slack message to Email or Notion update                             |\n| HR Agent Prompt          | Customize to match your company tone or include scoring rubrics                 |\n| Language Support         | Add support for bilingual input/output (e.g., Vietnamese & English)             |\n| Workflow Trigger         | Trigger from slash command or form instead of `@mention`                        |"
      },
      "typeVersion": 1
    },
    {
      "id": "9f5d8dfa-905b-4593-b75d-82d4cb826106",
      "name": "스티키 노트1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3616,
        1040
      ],
      "parameters": {
        "width": 272,
        "height": 192,
        "content": "### 1. 🚀 Trigger on Slack Mention\nWhen a Slack user mentions the HR bot and includes a message (e.g. “Please evaluate this candidate for the AI Engineer role”) along with an attached PDF resume, the workflow is triggered via webhook."
      },
      "typeVersion": 1
    },
    {
      "id": "69148cf4-dff4-417d-acf6-a506deadee53",
      "name": "스티키 노트2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3296,
        1136
      ],
      "parameters": {
        "width": 384,
        "height": 128,
        "content": "### 2. 🧾 Validate Input\nThe workflow checks if a file (PDF) is attached. If not, it sends a friendly message back to the user, asking them to upload the resume before sending the request."
      },
      "typeVersion": 1
    },
    {
      "id": "9aba6130-c3b5-4045-8ec1-09ae606f2263",
      "name": "스티키 노트3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2880,
        528
      ],
      "parameters": {
        "width": 352,
        "height": 128,
        "content": "### 3. 📥 Download and Extract Resume\nThe bot downloads the attached PDF resume and uses the `Extract from File` module to convert the document into readable plain text.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "22361750-c673-49e7-927e-e9551724abc1",
      "name": "스티키 노트4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2432,
        416
      ],
      "parameters": {
        "width": 336,
        "height": 240,
        "content": "### 4. 🧠 Analyze Profile (AI Agent)\nThe extracted resume text and user request message are sent to the **Profile Analyzer Agent**, which:\n- Extracts candidate details (name, email, skills, summary)\n- Identifies the **applied job position** from the message\n- Queries a Google Sheet to retrieve the corresponding **Job Description URL**"
      },
      "typeVersion": 1
    },
    {
      "id": "f47d2b7d-00fb-409a-93e6-3d16c65ad918",
      "name": "스티키 노트5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1952,
        880
      ],
      "parameters": {
        "width": 336,
        "height": 128,
        "content": "### 5. 📄 Fetch and Extract Job Description\nUsing the matched Job Description URL from the Google Sheet, the workflow downloads and parses the JD PDF into plain text."
      },
      "typeVersion": 1
    },
    {
      "id": "81d73e30-1b8b-48dc-9fd8-495c2b8a6cee",
      "name": "스티키 노트6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1552,
        480
      ],
      "parameters": {
        "width": 368,
        "content": "### 6. 👩‍💼 Evaluate Candidate (HR Expert Agent)\nThe candidate profile and job description are passed to the **HR Expert Agent**, which:\n- Assesses the fit between the resume and job description\n- Outputs a summary evaluation and insights"
      },
      "typeVersion": 1
    },
    {
      "id": "b1443b1d-e175-4e01-ba34-2002ae23b740",
      "name": "스티키 노트7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -880,
        416
      ],
      "parameters": {
        "width": 272,
        "height": 144,
        "content": "### 7. 📤 Send Results via Slack\nThe evaluation result is posted back to the **Slack thread** where the request originated, notifying the original user with a clean and readable summary."
      },
      "typeVersion": 1
    },
    {
      "id": "5c9af46b-bcf2-403f-a67b-bdf4b3ce9f2d",
      "name": "스티키 노트8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -896,
        960
      ],
      "parameters": {
        "width": 288,
        "height": 128,
        "content": "### 8. 📊 Log to Google Sheet\nThe evaluation result, along with candidate and job data, is saved into a **Google Sheet** for internal tracking, auditing, or reporting purposes."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {},
  "versionId": "862307b9-766b-4c14-bd23-46de364fff6c",
  "connections": {
    "83a9bea2-1012-4ad6-a6db-145c74086b30": {
      "main": [
        [
          {
            "node": "1f49b4bf-5a06-42cc-8566-440639d15aeb",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "e41b4a81-7feb-45df-bbe8-ad006e6ebdb8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4a7ec607-1706-4357-aa89-4c44faa98fb8": {
      "main": [
        [
          {
            "node": "97989831-3fc6-4954-ac55-8e0950081b7a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2f406e89-d1d9-458a-839a-f9c612184714": {
      "main": [
        [
          {
            "node": "3b996554-5e83-4ffe-9142-f52883e15573",
            "type": "main",
            "index": 0
          },
          {
            "node": "64560334-5db8-4d2d-b5e7-ad4b865cb0bd",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "04940f53-05e2-4dbb-8bbe-2c6104cf978b": {
      "ai_outputParser": [
        [
          {
            "node": "9e39fb8d-e66b-4767-a04b-c35a5cbd37f7",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "0609ac69-6003-4948-a847-d6e3fcb326da": {
      "ai_languageModel": [
        [
          {
            "node": "9e39fb8d-e66b-4767-a04b-c35a5cbd37f7",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "7091e495-668b-4fed-a5f9-de2333908a3d": {
      "main": [
        [
          {
            "node": "d3067e57-7b79-4dff-bbdd-31ae43228a34",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "74430118-e4d3-4966-8703-c2ffa483b895": {
      "ai_outputParser": [
        [
          {
            "node": "cc30fbc4-c777-4556-a89c-3d782bedc7cf",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "cc30fbc4-c777-4556-a89c-3d782bedc7cf": {
      "main": [
        [
          {
            "node": "2f406e89-d1d9-458a-839a-f9c612184714",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "14ddc37b-9286-46a8-bdeb-d333db447d24": {
      "ai_languageModel": [
        [
          {
            "node": "cc30fbc4-c777-4556-a89c-3d782bedc7cf",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "97989831-3fc6-4954-ac55-8e0950081b7a": {
      "main": [
        [
          {
            "node": "83a9bea2-1012-4ad6-a6db-145c74086b30",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "afa6b192-1e25-46b6-8fdc-81dff9a37e74",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "04301600-3371-4fba-b2a6-509bfd3809f9": {
      "main": [
        [
          {
            "node": "9e39fb8d-e66b-4767-a04b-c35a5cbd37f7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9e39fb8d-e66b-4767-a04b-c35a5cbd37f7": {
      "main": [
        [
          {
            "node": "7091e495-668b-4fed-a5f9-de2333908a3d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d3067e57-7b79-4dff-bbdd-31ae43228a34": {
      "main": [
        [
          {
            "node": "cc30fbc4-c777-4556-a89c-3d782bedc7cf",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "64818e9c-f6d3-4b05-8297-b7b9089044ca": {
      "ai_tool": [
        [
          {
            "node": "9e39fb8d-e66b-4767-a04b-c35a5cbd37f7",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "64560334-5db8-4d2d-b5e7-ad4b865cb0bd": {
      "main": [
        [
          {
            "node": "d8a4b76d-1bbd-4fee-b024-ffa824829558",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d8a4b76d-1bbd-4fee-b024-ffa824829558": {
      "main": [
        []
      ]
    },
    "1f49b4bf-5a06-42cc-8566-440639d15aeb": {
      "main": [
        [
          {
            "node": "04301600-3371-4fba-b2a6-509bfd3809f9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
자주 묻는 질문

이 워크플로우를 어떻게 사용하나요?

위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.

이 워크플로우는 어떤 시나리오에 적합한가요?

고급 - AI 챗봇, 멀티모달 AI

유료인가요?

이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.

워크플로우 정보
난이도
고급
노드 수29
카테고리2
노드 유형15
난이도 설명

고급 사용자를 위한 16+개 노드의 복잡한 워크플로우

저자
Trung Tran

Trung Tran

@trungtran

Empowering small and medium businesses with smart automation and practical AI, no big tech team required.

외부 링크
n8n.io에서 보기

이 워크플로우 공유

카테고리

카테고리: 34