{
  "name": "09 - AI-Powered Job Application Tracker",
  "nodes": [
    {
      "id": "node-1",
      "name": "Gmail Trigger - Job Emails",
      "type": "n8n-nodes-base.gmailTrigger",
      "typeVersion": 1.2,
      "position": [240, 200],
      "credentials": { "gmailOAuth2": { "id": "YOUR_GMAIL_CREDENTIAL_ID", "name": "Gmail account" } },
      "parameters": {
        "filters": { "q": "subject:(application OR interview OR offer OR position OR rejected OR hired)" },
        "pollTimes": { "item": [{ "mode": "everyX", "value": 2, "unit": "hours" }] }
      }
    },
    {
      "id": "node-2",
      "name": "OpenAI - Extract Application Info",
      "type": "n8n-nodes-base.openAi",
      "typeVersion": 1.8,
      "position": [480, 200],
      "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": "user", "content": "=Extract job info from this email. Return ONLY JSON: {company_name, job_title, status (\"applied\"|\"interview_scheduled\"|\"offer_received\"|\"rejected\"|\"unknown\"), interview_date (ISO or null), next_action, is_job_related (boolean)}\n\nSubject: {{ $json.subject }}\nFrom: {{ $json.from.value[0].address }}\nBody: {{ ($json.text||'').substring(0,2000) }}" }
          ]
        },
        "options": { "temperature": 0.1 }
      }
    },
    {
      "id": "node-3",
      "name": "Code - Parse & Filter",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [720, 200],
      "parameters": {
        "jsCode": "let ai;\ntry { ai = JSON.parse($input.first().json.message.content); } catch(e) { return []; }\nif (!ai.is_job_related) return [];\nconst email = $('Gmail Trigger - Job Emails').first().json;\nreturn [{ json: { ...ai, email_subject: email.subject, from: email.from.value[0].address, received_date: email.date, logged_at: new Date().toISOString() } }];"
      }
    },
    {
      "id": "node-4",
      "name": "Airtable - Save Application",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2.1,
      "position": [960, 200],
      "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": "Job_Applications", "mode": "name" },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Company": "={{ $json.company_name }}",
            "Role": "={{ $json.job_title }}",
            "Status": "={{ $json.status }}",
            "Interview Date": "={{ $json.interview_date }}",
            "Next Action": "={{ $json.next_action }}",
            "Email Subject": "={{ $json.email_subject }}",
            "From": "={{ $json.from }}",
            "Received Date": "={{ $json.received_date }}",
            "Logged At": "={{ $json.logged_at }}"
          }
        }
      }
    },
    {
      "id": "node-5",
      "name": "IF - Interview Scheduled",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [1200, 200],
      "parameters": {
        "conditions": {
          "conditions": [{ "id": "c1", "leftValue": "={{ $json.status }}", "rightValue": "interview_scheduled", "operator": { "type": "string", "operation": "equals" } }],
          "combinator": "and"
        }
      }
    },
    {
      "id": "node-6",
      "name": "Google Calendar - Create Interview Event",
      "type": "n8n-nodes-base.googleCalendar",
      "typeVersion": 1.3,
      "position": [1440, 100],
      "credentials": { "googleCalendarOAuth2Api": { "id": "YOUR_GOOGLE_CALENDAR_CREDENTIAL_ID", "name": "Google Calendar account" } },
      "parameters": {
        "resource": "event",
        "operation": "create",
        "calendarId": { "__rl": true, "value": "primary", "mode": "list", "cachedResultName": "primary" },
        "start": "={{ $json.interview_date || new Date().toISOString() }}",
        "end": "={{ new Date(new Date($json.interview_date||Date.now()).getTime()+3600000).toISOString() }}",
        "additionalFields": {
          "summary": "=Interview — {{ $json.company_name }} ({{ $json.job_title }})",
          "description": "=Job Interview\nCompany: {{ $json.company_name }}\nRole: {{ $json.job_title }}\nNext Action: {{ $json.next_action }}"
        }
      }
    },
    {
      "id": "node-7",
      "name": "Schedule - Weekly Report (Mon 9AM)",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.1,
      "position": [240, 500],
      "parameters": { "rule": { "interval": [{ "field": "cronExpression", "expression": "0 9 * * 1" }] } }
    },
    {
      "id": "node-8",
      "name": "Airtable - Fetch All Applications",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2.1,
      "position": [480, 500],
      "credentials": { "airtableTokenApi": { "id": "YOUR_AIRTABLE_CREDENTIAL_ID", "name": "Airtable account" } },
      "parameters": {
        "resource": "record",
        "operation": "search",
        "baseId": { "__rl": true, "value": "YOUR_AIRTABLE_BASE_ID", "mode": "id" },
        "tableId": { "__rl": true, "value": "Job_Applications", "mode": "name" },
        "returnAll": true,
        "options": { "sort": [{ "field": "Logged At", "direction": "desc" }] }
      }
    },
    {
      "id": "node-9",
      "name": "Code - Build Report",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [720, 500],
      "parameters": {
        "jsCode": "const records = $input.all().map(i => i.json);\nconst countBy = (arr, key) => arr.reduce((a, r) => { a[r[key]]=(a[r[key]]||0)+1; return a; }, {});\nconst counts = countBy(records, 'Status');\nconst report = `WEEKLY JOB SEARCH SUMMARY\\n${'='.repeat(35)}\\nWeek of: ${new Date().toLocaleDateString()}\\n\\nTotal Applications: ${records.length}\\n\\nBy Status:\\n${Object.entries(counts).map(([s,c])=>`  ${s}: ${c}`).join('\\n')}\\n\\nMost Recent (5):\\n${records.slice(0,5).map(r=>`  • ${r.Company} | ${r.Role} | ${r.Status}`).join('\\n')}\\n\\n💪 Keep applying!`;\nreturn [{ json: { report, total: records.length } }];"
      }
    },
    {
      "id": "node-10",
      "name": "Gmail - Send Weekly Summary",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [960, 500],
      "credentials": { "gmailOAuth2": { "id": "YOUR_GMAIL_CREDENTIAL_ID", "name": "Gmail account" } },
      "parameters": {
        "resource": "message",
        "operation": "send",
        "sendTo": "YOUR_PERSONAL_EMAIL@gmail.com",
        "subject": "=📊 Weekly Job Search Summary — {{ new Date().toLocaleDateString() }}",
        "message": "={{ $json.report }}",
        "options": {}
      }
    }
  ],
  "connections": {
    "Gmail Trigger - Job Emails": { "main": [[{ "node": "OpenAI - Extract Application Info", "type": "main", "index": 0 }]] },
    "OpenAI - Extract Application Info": { "main": [[{ "node": "Code - Parse & Filter", "type": "main", "index": 0 }]] },
    "Code - Parse & Filter": { "main": [[{ "node": "Airtable - Save Application", "type": "main", "index": 0 }]] },
    "Airtable - Save Application": { "main": [[{ "node": "IF - Interview Scheduled", "type": "main", "index": 0 }]] },
    "IF - Interview Scheduled": {
      "main": [
        [{ "node": "Google Calendar - Create Interview Event", "type": "main", "index": 0 }],
        []
      ]
    },
    "Schedule - Weekly Report (Mon 9AM)": { "main": [[{ "node": "Airtable - Fetch All Applications", "type": "main", "index": 0 }]] },
    "Airtable - Fetch All Applications": { "main": [[{ "node": "Code - Build Report", "type": "main", "index": 0 }]] },
    "Code - Build Report": { "main": [[{ "node": "Gmail - Send Weekly Summary", "type": "main", "index": 0 }]] }
  },
  "settings": { "executionOrder": "v1" },
  "active": false,
  "tags": [{ "name": "Portfolio" }, { "name": "Productivity" }, { "name": "AI" }]
}
