{
  "id": "u6seZCMlUCt4sZqF",
  "meta": {
    "templateId": "1961",
    "templateCredsSetupCompleted": true
  },
  "name": "Building an AI-Powered Chatbot for Candidate Evaluation on Slack",
  "tags": [],
  "nodes": [
    {
      "id": "97989831-3fc6-4954-ac55-8e0950081b7a",
      "name": "Is user message?",
      "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": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -3088,
        976
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "4a7ec607-1706-4357-aa89-4c44faa98fb8",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -3536,
        880
      ],
      "parameters": {
        "path": "slack-gilfoyle",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode"
      },
      "typeVersion": 2
    },
    {
      "id": "04301600-3371-4fba-b2a6-509bfd3809f9",
      "name": "Extract from File",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -2640,
        688
      ],
      "parameters": {
        "options": {},
        "operation": "pdf",
        "binaryPropertyName": "=data"
      },
      "typeVersion": 1
    },
    {
      "id": "1f49b4bf-5a06-42cc-8566-440639d15aeb",
      "name": "Download Candidate Profile From 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": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "04940f53-05e2-4dbb-8bbe-2c6104cf978b",
      "name": "json parser",
      "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 model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -2416,
        912
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "7091e495-668b-4fed-a5f9-de2333908a3d",
      "name": "Download file",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -1952,
        688
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $json.output.JobDescription }}"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "d3067e57-7b79-4dff-bbdd-31ae43228a34",
      "name": "Extract Job Description",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -1728,
        688
      ],
      "parameters": {
        "options": {},
        "operation": "pdf"
      },
      "typeVersion": 1
    },
    {
      "id": "cc30fbc4-c777-4556-a89c-3d782bedc7cf",
      "name": "HR Expert Agent",
      "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\u2019s 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": "Profile Analyzer Agent",
      "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\u2019s **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\u2019s 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": "Update evaluation sheet",
      "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": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "2f406e89-d1d9-458a-839a-f9c612184714",
      "name": "Map Columns",
      "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 model 2",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -1472,
        912
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "74430118-e4d3-4966-8703-c2ffa483b895",
      "name": "json parser 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": "If",
      "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": "Send result in the mentioned channel",
      "type": "n8n-nodes-base.slack",
      "position": [
        -656,
        592
      ],
      "parameters": {
        "text": "=\ud83c\udfaf *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\ud83d\udc64 *Candidate:* {{ $('Map Columns').item.json.full_name }}\n\ud83d\udcdd *Summary:*  \n\u2022 *Fit Score:* {{ $('Map Columns').item.json.overall_fit_score }}/10  \n\u2022 *Recommendation:* {{ $('Map Columns').item.json.recommendation }}\n\u2022 *Key Strengths:* {{ $('Map Columns').item.json.strengths }}\n\ud83d\udc49 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": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "e41b4a81-7feb-45df-bbe8-ad006e6ebdb8",
      "name": "Inform user that profile is missing",
      "type": "n8n-nodes-base.slack",
      "position": [
        -2864,
        880
      ],
      "parameters": {
        "text": "=\ud83d\uddc2\ufe0f Got it \u2014 just one more thing!\nI can help read the candidate profile you mentioned, but it looks like I didn\u2019t catch the file in your last message.\n\ud83d\udc49 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! \ud83d\ude0a",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Webhook').item.json.body.event.channel }}"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "64818e9c-f6d3-4b05-8297-b7b9089044ca",
      "name": "Query available positions",
      "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": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "64560334-5db8-4d2d-b5e7-ad4b865cb0bd",
      "name": "Get information about a user",
      "type": "n8n-nodes-base.slack",
      "position": [
        -880,
        592
      ],
      "parameters": {
        "user": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Webhook').item.json.body.event.files[0].user }}"
        },
        "resource": "user",
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "7e1f48d9-ae9c-43e2-ae89-09d207e3a33f",
      "name": "Sticky Note",
      "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\u2019s 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 \u2192 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\u2019s 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": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3616,
        1040
      ],
      "parameters": {
        "width": 272,
        "height": 192,
        "content": "### 1. \ud83d\ude80 Trigger on Slack Mention\nWhen a Slack user mentions the HR bot and includes a message (e.g. \u201cPlease evaluate this candidate for the AI Engineer role\u201d) along with an attached PDF resume, the workflow is triggered via webhook."
      },
      "typeVersion": 1
    },
    {
      "id": "69148cf4-dff4-417d-acf6-a506deadee53",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3296,
        1136
      ],
      "parameters": {
        "width": 384,
        "height": 128,
        "content": "### 2. \ud83e\uddfe 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": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2880,
        528
      ],
      "parameters": {
        "width": 352,
        "height": 128,
        "content": "### 3. \ud83d\udce5 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": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2432,
        416
      ],
      "parameters": {
        "width": 336,
        "height": 240,
        "content": "### 4. \ud83e\udde0 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": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1952,
        880
      ],
      "parameters": {
        "width": 336,
        "height": 128,
        "content": "### 5. \ud83d\udcc4 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": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1552,
        480
      ],
      "parameters": {
        "width": 368,
        "content": "### 6. \ud83d\udc69\u200d\ud83d\udcbc 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": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -880,
        416
      ],
      "parameters": {
        "width": 272,
        "height": 144,
        "content": "### 7. \ud83d\udce4 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": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -896,
        960
      ],
      "parameters": {
        "width": 288,
        "height": 128,
        "content": "### 8. \ud83d\udcca 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,
  "settings": {},
  "versionId": "862307b9-766b-4c14-bd23-46de364fff6c",
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Download Candidate Profile From Slack",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Inform user that profile is missing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Is user message?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Map Columns": {
      "main": [
        [
          {
            "node": "Update evaluation sheet",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get information about a user",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "json parser": {
      "ai_outputParser": [
        [
          {
            "node": "Profile Analyzer Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "gpt4-1 model": {
      "ai_languageModel": [
        [
          {
            "node": "Profile Analyzer Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Download file": {
      "main": [
        [
          {
            "node": "Extract Job Description",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "json parser 2": {
      "ai_outputParser": [
        [
          {
            "node": "HR Expert Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "HR Expert Agent": {
      "main": [
        [
          {
            "node": "Map Columns",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "gpt-4-1 model 2": {
      "ai_languageModel": [
        [
          {
            "node": "HR Expert Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Is user message?": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from File": {
      "main": [
        [
          {
            "node": "Profile Analyzer Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Profile Analyzer Agent": {
      "main": [
        [
          {
            "node": "Download file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Job Description": {
      "main": [
        [
          {
            "node": "HR Expert Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Query available positions": {
      "ai_tool": [
        [
          {
            "node": "Profile Analyzer Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get information about a user": {
      "main": [
        [
          {
            "node": "Send result in the mentioned channel",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send result in the mentioned channel": {
      "main": [
        []
      ]
    },
    "Download Candidate Profile From Slack": {
      "main": [
        [
          {
            "node": "Extract from File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}