{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "653e875b-4099-4a89-b6b6-530143ae2109",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1760,
        -416
      ],
      "parameters": {
        "width": 576,
        "height": 848,
        "content": "## Match Resumes to Jobs Automatically with Gemini AI and Decodo Scraping\n\nSign up for Decodo [HERE](https://visit.decodo.com/discount) for Discount\n\nThis automation intelligently connects candidate profiles to job opportunities. It takes an intake form with a short summary, resume link, and optional LinkedIn profile, then enriches the data using Decodo and Gemini. The workflow analyzes skills, experience, and role relevance, ranks top matches, and emails a polished HTML report directly to your inbox\u2014saving hours of manual review and matching effort.\n\n## Who\u2019s it for?\n\nThis template is designed for recruiters, hiring managers, and talent operations teams who handle large candidate volumes and want faster, more accurate shortlisting. It\u2019s also helpful for job seekers or career coaches who wish to identify high-fit openings automatically using structured AI analysis.\n\n## How it works\n\n1. Receive an intake form containing a candidate\u2019s resume, summary, and LinkedIn URL.\n2. Parse and summarize the resume with Gemini for core skills and experience.\n3. Enrich the data using Decodo scraping to gather extra profile details.\n4. Merge insights and rank job matches from Decodo\u2019s job data.\n5. Generate an HTML shortlist and email it automatically through Gmail.\n\n## How to set up\n\n1. Connect credentials for Gmail, Google Gemini, and Decodo.\n2. Update the Webhook path and test your form connection.\n3. Customize variables such as location or role preferences.\n4. Enable **Send as HTML** in the Gmail node for clean reports.\n5. Publish as **self-hosted** if community nodes are included.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "8e87a629-1c26-47ae-8b85-eaf84f2eee3b",
      "name": "Set: Capture Form Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        2784,
        32
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "62bbfb3c-6407-4889-9673-5ef912ab0afb",
              "name": "short_summary",
              "type": "string",
              "value": "={{ $json.body.data.fields[1].value }}"
            },
            {
              "id": "069dd205-fd11-445e-8693-422963e1b9c0",
              "name": "resume_url_link",
              "type": "string",
              "value": "={{ $json.body.data.fields[2].value[0].url }}"
            },
            {
              "id": "784f8da9-1eea-446f-9f6d-2d0a1ddbdb03",
              "name": "user_email",
              "type": "string",
              "value": "={{ $json.body.data.fields[0].value }}"
            },
            {
              "id": "4a69f2d3-c3a8-485c-a2f0-bb82e0af07f8",
              "name": "user_linkedin",
              "type": "string",
              "value": "={{ $json.body.data.fields[3].value }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "3a3a6aaf-c987-48fb-9ba3-a8d832a57331",
      "name": "Switch: Has LinkedIn URL?",
      "type": "n8n-nodes-base.switch",
      "position": [
        3040,
        32
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "If LinkedIn User is Exist",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "5a366206-392c-47d6-a343-2c208468a765",
                    "operator": {
                      "type": "string",
                      "operation": "notEmpty",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.user_linkedin }}",
                    "rightValue": ""
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "If LinkedIn User is not Exist",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "3dcf4c0f-6438-4f72-a0b8-6086674ee4de",
                    "operator": {
                      "type": "string",
                      "operation": "empty",
                      "singleValue": true
                    },
                    "leftValue": "{{ $json.user_linkedin }}",
                    "rightValue": "1"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {
          "allMatchingOutputs": true
        }
      },
      "typeVersion": 3.3
    },
    {
      "id": "d012f268-5608-4caf-b033-7295c91eafbd",
      "name": "Decodo: Scrape LinkedIn Profile",
      "type": "@decodo/n8n-nodes-decodo.decodo",
      "position": [
        3376,
        -256
      ],
      "parameters": {
        "geo": "=",
        "url": "={{ $json.user_linkedin }}"
      },
      "typeVersion": 1
    },
    {
      "id": "0351aafb-34ce-4802-ba88-b54bf55fd316",
      "name": "Gemini Model: Profile Extraction",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        3664,
        -144
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "a86ef6a5-2a21-403c-adf6-222ba399c766",
      "name": "Merge: Assemble Candidate Profile",
      "type": "n8n-nodes-base.merge",
      "position": [
        3952,
        16
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "2b2c3de0-ee3b-4d3f-982e-066777c5b4d7",
      "name": "Gemini Model: Job Matching",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        4176,
        32
      ],
      "parameters": {
        "text": "=Short Summary User: {{ $('Set: Capture Form Fields').item.json.short_summary }}\n---\nUser Resume and Experience: {{ $json.content.parts[0].text }}\n---\nLinkedIn User: {{ $json.output }}",
        "options": {
          "systemMessage": "=# System Message \u2014 Smart Job Match Finder Agent\n\nYou are a Smart Job Match Finder Agent, an intelligent assistant that analyzes a user\u2019s resume, personal summary and linkedin profile to automatically find the most relevant job openings available online.\n\nYou specialize in connecting people with jobs that truly match their skills, experience, and career goals \u2014 not just keywords. You also evaluate and score how well each job aligns with the user\u2019s background.\n\nYou use Decodo Tool to scrape and extract accurate, up-to-date job postings from trusted online job boards.\n\nYour output will using format clean HTML that can passed Email format.\n\nAssume the user is semi-technical: they can provide their resume file url, short personal summary and linkedin profile, but they expect a clear, structured, and Email-Ready-output \u2014 not long explanations.\n\n---\n\n##Tools\n\nDecodo Tool:\n\nUse this tool to scrape and extract job postings directly from websites like:\n\n- LinkedIn Jobs\n- JobStreet\n\n---\n\n##Rules\n\n1. Mandatory Tool Use: Always use Decodo Tool for scraping job listings.\n2. User Input Requirements:\n    \n    The user provides:\n    \n    - Their resume files url (skills, work experience, education).\n    - A short personal summary or preferred job type (e.g. \"I want to find remote React Developer jobs in Singapore\").\n    - Their LinkedIn Profiles \n3. Job Search Process:\n    - Search and scrape job postings that match the user\u2019s skills, experience, and preferences.\n    - Compare the user profile (resume + summary) with each job description.\n    - Select and display the top 10 most relevant matches.\n4. Output Format:\n    \n    Present the output in clean HTML (Email-ready).\n    Use this structure for each result:\n    ---\n    ## Job Title: [Job Title]\n    ## Company: [Company Name]\n    ## Location: [Location]\n    ## Work Type: [Remote / Hybrid / On-site]\n    ## Salary Range: [If available]\n    ## Source: [Platform Name]\n    ## Job URL: [Link]\n    ## Match Score: [Percentage, e.g., 85%] Why It Matches: [Short explanation of relevant skills/experience]Missing Skills: [List of missing or less relevant areas]\n    ---\n5. Email-Ready-Format: Present the output in clean, minimal HTMl that can be directly passed to the Gmail node (no extra formatting required).\n6. Tone & Style:\nProfessional, structured, and encouraging \u2014 never robotic or overly formal.\nAvoid filler words like \u201cof course,\u201d \u201cI understand,\u201d or \u201clet\u2019s see.\u201d\n    \n---\n\n##Scoring Criteria\n\n- 50% \u2014 Skill and Technology Alignment\n- 25% \u2014 Experience and Role Match\n- 15% \u2014 Location / Work Type Preference\n- 10% \u2014 Keyword Similarity in Job Description\n\n---\n\n##Fallback Behavior\n\n- If no relevant jobs are found, politely inform the user and suggest adjusting keywords or expanding preferred locations.\n- If the resume text is too short, request additional experience details.\n- Never output raw HTML or irrelevant scraping data."
        },
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "edffb457-c33e-4ccc-9b90-eb3e9a80bb38",
      "name": "Decodo Tool: Scrape Job Boards",
      "type": "@decodo/n8n-nodes-decodo.decodoTool",
      "position": [
        4416,
        288
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "713db6bd-6e12-4d53-aff8-55ccb9024275",
      "name": "Gemini Model: Match & Score Jobs",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        4128,
        288
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "02d4b243-8a6c-47cd-a9f7-ad6547e2c3c2",
      "name": "Gmail: Send Resume Summary and Top Matches Job",
      "type": "n8n-nodes-base.gmail",
      "position": [
        4608,
        32
      ],
      "parameters": {
        "sendTo": "={{ $('Set: Capture Form Fields').item.json.user_email }}",
        "message": "={{ $json.output }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "Top Job Matches for you"
      },
      "typeVersion": 2.1
    },
    {
      "id": "a1a5b2f9-ca44-4336-aa6a-15c69ea09b8a",
      "name": "Webhook: Receive Intake Form (POST)",
      "type": "n8n-nodes-base.webhook",
      "position": [
        2496,
        32
      ],
      "parameters": {
        "path": "ca18f47b-399e-4689-9795-80ac1d23829b",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "e37fd4a9-666c-44ce-afb4-556b06757b9b",
      "name": "LLM: Extract LinkedIn Details",
      "type": "@n8n/n8n-nodes-langchain.informationExtractor",
      "position": [
        3600,
        -368
      ],
      "parameters": {
        "text": "={{ $json.data.results[0].content }}",
        "options": {},
        "attributes": {
          "attributes": [
            {
              "name": "Name",
              "required": true,
              "description": "Name of the LinkedIn User"
            },
            {
              "name": "Headline",
              "required": true,
              "description": "Headline of the LinkedIn User"
            },
            {
              "name": "Location",
              "required": true,
              "description": "Location of the LinkedIn User"
            },
            {
              "name": "About summary",
              "required": true,
              "description": "About summary of the LinkedIn User"
            },
            {
              "name": "Experience (detailed roles and companies)",
              "required": true,
              "description": "Experience (detailed roles and companies) of the LinkedIn User"
            },
            {
              "name": "Education",
              "required": true,
              "description": "Education of the LinkedIn User"
            },
            {
              "name": "Licenses & Certifications",
              "required": true,
              "description": "Licenses & Certifications of the LinkedIn User"
            },
            {
              "name": "Volunteer Experience",
              "required": true,
              "description": "Volunteer Experience of the LinkedIn User"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "80da4358-bae6-4996-9594-58fb1b012d91",
      "name": "Gemini: Parse Resume",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        3648,
        32
      ],
      "parameters": {
        "text": "What's in this document or picture?",
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-2.5-flash",
          "cachedResultName": "models/gemini-2.5-flash"
        },
        "options": {},
        "resource": "document",
        "documentUrls": "={{ $json.resume_url_link }}"
      },
      "typeVersion": 1
    },
    {
      "id": "6d6e9fe3-7431-42cc-84da-37caaf5ddd5c",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2384,
        -416
      ],
      "parameters": {
        "color": 4,
        "width": 2432,
        "height": 960,
        "content": "\n"
      },
      "typeVersion": 1
    },
    {
      "id": "acfe640d-a00b-45e6-9e93-25216d353360",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2416,
        -112
      ],
      "parameters": {
        "color": 5,
        "width": 256,
        "height": 336,
        "content": "Copy the Webhook URL to your Form\n\nYou can test this workflow using form below\nhttps://tally.so/r/3jOA51\n"
      },
      "typeVersion": 1
    },
    {
      "id": "2fd6baab-53ae-41bc-8201-f726cea0e42c",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4336,
        272
      ],
      "parameters": {
        "color": 3,
        "height": 256,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\nCommunity node; works on self-hosted n8n. Make sure to add your Decodo API credentials."
      },
      "typeVersion": 1
    },
    {
      "id": "f17e52ef-68f6-405b-a82e-4fea377c4d71",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3312,
        -272
      ],
      "parameters": {
        "color": 3,
        "height": 256,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\nCommunity node; works on self-hosted n8n. Make sure to add your Decodo API credentials."
      },
      "typeVersion": 1
    },
    {
      "id": "cffdaf30-4a4b-4756-b790-615a0f6105fd",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2704,
        -48
      ],
      "parameters": {
        "color": 5,
        "width": 256,
        "height": 272,
        "content": "Make sure to adjust the form fields capture intake from the webhook"
      },
      "typeVersion": 1
    },
    {
      "id": "70b82818-b466-42d2-b1c8-0dfb794e3c1d",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4544,
        -96
      ],
      "parameters": {
        "color": 5,
        "height": 320,
        "content": "You can adjust the email massage by editing the prompt from the agent, or make your email massage by yourself, but make sure to use HTML format."
      },
      "typeVersion": 1
    },
    {
      "id": "c1586711-8836-4aa5-a31f-dd79fb4755ef",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2400,
        -400
      ],
      "parameters": {
        "color": 3,
        "width": 480,
        "height": 96,
        "content": "> **Disclaimer:** This workflow relies on a **community Decodo node** and therefore requires **self-hosted n8n**. Install the node from the community marketplace and configure the Decodo API credential."
      },
      "typeVersion": 1
    },
    {
      "id": "d0932003-f219-40e3-96fc-24c9e52ed234",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3088,
        -1104
      ],
      "parameters": {
        "width": 1120,
        "height": 656,
        "content": "@[youtube](ozqeRAoO22o)\n"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Gemini: Parse Resume": {
      "main": [
        [
          {
            "node": "Merge: Assemble Candidate Profile",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Set: Capture Form Fields": {
      "main": [
        [
          {
            "node": "Switch: Has LinkedIn URL?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch: Has LinkedIn URL?": {
      "main": [
        [
          {
            "node": "Decodo: Scrape LinkedIn Profile",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Gemini: Parse Resume",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini Model: Job Matching": {
      "main": [
        [
          {
            "node": "Gmail: Send Resume Summary and Top Matches Job",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "LLM: Extract LinkedIn Details": {
      "main": [
        [
          {
            "node": "Merge: Assemble Candidate Profile",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Decodo Tool: Scrape Job Boards": {
      "ai_tool": [
        [
          {
            "node": "Gemini Model: Job Matching",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Decodo: Scrape LinkedIn Profile": {
      "main": [
        [
          {
            "node": "LLM: Extract LinkedIn Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini Model: Match & Score Jobs": {
      "ai_languageModel": [
        [
          {
            "node": "Gemini Model: Job Matching",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Gemini Model: Profile Extraction": {
      "ai_languageModel": [
        [
          {
            "node": "LLM: Extract LinkedIn Details",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Merge: Assemble Candidate Profile": {
      "main": [
        [
          {
            "node": "Gemini Model: Job Matching",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook: Receive Intake Form (POST)": {
      "main": [
        [
          {
            "node": "Set: Capture Form Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}