{
  "name": "AI Resume Screening Workflow",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "resume-screening",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "node-webhook-trigger",
      "name": "Resume Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        100,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.event }}",
              "operation": "equal",
              "value2": "new_candidate"
            }
          ]
        }
      },
      "id": "node-check-event",
      "name": "Validate Event",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        320,
        300
      ]
    },
    {
      "parameters": {
        "resource": "chat",
        "model": "gpt-4o",
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are an expert HR assistant. Analyze candidate profiles and provide actionable insights for recruiters. Be concise and professional. Respond with valid JSON only."
            },
            {
              "role": "user",
              "content": "=Generate a recruiter briefing for this candidate:\n\nName: {{ $json.candidate.name }}\nScore: {{ $json.candidate.score }}/100\nRecommendation: {{ $json.candidate.recommendation }}\nPosition: {{ $json.job?.title || 'Open Position' }}\n\nProvide a JSON response with:\n{\n  \"subject\": \"concise email subject line\",\n  \"briefing\": \"2-3 sentences professional briefing for the recruiter\",\n  \"priority\": \"high|medium|low\",\n  \"next_action\": \"specific recommended next step\"\n}"
            }
          ]
        },
        "options": {
          "temperature": 0.3,
          "responseFormat": "json_object"
        }
      },
      "id": "node-openai-briefing",
      "name": "AI Recruiter Briefing",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.3,
      "position": [
        540,
        200
      ],
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Parse AI briefing and prepare notification data\nconst webhook = $('Resume Webhook').first().json;\nlet briefing = {};\n\ntry {\n  const aiContent = $('AI Recruiter Briefing').first().json?.message?.content || '{}';\n  briefing = JSON.parse(aiContent);\n} catch (e) {\n  briefing = {\n    subject: `New Application: ${webhook.candidate?.name}`,\n    briefing: `${webhook.candidate?.name} applied with a score of ${webhook.candidate?.score}/100.`,\n    priority: webhook.candidate?.score >= 75 ? 'high' : webhook.candidate?.score >= 50 ? 'medium' : 'low',\n    next_action: 'Review candidate profile in the dashboard'\n  };\n}\n\nconst scoreColor = webhook.candidate?.score >= 75 ? '#22c55e' :\n                   webhook.candidate?.score >= 50 ? '#f59e0b' : '#ef4444';\n\nconst recommendationLabel = {\n  'strong_yes': 'Strong Yes',\n  'yes': 'Yes',\n  'maybe': 'Maybe',\n  'no': 'No'\n}[webhook.candidate?.recommendation] || 'N/A';\n\nreturn [{\n  json: {\n    candidate_id: webhook.candidate_id,\n    candidate_name: webhook.candidate?.name,\n    candidate_email: webhook.candidate?.email,\n    score: webhook.candidate?.score,\n    recommendation: webhook.candidate?.recommendation,\n    recommendation_label: recommendationLabel,\n    job_title: webhook.job?.title || 'Open Position',\n    score_color: scoreColor,\n    briefing: briefing.briefing,\n    subject: briefing.subject,\n    priority: briefing.priority,\n    next_action: briefing.next_action,\n    dashboard_url: `${$env.APP_URL || 'http://localhost:3000'}/dashboard.html`,\n    timestamp: new Date().toISOString()\n  }\n}];"
      },
      "id": "node-prepare-data",
      "name": "Prepare Notification",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        760,
        200
      ]
    },
    {
      "parameters": {
        "conditions": {
          "number": [
            {
              "value1": "={{ $json.score }}",
              "operation": "largerEqual",
              "value2": 60
            }
          ]
        }
      },
      "id": "node-score-check",
      "name": "High Score?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        980,
        200
      ]
    },
    {
      "parameters": {
        "fromEmail": "={{ $env.EMAIL_FROM || 'ai-screening@company.com' }}",
        "toEmail": "={{ $env.RECRUITER_EMAIL || 'recruiter@company.com' }}",
        "subject": "=[{{ $json.priority === 'high' ? 'HIGH' : $json.priority === 'medium' ? 'MEDIUM' : 'LOW' }}] {{ $json.subject }}",
        "emailType": "html",
        "html": "=<!DOCTYPE html>\n<html>\n<head>\n<meta charset='utf-8'>\n<style>\nbody { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; margin: 0; background: #f8fafc; }\n.container { max-width: 580px; margin: 30px auto; background: white; border-radius: 16px; overflow: hidden; box-shadow: 0 4px 20px rgba(0,0,0,0.08); }\n.header { background: linear-gradient(135deg, #1e293b 0%, #334155 100%); padding: 28px 32px; }\n.header h1 { color: white; margin: 0; font-size: 20px; font-weight: 700; }\n.header p { color: #94a3b8; margin: 4px 0 0; font-size: 13px; }\n.body { padding: 28px 32px; }\n.score-big { font-size: 56px; font-weight: 900; color: {{ $json.score_color }}; line-height: 1; }\n.score-label { color: #94a3b8; font-size: 12px; margin-top: 4px; text-transform: uppercase; letter-spacing: 1px; }\n.info-row { display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid #f1f5f9; }\n.info-label { color: #94a3b8; font-size: 13px; }\n.info-value { color: #1e293b; font-size: 13px; font-weight: 600; }\n.briefing { background: #f8fafc; border-left: 4px solid #6366f1; padding: 14px 16px; border-radius: 0 8px 8px 0; color: #475569; font-size: 14px; line-height: 1.6; margin: 16px 0; }\n.action-box { background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 10px; padding: 14px; margin: 16px 0; }\n.action-box p { color: #1d4ed8; font-size: 13px; margin: 0; font-weight: 500; }\n.btn { display: inline-block; background: linear-gradient(135deg, #6366f1, #8b5cf6); color: white; padding: 12px 28px; border-radius: 8px; text-decoration: none; font-weight: 600; font-size: 14px; margin-top: 16px; }\n.footer { background: #f8fafc; padding: 16px 32px; text-align: center; border-top: 1px solid #e2e8f0; }\n.footer p { color: #94a3b8; font-size: 11px; margin: 2px 0; }\n.badge { display: inline-block; padding: 4px 12px; border-radius: 20px; font-size: 12px; font-weight: 600; background: {{ $json.score >= 75 ? 'rgba(34,197,94,0.15)' : $json.score >= 50 ? 'rgba(245,158,11,0.15)' : 'rgba(239,68,68,0.15)' }}; color: {{ $json.score_color }}; }\n</style>\n</head>\n<body>\n<div class='container'>\n  <div class='header'>\n    <h1>New Candidate Alert</h1>\n    <p>AI Resume Screening System - n8n Workflow</p>\n  </div>\n  <div class='body'>\n    <div style='display:flex;align-items:flex-start;gap:24px;margin-bottom:24px;'>\n      <div>\n        <div class='score-big'>{{ $json.score }}</div>\n        <div class='score-label'>AI Score / 100</div>\n        <div class='badge' style='margin-top:8px;'>{{ $json.recommendation_label }}</div>\n      </div>\n      <div style='flex:1;'>\n        <h2 style='margin:0 0 4px;color:#1e293b;font-size:20px;font-weight:700;'>{{ $json.candidate_name }}</h2>\n        <p style='margin:0;color:#64748b;font-size:14px;'>{{ $json.candidate_email }}</p>\n        <p style='margin:8px 0 0;color:#64748b;font-size:13px;'>Applied for: <strong>{{ $json.job_title }}</strong></p>\n      </div>\n    </div>\n    <div class='info-row'>\n      <span class='info-label'>Priority</span>\n      <span class='info-value'>{{ $json.priority === 'high' ? 'High' : $json.priority === 'medium' ? 'Medium' : 'Low' }}</span>\n    </div>\n    <div class='info-row'>\n      <span class='info-label'>Received</span>\n      <span class='info-value'>{{ new Date($json.timestamp).toLocaleString() }}</span>\n    </div>\n    <div class='briefing'>{{ $json.briefing }}</div>\n    <div class='action-box'>\n      <p>Recommended Action: {{ $json.next_action }}</p>\n    </div>\n    <a href='{{ $json.dashboard_url }}' class='btn'>View Full Profile</a>\n  </div>\n  <div class='footer'>\n    <p>Automated by n8n - AI Resume Screening System</p>\n    <p>This alert was triggered because the candidate scored {{ $json.score }}/100</p>\n  </div>\n</div>\n</body>\n</html>"
      },
      "id": "node-send-recruiter-email",
      "name": "Alert Recruiter",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2,
      "position": [
        1200,
        100
      ],
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "url": "={{ $env.APP_URL || 'http://localhost:3000' }}/api/webhook/n8n-callback",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "candidate_id",
              "value": "={{ $json.candidate_id }}"
            },
            {
              "name": "action",
              "value": "update_status"
            },
            {
              "name": "data",
              "value": "={{ JSON.stringify({ status: 'reviewing', n8n_processed: true, processed_at: new Date().toISOString() }) }}"
            }
          ]
        },
        "options": {}
      },
      "id": "node-callback-api",
      "name": "Update Backend Status",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        1200,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Log workflow completion\nconst data = $('Prepare Notification').first().json;\nconsole.log(`Workflow completed for candidate: ${data.candidate_name} (Score: ${data.score})`);\n\nreturn [{\n  json: {\n    success: true,\n    message: 'Workflow completed successfully',\n    candidate_id: data.candidate_id,\n    score: data.score,\n    processed_at: new Date().toISOString()\n  }\n}];"
      },
      "id": "node-log-completion",
      "name": "Log Completion",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1420,
        300
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ success: true, message: 'Workflow triggered', candidate_id: $('Resume Webhook').first().json.candidate_id }) }}"
      },
      "id": "node-webhook-response",
      "name": "Webhook Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        320,
        500
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "=INSERT INTO workflow_events (candidate_id, event_type, payload, status)\nVALUES ('{{ $('Resume Webhook').first().json.candidate_id }}', 'n8n_processed', '{{ JSON.stringify($('Prepare Notification').first().json) }}', 'success')\nON CONFLICT DO NOTHING;"
      },
      "id": "node-db-log",
      "name": "Save to Database",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "position": [
        1420,
        100
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "triggerTimes": {
          "item": [
            {
              "mode": "everyHour"
            }
          ]
        }
      },
      "id": "node-cron-trigger",
      "name": "Hourly Check (IMAP)",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.1,
      "position": [
        100,
        600
      ]
    },
    {
      "parameters": {
        "mailbox": "INBOX",
        "subject": "resume OR cv OR application OR job",
        "downloadAttachments": true,
        "format": "resolved",
        "options": {
          "allowUnauthorizedCerts": false
        }
      },
      "id": "node-email-read",
      "name": "Check Email Inbox",
      "type": "n8n-nodes-base.emailReadImap",
      "typeVersion": 2,
      "position": [
        320,
        600
      ],
      "credentials": {
        "imap": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.attachments && $json.attachments.length > 0 }}",
              "value2": true
            }
          ]
        }
      },
      "id": "node-has-attachment",
      "name": "Has Attachment?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        540,
        600
      ]
    },
    {
      "parameters": {
        "url": "={{ $env.APP_URL || 'http://localhost:3000' }}/api/email-resume",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"sender\": \"{{ $json.from.value[0].address }}\",\n  \"subject\": \"{{ $json.subject }}\",\n  \"resume_text\": \"{{ $json.text || $json.textAsHtml || '' }}\",\n  \"attachments\": {{ JSON.stringify(($json.attachments || []).map(a => ({ filename: a.filename, mimeType: a.mimeType }))) }}\n}",
        "options": {}
      },
      "id": "node-process-email",
      "name": "Send to Backend",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        760,
        550
      ]
    }
  ],
  "connections": {
    "Resume Webhook": {
      "main": [
        [
          {
            "node": "Validate Event",
            "type": "main",
            "index": 0
          },
          {
            "node": "Webhook Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Event": {
      "main": [
        [
          {
            "node": "AI Recruiter Briefing",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "AI Recruiter Briefing": {
      "main": [
        [
          {
            "node": "Prepare Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Notification": {
      "main": [
        [
          {
            "node": "High Score?",
            "type": "main",
            "index": 0
          },
          {
            "node": "Update Backend Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "High Score?": {
      "main": [
        [
          {
            "node": "Alert Recruiter",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Alert Recruiter": {
      "main": [
        [
          {
            "node": "Save to Database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Backend Status": {
      "main": [
        [
          {
            "node": "Log Completion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Hourly Check (IMAP)": {
      "main": [
        [
          {
            "node": "Check Email Inbox",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Email Inbox": {
      "main": [
        [
          {
            "node": "Has Attachment?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Attachment?": {
      "main": [
        [
          {
            "node": "Send to Backend",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1",
    "saveManualExecutions": true,
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": ""
  },
  "staticData": null,
  "tags": [
    {
      "name": "HR Automation"
    },
    {
      "name": "AI"
    },
    {
      "name": "Resume Screening"
    }
  ],
  "meta": {
    "description": "Complete AI-powered resume screening workflow. Processes form submissions and email resumes, triggers AI analysis, sends recruiter alerts, and updates the hiring database."
  }
}