{
  "name": "13 - AI-Powered Recruitment Pipeline",
  "nodes": [
    {
      "id": "node-1",
      "name": "Webhook - New Application",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [240, 300],
      "parameters": { "httpMethod": "POST", "path": "job-application", "responseMode": "responseNode" }
    },
    {
      "id": "node-2",
      "name": "Code - Validate Application",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [480, 300],
      "parameters": {
        "jsCode": "const a = $input.first().json;\nif (!a.email || !a.name) throw new Error('Missing required fields: email and name');\nreturn [{ json: { application_id: a.id||`APP-${Date.now()}`, candidate_name: a.name, candidate_email: a.email, candidate_phone: a.phone||'', linkedin_url: a.linkedin||'', resume_text: a.resume_text||'', job_title: a.job_title||'Open Position', job_requirements: a.job_requirements||'Strong communication, relevant experience, problem solving', department: a.department||'General', source: a.source||'website', applied_at: new Date().toISOString() } }];"
      }
    },
    {
      "id": "node-3",
      "name": "OpenAI - Screen Resume",
      "type": "n8n-nodes-base.openAi",
      "typeVersion": 1.8,
      "position": [720, 300],
      "credentials": { "openAiApi": { "id": "YOUR_OPENAI_CREDENTIAL_ID", "name": "OpenAI account" } },
      "parameters": {
        "resource": "chat",
        "operation": "complete",
        "modelId": { "__rl": true, "value": "gpt-4o", "mode": "list", "cachedResultName": "gpt-4o" },
        "messages": {
          "values": [
            { "role": "system", "content": "You are an expert recruiter. Screen resumes objectively. Return ONLY valid JSON: {\"score\": number (1-100), \"strengths\": [string], \"gaps\": [string], \"recommendation\": \"advance|maybe|reject\", \"summary\": string, \"interview_questions\": [string]}" },
            { "role": "user", "content": "=Role: {{ $json.job_title }}\nRequirements: {{ $json.job_requirements }}\n\nCandidate: {{ $json.candidate_name }}\nLinkedIn: {{ $json.linkedin_url }}\nResume: {{ $json.resume_text }}" }
          ]
        },
        "options": { "temperature": 0.2 }
      }
    },
    {
      "id": "node-4",
      "name": "Code - Parse Screening",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [960, 300],
      "parameters": {
        "jsCode": "let s;\ntry { s = JSON.parse($input.first().json.message.content); } catch(e) { throw new Error('AI returned invalid JSON'); }\nconst c = $('Code - Validate Application').first().json;\nreturn [{ json: { ...c, score: s.score, strengths: s.strengths||[], gaps: s.gaps||[], recommendation: s.recommendation, summary: s.summary, interview_questions: s.interview_questions||[], should_advance: s.score >= 75, screened_at: new Date().toISOString() } }];"
      }
    },
    {
      "id": "node-5",
      "name": "IF - Advance (Score 75+)",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [1200, 300],
      "parameters": {
        "conditions": {
          "conditions": [{ "id": "c1", "leftValue": "={{ $json.should_advance }}", "rightValue": true, "operator": { "type": "boolean", "operation": "true" } }],
          "combinator": "and"
        }
      }
    },
    {
      "id": "node-6",
      "name": "Gmail - Send Interview Invite",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [1440, 140],
      "credentials": { "gmailOAuth2": { "id": "YOUR_GMAIL_CREDENTIAL_ID", "name": "Gmail account" } },
      "parameters": {
        "resource": "message",
        "operation": "send",
        "sendTo": "={{ $json.candidate_email }}",
        "subject": "=🎉 Interview Invitation — {{ $json.job_title }}",
        "message": "=<h2>Congratulations, {{ $json.candidate_name }}!</h2><p>After reviewing your application for <strong>{{ $json.job_title }}</strong>, we're excited to move forward!</p><p><a href='https://calendly.com/yourcompany/interview'>📅 Schedule Your Interview</a></p><h3>What impressed us:</h3><ul>{{ $json.strengths.map(s=>'<li>'+s+'</li>').join('') }}</ul>",
        "options": { "isHtml": true }
      }
    },
    {
      "id": "node-7",
      "name": "Slack - Notify Hiring Manager",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.3,
      "position": [1440, 300],
      "credentials": { "slackApi": { "id": "YOUR_SLACK_CREDENTIAL_ID", "name": "Slack account" } },
      "parameters": {
        "resource": "message",
        "operation": "send",
        "channel": { "__rl": true, "value": "#recruiting", "mode": "name" },
        "text": "=✅ *Candidate Advanced to Interview!*\n\n*Name:* {{ $json.candidate_name }}\n*Email:* {{ $json.candidate_email }}\n*Role:* {{ $json.job_title }}\n*AI Score:* {{ $json.score }}/100\n*Summary:* {{ $json.summary }}\n\n*Interview Questions:*\n{{ $json.interview_questions.map((q,i)=>`${i+1}. ${q}`).join('\\n') }}",
        "otherOptions": {}
      }
    },
    {
      "id": "node-8",
      "name": "Gmail - Send Rejection Email",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [1440, 460],
      "credentials": { "gmailOAuth2": { "id": "YOUR_GMAIL_CREDENTIAL_ID", "name": "Gmail account" } },
      "parameters": {
        "resource": "message",
        "operation": "send",
        "sendTo": "={{ $json.candidate_email }}",
        "subject": "=Your application for {{ $json.job_title }}",
        "message": "=<p>Hi {{ $json.candidate_name }},</p><p>Thank you for applying for <strong>{{ $json.job_title }}</strong>. After careful review, we've decided to move forward with other candidates. We'll keep your profile on file for future openings.</p><p>Best wishes,<br>The Talent Team</p>",
        "options": { "isHtml": true }
      }
    },
    {
      "id": "node-9",
      "name": "Airtable - Update ATS",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2.1,
      "position": [1680, 300],
      "credentials": { "airtableTokenApi": { "id": "YOUR_AIRTABLE_CREDENTIAL_ID", "name": "Airtable account" } },
      "parameters": {
        "resource": "record",
        "operation": "create",
        "baseId": { "__rl": true, "value": "YOUR_AIRTABLE_BASE_ID", "mode": "id" },
        "tableId": { "__rl": true, "value": "Candidates", "mode": "name" },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Candidate Name": "={{ $json.candidate_name }}",
            "Email": "={{ $json.candidate_email }}",
            "Phone": "={{ $json.candidate_phone }}",
            "Role Applied": "={{ $json.job_title }}",
            "Department": "={{ $json.department }}",
            "AI Score": "={{ $json.score }}",
            "Status": "={{ $json.should_advance ? 'Interview Scheduled' : 'Rejected' }}",
            "Recommendation": "={{ $json.recommendation }}",
            "Summary": "={{ $json.summary }}",
            "Source": "={{ $json.source }}",
            "Applied At": "={{ $json.applied_at }}",
            "Screened At": "={{ $json.screened_at }}"
          }
        }
      }
    },
    {
      "id": "node-10",
      "name": "Respond with Result",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [1920, 300],
      "parameters": { "respondWith": "json", "responseBody": "={\n  \"status\": \"processed\",\n  \"application_id\": \"{{ $json.application_id }}\",\n  \"score\": {{ $json.score }},\n  \"recommendation\": \"{{ $json.recommendation }}\",\n  \"advanced\": {{ $json.should_advance }}\n}" }
    }
  ],
  "connections": {
    "Webhook - New Application": { "main": [[{ "node": "Code - Validate Application", "type": "main", "index": 0 }]] },
    "Code - Validate Application": { "main": [[{ "node": "OpenAI - Screen Resume", "type": "main", "index": 0 }]] },
    "OpenAI - Screen Resume": { "main": [[{ "node": "Code - Parse Screening", "type": "main", "index": 0 }]] },
    "Code - Parse Screening": { "main": [[{ "node": "IF - Advance (Score 75+)", "type": "main", "index": 0 }]] },
    "IF - Advance (Score 75+)": {
      "main": [
        [{ "node": "Gmail - Send Interview Invite", "type": "main", "index": 0 }, { "node": "Slack - Notify Hiring Manager", "type": "main", "index": 0 }],
        [{ "node": "Gmail - Send Rejection Email", "type": "main", "index": 0 }]
      ]
    },
    "Gmail - Send Interview Invite": { "main": [[{ "node": "Airtable - Update ATS", "type": "main", "index": 0 }]] },
    "Gmail - Send Rejection Email": { "main": [[{ "node": "Airtable - Update ATS", "type": "main", "index": 0 }]] },
    "Airtable - Update ATS": { "main": [[{ "node": "Respond with Result", "type": "main", "index": 0 }]] }
  },
  "settings": { "executionOrder": "v1" },
  "active": false,
  "tags": [{ "name": "Portfolio" }, { "name": "HR" }, { "name": "AI" }, { "name": "Recruitment" }]
}
