{
  "id": "wf8lxxjmZ15LSDB1",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Match job vacancies from Gmail against a candidate profile",
  "tags": [],
  "nodes": [
    {
      "id": "827b3b9e-c95f-4a13-bb6c-ba17d117cc6e",
      "name": "Gmail Trigger",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        -352,
        -64
      ],
      "parameters": {
        "simple": false,
        "filters": {},
        "options": {
          "downloadAttachments": true
        },
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        }
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.4
    },
    {
      "id": "650f66ae-2e82-4bc7-ab70-b60cb928ac8c",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        192,
        256
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "gpt-4.1-mini"
        },
        "options": {},
        "responsesApiEnabled": false
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "486bf411-dbba-493a-be4b-91da094b58ad",
      "name": "AI Job Analyzer",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        640,
        -272
      ],
      "parameters": {
        "text": "=Analyze this job vacancy:\n\n{{ $json.text }}\n\nCompare it with the candidate profile in Pinecone.",
        "options": {
          "systemMessage": "You are a job matching agent.\n\nAnalyze the job vacancy against the candidate profile available through the Pinecone Vector Store.\n\nUse the Pinecone tool to retrieve relevant candidate information.\n\nReturn ONLY the structured output required by the output parser.\n\nmatch_score must be a number from 0 to 100.\napply must be true or false.\nreason must be a short explanation."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "b4dff991-39bb-4e7b-b282-70253ae90827",
      "name": "Pinecone Vector Store",
      "type": "@n8n/n8n-nodes-langchain.vectorStorePinecone",
      "position": [
        672,
        -64
      ],
      "parameters": {
        "mode": "retrieve-as-tool",
        "options": {},
        "pineconeIndex": {
          "__rl": true,
          "mode": "list",
          "value": "email-categorizer",
          "cachedResultName": "email-categorizer"
        },
        "includeDocumentMetadata": false
      },
      "credentials": {
        "pineconeApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "9ef9cb9c-b894-4384-b910-8801ba60b057",
      "name": "Embeddings OpenAI",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        368,
        -528
      ],
      "parameters": {
        "options": {
          "dimensions": 512
        }
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "9cc0f5f7-2c62-4104-bf2a-384ce22220f6",
      "name": "Default Data Loader",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        544,
        -528
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "f224df35-c521-42f4-b2a2-2359e716144e",
      "name": "Embeddings OpenAI1",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        672,
        64
      ],
      "parameters": {
        "options": {
          "dimensions": 512
        }
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "6c12664e-fd5d-4d02-9013-4864e4054d0c",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        608,
        -144
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4",
          "cachedResultName": "gpt-4"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "8facf008-edfa-47e2-a97c-1d0713b0aac5",
      "name": "Approval Message",
      "type": "n8n-nodes-base.whatsApp",
      "position": [
        1472,
        -160
      ],
      "parameters": {
        "textBody": "=Should Apply To This Job",
        "operation": "send",
        "phoneNumberId": "1235207553010708",
        "additionalFields": {},
        "recipientPhoneNumber": "+1234567890"
      },
      "credentials": {
        "whatsAppApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "5c280f2a-5cca-4ea2-a1d2-1ac831e0200b",
      "name": "Check Rating",
      "type": "n8n-nodes-base.if",
      "position": [
        1280,
        -112
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "ced2ef63-118c-4991-9883-61f450939cc6",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.output[0].content[0].text }}",
              "rightValue": 7
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "9ae12e4c-9be2-4092-a828-30e5e5c44085",
      "name": "Get Rating",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1008,
        -112
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-3.5-turbo",
          "cachedResultName": "GPT-3.5-TURBO"
        },
        "options": {},
        "responses": {
          "values": [
            {
              "content": "=Give me score between 1-10 based on this  {{ $json.output }}"
            },
            {
              "role": "system",
              "content": "You are a job matching score calculator.\n\nAnalyze the candidate's fit for the job based on the provided information.\n\nGive a score from 0 to 10.\n\nIMPORTANT:\n- Return ONLY ONE NUMBER.\n- Do NOT include any explanation.\n- Do NOT include words.\n- Do NOT include \"out of 10\".\n- Do NOT use JSON.\n- Do NOT use markdown.\n- The response must contain exactly one number.\n\nExamples of valid responses:\n7\n8\n4\n10"
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "e3372754-d984-48dd-9940-02f0ed3e36f3",
      "name": "Send Information",
      "type": "n8n-nodes-base.whatsApp",
      "position": [
        736,
        224
      ],
      "parameters": {
        "textBody": "={{ $json.text }}",
        "operation": "send",
        "phoneNumberId": "1235207553010708",
        "additionalFields": {},
        "recipientPhoneNumber": "+1234567890"
      },
      "credentials": {
        "whatsAppApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "bedad166-cb1e-48bb-b359-0fb08155d5d8",
      "name": "Label Important",
      "type": "n8n-nodes-base.gmail",
      "position": [
        768,
        416
      ],
      "parameters": {
        "labelIds": [
          "IMPORTANT"
        ],
        "messageId": "={{ $('Gmail Trigger').item.json.id }}",
        "operation": "addLabels"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "6d727965-9c2c-4261-8635-c8f99fba975b",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        -832
      ],
      "parameters": {
        "color": 2,
        "width": 784,
        "height": 448,
        "content": "## Candidate profile setup\n\nUpload your CV to Google Drive and select the file in the Download CV from Drive node. The workflow extracts the CV content and stores it in Pinecone for job matching."
      },
      "typeVersion": 1
    },
    {
      "id": "03b10f23-6aca-4ab4-bfa5-bffe073d5975",
      "name": "Check for Attachments",
      "type": "n8n-nodes-base.if",
      "position": [
        -176,
        -64
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cef98739-fced-4cda-ba21-f0e2ec22f464",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ Object.keys($binary ?? {}).length > 0 }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "b6cab5e7-c040-40b2-b52e-a74e42ddabc1",
      "name": "Extract Job PDF",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        16,
        -144
      ],
      "parameters": {
        "options": {},
        "operation": "pdf",
        "binaryPropertyName": "attachment_0"
      },
      "typeVersion": 1.1
    },
    {
      "id": "bcbd4828-b1bf-4245-b760-a2158fab2c94",
      "name": "Classify Job Email",
      "type": "@n8n/n8n-nodes-langchain.textClassifier",
      "position": [
        208,
        -176
      ],
      "parameters": {
        "options": {
          "multiClass": true
        },
        "inputText": "={{ $json.text }}",
        "categories": {
          "categories": [
            {
              "category": "job vacancies ",
              "description": "An email about a full-time or part-time employment opportunity suitable for a Computer Science student, fresh graduate, or entry-level candidate. This includes junior software developer, software engineer, AI/ML engineer, data analyst, web developer, QA engineer, DevOps, IT, or other technology-related positions."
            },
            {
              "category": "Internship Opportunity",
              "description": "An email offering or discussing an internship opportunity for a Computer Science student or recent graduate. This includes software engineering internships, AI/ML internships, web development internships, data science internships, summer internships, remote internships, and other technology-related internships."
            },
            {
              "category": "Interview / Assessment",
              "description": "An email related to an interview, coding test, technical assessment, online assessment, screening call, HR interview, interview scheduling, or another recruitment evaluation. This category should be used even if the original job application was submitted earlier."
            },
            {
              "category": "Trainee / Graduate Program",
              "description": "An email about a graduate trainee, technology trainee, apprenticeship, entry-level training program, graduate development program, or fresh graduate hiring program designed for students or recent graduates with limited professional experience."
            },
            {
              "category": "Application Update",
              "description": "An email providing an update about a previously submitted job or internship application. This includes application confirmation, application received, application under review, shortlisted status, next steps, hiring process updates, or requests for additional information."
            },
            {
              "category": "Rejection",
              "description": "An email informing the candidate that their job or internship application was unsuccessful, rejected, or that they were not selected to continue in the hiring process."
            },
            {
              "category": "Recruiter / Hiring Contact",
              "description": "An email directly from a recruiter, hiring manager, HR representative, staffing agency, or company representative contacting the candidate about potential employment, recruitment, or career opportunities. Use this when the email is primarily a direct recruitment message rather than a formal job application update."
            },
            {
              "category": "Career Event",
              "description": "An email about a career fair, recruitment drive, employer hiring event, campus recruitment event, job fair, company information session, career webinar, or other event where students or fresh graduates can connect with employers."
            },
            {
              "category": "Networking Opportunity",
              "description": "An email related to professional networking, mentorship, connecting with industry professionals, career guidance, or someone offering to discuss potential career opportunities without presenting a specific job or internship position."
            },
            {
              "category": "Other",
              "description": "An email that is not related to jobs, internships, recruitment, career opportunities, interviews, applications, or professional development relevant to a Computer Science student or fresh graduate. This includes newsletters, advertisements, promotions, general notifications, social emails, and unrelated messages."
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "6ee4891a-164a-461c-a39f-037c25b5322b",
      "name": "Ignore",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1472,
        0
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "59697029-df51-4f8b-a4a7-7fcb8142e269",
      "name": "Ignore1",
      "type": "n8n-nodes-base.noOp",
      "position": [
        384,
        352
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "4ef54b8f-5c90-47e3-9aae-d3d18831b94a",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -960,
        -320
      ],
      "parameters": {
        "color": "#CCC985",
        "width": 544,
        "height": 848,
        "content": "# AI job vacancy matcher from Gmail\n\nThis workflow automatically analyzes job vacancies received through Gmail and identifies opportunities that closely match a candidate's skills and experience. It can process job descriptions from PDF attachments, classify incoming messages, and use an AI agent with a Pinecone vector store containing the candidate's CV to calculate a job-match score.\n\n### How it works\n\n1. Gmail Trigger monitors incoming job-related emails.\n2. The workflow checks whether the email contains an attachment.\n3. PDF job descriptions are converted into text.\n4. The job email is classified to identify relevant vacancies.\n5. The AI Job Analyzer compares the vacancy against the candidate profile stored in Pinecone.\n6. The workflow generates a match score from 0\u201310.\n7. Jobs meeting the configured score threshold are saved and can trigger a notification.\n\n### Setup\n\nConnect your Gmail account, configure the Pinecone vector store with your CV/profile, and configure the AI model credentials. Set the desired match-score threshold in the IF node. Configure the destination used to store matched jobs and the notification service.\n\n### Customization\n\nAdjust the score threshold, classification categories, AI matching criteria, notification channel, and job-storage destination to fit your job-search process."
      },
      "typeVersion": 1
    },
    {
      "id": "59e63308-9b20-4fcb-b0a5-7c13b9aa5116",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -384,
        -256
      ],
      "parameters": {
        "color": "#493232",
        "width": 496,
        "height": 400,
        "content": "## 1. Receive and extract job vacancies\n\nGmail receives job emails and the workflow extracts PDF attachments for analysis."
      },
      "typeVersion": 1
    },
    {
      "id": "42af184a-c745-4462-820f-3938b4ea2fc4",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        -320
      ],
      "parameters": {
        "color": 4,
        "width": 768,
        "height": 880,
        "content": "## 2. Analyze and match jobs\n\nClassify the vacancy and compare its requirements \nagainst the candidate profile using AI and Pinecone."
      },
      "typeVersion": 1
    },
    {
      "id": "91e53505-1838-473e-8a21-b89e1468cc8e",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        -272
      ],
      "parameters": {
        "color": 5,
        "width": 688,
        "height": 416,
        "content": "## 3. Score and filter opportunities\n\nGenerate a 0\u201310 match score and continue only with jobs that meet the configured threshold."
      },
      "typeVersion": 1
    },
    {
      "id": "dde11045-a983-4fb8-b1a8-344f19843631",
      "name": "Download CV from Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -32,
        -688
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "list",
          "value": "1THRpY22bWixBg2dwuAqSOAP1QgJ0625R",
          "cachedResultUrl": "https://drive.google.com/file/d/1THRpY22bWixBg2dwuAqSOAP1QgJ0625R/view?usp=drivesdk",
          "cachedResultName": "Khadija_Naeem__cv.pdf"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "883a1381-e409-4b91-b9b7-cd66492c4bf1",
      "name": "Extract Information from CV",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        176,
        -688
      ],
      "parameters": {
        "options": {},
        "operation": "pdf"
      },
      "typeVersion": 1.1
    },
    {
      "id": "9d4804a5-8c52-47d0-be0f-8ba6253591fe",
      "name": "Store In pinecone",
      "type": "@n8n/n8n-nodes-langchain.vectorStorePinecone",
      "position": [
        384,
        -688
      ],
      "parameters": {
        "mode": "insert",
        "options": {},
        "pineconeIndex": {
          "__rl": true,
          "mode": "list",
          "value": "email-categorizer",
          "cachedResultName": "email-categorizer"
        }
      },
      "credentials": {
        "pineconeApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "86507efe-3760-4f8f-8422-9fc3e0a9db99",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -672,
        -624
      ],
      "parameters": {
        "color": 3,
        "width": 256,
        "height": 240,
        "content": "\u26a0\ufe0f Candidate profile required\n\nAdd your own CV/profile documents to the Pinecone vector store before running the workflow. Do not use personal credentials or data in the template."
      },
      "typeVersion": 1
    },
    {
      "id": "f678c242-389b-4c29-8e54-85577e92a2a6",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        -608
      ],
      "parameters": {
        "color": 3,
        "height": 224,
        "content": "\u26a0\ufe0f Use your own Pinecone index\n\nCreate/select your own Pinecone index and connect your own Pinecone credentials. Do not use the template creator's index or credentials."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "7ba3c64a-76dc-4f72-ab26-b0edabd5ae09",
  "nodeGroups": [],
  "connections": {
    "Get Rating": {
      "main": [
        [
          {
            "node": "Check Rating",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Rating": {
      "main": [
        [
          {
            "node": "Approval Message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Ignore",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail Trigger": {
      "main": [
        [
          {
            "node": "Check for Attachments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Job Analyzer": {
      "main": [
        [
          {
            "node": "Get Rating",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Job PDF": {
      "main": [
        [
          {
            "node": "Classify Job Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Information": {
      "main": [
        []
      ]
    },
    "Embeddings OpenAI": {
      "ai_embedding": [
        [
          {
            "node": "Store In pinecone",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Classify Job Email",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Classify Job Email": {
      "main": [
        [
          {
            "node": "AI Job Analyzer",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "AI Job Analyzer",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Information",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "AI Job Analyzer",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Information",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Information",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Label Important",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Label Important",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Label Important",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Ignore1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI1": {
      "ai_embedding": [
        [
          {
            "node": "Pinecone Vector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "AI Job Analyzer",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Default Data Loader": {
      "ai_document": [
        [
          {
            "node": "Store In pinecone",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Check for Attachments": {
      "main": [
        [
          {
            "node": "Extract Job PDF",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Classify Job Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pinecone Vector Store": {
      "ai_tool": [
        [
          {
            "node": "AI Job Analyzer",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Download CV from Drive": {
      "main": [
        [
          {
            "node": "Extract Information from CV",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Information from CV": {
      "main": [
        [
          {
            "node": "Store In pinecone",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}