Visual Workflow

    JSON Code

    {
      "id": "uUb4ePCAGLLeSnF3",
      "meta": {
        "instanceId": "558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a",
        "templateCredsSetupCompleted": true
      },
      "name": "Job-Hunting_AI",
      "tags": [],
      "nodes": [
        {
          "id": "6629f501-fff9-4dfb-b857-b46840512e42",
          "name": "Google Gemini Chat Model",
          "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
          "position": [
            -2704,
            992
          ],
          "parameters": {
            "options": {}
          },
          "credentials": {
            "googlePalmApi": {
              "id": "StSEXAhsG73mLD4l",
              "name": "Google Gemini(PaLM) Api account"
            }
          },
          "typeVersion": 1
        },
        {
          "id": "28e9b0bf-4803-4d04-b773-e106a6cfe64d",
          "name": "Append or update row in sheet",
          "type": "n8n-nodes-base.googleSheets",
          "position": [
            -1024,
            944
          ],
          "parameters": {
            "columns": {
              "value": {
                "Link": "={{ $('Clean and Format Data').item.json.applyLink }}",
                "score": "={{ $json.score }}",
                "Title ": "={{ $('Clean and Format Data').item.json.title }}",
                "Company": "={{ $('Clean and Format Data').item.json.company }}",
                "Location": "={{ $('Clean and Format Data').item.json.location }}",
                "description": "={{ $('Clean and Format Data').item.json.description }}",
                "Cover Letter ": "={{ $json.coverLetter }}"
              },
              "schema": [
                {
                  "id": "Title ",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Title ",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Company",
                  "type": "string",
                  "display": true,
                  "required": false,
                  "displayName": "Company",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Location",
                  "type": "string",
                  "display": true,
                  "required": false,
                  "displayName": "Location",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Link",
                  "type": "string",
                  "display": true,
                  "required": false,
                  "displayName": "Link",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "score",
                  "type": "string",
                  "display": true,
                  "required": false,
                  "displayName": "score",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "description",
                  "type": "string",
                  "display": true,
                  "required": false,
                  "displayName": "description",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Cover Letter ",
                  "type": "string",
                  "display": true,
                  "required": false,
                  "displayName": "Cover Letter ",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                }
              ],
              "mappingMode": "defineBelow",
              "matchingColumns": [
                "Title "
              ],
              "attemptToConvertTypes": false,
              "convertFieldsToString": false
            },
            "options": {},
            "operation": "appendOrUpdate",
            "sheetName": {
              "__rl": true,
              "mode": "list",
              "value": "gid=0",
              "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1D4_I_0YpYauo-FWzwbtXjtwIyzMFc5xpSOj0eYgNsLI/edit#gid=0",
              "cachedResultName": "Sheet1"
            },
            "documentId": {
              "__rl": true,
              "mode": "list",
              "value": "1D4_I_0YpYauo-FWzwbtXjtwIyzMFc5xpSOj0eYgNsLI",
              "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1D4_I_0YpYauo-FWzwbtXjtwIyzMFc5xpSOj0eYgNsLI/edit?usp=drivesdk",
              "cachedResultName": "result"
            }
          },
          "credentials": {
            "googleSheetsOAuth2Api": {
              "id": "W8gYNjmyfQeT0Rr8",
              "name": "Google Sheets credentials"
            }
          },
          "typeVersion": 4.7
        },
        {
          "id": "b8e4ee6a-6397-41fb-a0fe-1c54b011febe",
          "name": "Extract from linkendin1",
          "type": "n8n-nodes-base.code",
          "position": [
            432,
            -32
          ],
          "parameters": {
            "jsCode": "let url = \"https://www.linkedin.com/jobs/search/?currentJobId=4339332845\";\n\nconst keyword =$input.first().json.message.text;\nconst location = $input.first().json.Location;\nconst experienceLevel = $input.first().json[\"Experience Level\"];\nconst remote = $input.first().json.Remote;\nconst jobType = $input.first().json[\"Job Type\"];\nconst easyApply = $input.first().json[\"Easy Apply\"]; // fixed\n\nif (keyword !== \"\") {\n  url += `&keywords=${keyword}`;\n}\n\nif (location !== \"\") {\n  url += `&location=${location}`;\n}\n\nif (experienceLevel !== \"\") {\n  const transformerExperience = experienceLevel\n    .split(\",\")\n    .map((exp) => {\n      switch (exp.trim()) {\n        case \"Internship\": return \"1\";\n        case \"Entry Level\": return \"2\";\n        case \"Associate\": return \"3\";\n        case \"Junior Level\": return \"4\";\n        case \"Mid-Senior Level\": return \"5\";\n        case \"Executive\": return \"6\";\n        default: return \"\";\n      }\n    })\n    .filter(Boolean);\n\n  url += `&f_E=${transformerExperience.join(\",\")}`;\n}\n\nif (remote !== \"\") {\n  const transformedRemote = remote\n    .split(\",\")\n    .map((e) => {\n      switch (e.trim()) {\n        case \"Remote\": return \"2\";\n        case \"Hybrid\": return \"3\";\n        case \"On-Site\": return \"1\";\n        default: return \"\";\n      }\n    })\n    .filter(Boolean);\n\n  url += `&f_WT=${transformedRemote.join(\",\")}`;\n}\n\nif (jobType == \"\") {\n  const transformedJobType = jobType\n    .split(\",\")\n    .map((type) => type.trim().charAt(0).toUpperCase())\n    .join(\"\");\n\n  url += `&f_JT=${transformedJobType}`;\n}\nif (easyApply !==\"\"){\n  url += \"&f_EA=true\"\n}\n\nreturn { url };\n"
          },
          "typeVersion": 2
        },
        {
          "id": "6e666d8b-3b6d-4edb-9c1b-f5d451b9f6be",
          "name": "Google Gemini Chat Model1",
          "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
          "position": [
            -2912,
            288
          ],
          "parameters": {
            "options": {}
          },
          "credentials": {
            "googlePalmApi": {
              "id": "StSEXAhsG73mLD4l",
              "name": "Google Gemini(PaLM) Api account"
            }
          },
          "typeVersion": 1
        },
        {
          "id": "f177bcd4-676a-4218-b4d8-dae309ae62c5",
          "name": "Ollama Chat Model",
          "type": "@n8n/n8n-nodes-langchain.lmChatOllama",
          "position": [
            -1680,
            1008
          ],
          "parameters": {
            "model": "hf.co/MaziyarPanahi/Qwen2.5-7B-Instruct-GGUF:Q8_0",
            "options": {}
          },
          "credentials": {
            "ollamaApi": {
              "id": "l0xsqdgbiFZ3BDK3",
              "name": "Ollama account"
            }
          },
          "typeVersion": 1
        },
        {
          "id": "d540b0d4-8413-4585-9103-8b439105e97c",
          "name": "Trigger: New Telegram Message",
          "type": "n8n-nodes-base.telegramTrigger",
          "position": [
            -2144,
            48
          ],
          "webhookId": "e3e30f28-9d71-498c-9752-f307a259aee5",
          "parameters": {
            "updates": [
              "message"
            ],
            "additionalFields": {}
          },
          "credentials": {
            "telegramApi": {
              "id": "SvaHxyiOrdqJLzm1",
              "name": "Linkendin_bot"
            }
          },
          "typeVersion": 1.2
        },
        {
          "id": "7a6d5b2e-65f8-4f81-9a58-ea5e46f368e9",
          "name": "Check Start Command",
          "type": "n8n-nodes-base.if",
          "position": [
            -1824,
            48
          ],
          "parameters": {
            "options": {},
            "conditions": {
              "options": {
                "version": 2,
                "leftValue": "",
                "caseSensitive": true,
                "typeValidation": "strict"
              },
              "combinator": "and",
              "conditions": [
                {
                  "id": "1dd2f344-60f2-44f8-b473-ae01224225f9",
                  "operator": {
                    "name": "filter.operator.equals",
                    "type": "string",
                    "operation": "equals"
                  },
                  "leftValue": "={{ $json.message.text }}",
                  "rightValue": "/start"
                }
              ]
            }
          },
          "typeVersion": 2.2
        },
        {
          "id": "302b8ac1-e7c6-4fa9-84e9-2bc9007a2979",
          "name": "Send Welcome Message",
          "type": "n8n-nodes-base.telegram",
          "position": [
            -1552,
            32
          ],
          "webhookId": "a9d049f2-d6d8-4a7d-9253-35539a8dc298",
          "parameters": {
            "text": "Hi! I’m Ayush, your fast job-hunting assistant. Just send me your job title — I’ll instantly find the best jobs and help you apply fast.",
            "chatId": "1217561018",
            "additionalFields": {
              "parse_mode": "Markdown"
            }
          },
          "credentials": {
            "telegramApi": {
              "id": "SvaHxyiOrdqJLzm1",
              "name": "Linkendin_bot"
            }
          },
          "typeVersion": 1.2
        },
        {
          "id": "b69ac572-f742-409a-a36f-7de403b0ae56",
          "name": "Download cv from Drive",
          "type": "n8n-nodes-base.googleDrive",
          "position": [
            -2272,
            528
          ],
          "parameters": {
            "fileId": {
              "__rl": true,
              "mode": "url",
              "value": "https://drive.google.com/file/d/1dR_wfgGmhM_u3VscZeMjarM4kIHTYU4y/view?usp=drive_link"
            },
            "options": {},
            "operation": "download"
          },
          "credentials": {
            "googleDriveOAuth2Api": {
              "id": "R3yB34HRxIsYAWSy",
              "name": "Google Drive account"
            }
          },
          "typeVersion": 3
        },
        {
          "id": "7cbce984-6a55-42ee-a870-afe5ea5a59e6",
          "name": "Extract Text from PDF",
          "type": "n8n-nodes-base.extractFromFile",
          "position": [
            -2064,
            528
          ],
          "parameters": {
            "options": {},
            "operation": "pdf"
          },
          "typeVersion": 1.1
        },
        {
          "id": "6549c976-785a-4b49-96b3-e878fe85d324",
          "name": "Load User Preferences",
          "type": "n8n-nodes-base.googleSheets",
          "position": [
            -1856,
            528
          ],
          "parameters": {
            "options": {},
            "sheetName": {
              "__rl": true,
              "mode": "list",
              "value": "gid=0",
              "cachedResultUrl": "https://docs.google.com/spreadsheets/d/19gt2LuUS1v4uffou1jARt8fTCdS3IEerugvkaGEIqt4/edit#gid=0",
              "cachedResultName": "Sheet1"
            },
            "documentId": {
              "__rl": true,
              "mode": "list",
              "value": "19gt2LuUS1v4uffou1jARt8fTCdS3IEerugvkaGEIqt4",
              "cachedResultUrl": "https://docs.google.com/spreadsheets/d/19gt2LuUS1v4uffou1jARt8fTCdS3IEerugvkaGEIqt4/edit?usp=drivesdk",
              "cachedResultName": "Job search-n8n"
            }
          },
          "credentials": {
            "googleSheetsOAuth2Api": {
              "id": "W8gYNjmyfQeT0Rr8",
              "name": "Google Sheets credentials"
            }
          },
          "typeVersion": 4.7
        },
        {
          "id": "46c7067e-e1d3-40c3-8914-bce907d0c6da",
          "name": "Merge User Message with Config",
          "type": "n8n-nodes-base.merge",
          "position": [
            -1648,
            272
          ],
          "parameters": {
            "mode": "combine",
            "options": {},
            "combineBy": "combineByPosition"
          },
          "typeVersion": 3.2
        },
        {
          "id": "8a526b40-1401-409e-ac79-c59a3248339e",
          "name": "LinkedIn: Build Search URL",
          "type": "n8n-nodes-base.code",
          "position": [
            -1456,
            272
          ],
          "parameters": {
            "jsCode": "let url = \"https://www.linkedin.com/jobs/search/?currentJobId=4339332845\";\n\nconst keyword =$input.first().json.message.text;\nconst location = $input.first().json.Location;\nconst experienceLevel = $input.first().json[\"Experience Level\"];\nconst remote = $input.first().json.Remote;\nconst jobType = $input.first().json[\"Job Type\"];\nconst easyApply = $input.first().json[\"Easy Apply\"]; // fixed\n\nif (keyword !== \"\") {\n  url += `&keywords=${keyword}`;\n}\n\nif (location !== \"\") {\n  url += `&location=${location}`;\n}\n\nif (experienceLevel !== \"\") {\n  const transformerExperience = experienceLevel\n    .split(\",\")\n    .map((exp) => {\n      switch (exp.trim()) {\n        case \"Internship\": return \"1\";\n        case \"Entry Level\": return \"2\";\n        case \"Associate\": return \"3\";\n        case \"Junior Level\": return \"4\";\n        case \"Mid-Senior Level\": return \"5\";\n        case \"Executive\": return \"6\";\n        default: return \"\";\n      }\n    })\n    .filter(Boolean);\n\n  url += `&f_E=${transformerExperience.join(\",\")}`;\n}\n\nif (remote !== \"\") {\n  const transformedRemote = remote\n    .split(\",\")\n    .map((e) => {\n      switch (e.trim()) {\n        case \"Remote\": return \"2\";\n        case \"Hybrid\": return \"3\";\n        case \"On-Site\": return \"1\";\n        default: return \"\";\n      }\n    })\n    .filter(Boolean);\n\n  url += `&f_WT=${transformedRemote.join(\",\")}`;\n}\n\nif (jobType == \"\") {\n  const transformedJobType = jobType\n    .split(\",\")\n    .map((type) => type.trim().charAt(0).toUpperCase())\n    .join(\"\");\n\n  url += `&f_JT=${transformedJobType}`;\n}\nif (easyApply !==\"\"){\n  url += \"&f_EA=true\"\n}\n\nreturn { url };\n"
          },
          "typeVersion": 2
        },
        {
          "id": "4a5dcb86-edd3-4737-9bd7-9b6faaa5ae7c",
          "name": "Extract Job URLs",
          "type": "n8n-nodes-base.html",
          "position": [
            -1104,
            272
          ],
          "parameters": {
            "options": {},
            "operation": "extractHtmlContent",
            "extractionValues": {
              "values": [
                {
                  "key": "links",
                  "attribute": "href",
                  "cssSelector": "ul.jobs-search__results-list li div a[class*=\"base-card\"]",
                  "returnArray": true,
                  "returnValue": "attribute"
                }
              ]
            }
          },
          "typeVersion": 1.2
        },
        {
          "id": "c4b25eee-1fd8-47a4-9df8-d1341be0cb96",
          "name": "Fetch Search Results HTML",
          "type": "n8n-nodes-base.httpRequest",
          "position": [
            -1280,
            272
          ],
          "parameters": {
            "url": "={{ $json.url }}",
            "options": {}
          },
          "typeVersion": 4.3
        },
        {
          "id": "d7e59b23-e86b-41c6-92d7-b4d72da25585",
          "name": "Split URLs into Individual Items",
          "type": "n8n-nodes-base.splitOut",
          "position": [
            -944,
            272
          ],
          "parameters": {
            "options": {},
            "fieldToSplitOut": "links"
          },
          "typeVersion": 1
        },
        {
          "id": "7189e624-1e0b-49e0-8702-744d55a82c95",
          "name": "Jobs: Batch Processing Loop",
          "type": "n8n-nodes-base.splitInBatches",
          "position": [
            -608,
            496
          ],
          "parameters": {
            "options": {}
          },
          "typeVersion": 3
        },
        {
          "id": "f04eb7cc-6b62-4a8a-ae98-03dd63a81d80",
          "name": "Fetch Job Details HTML",
          "type": "n8n-nodes-base.httpRequest",
          "position": [
            -2208,
            752
          ],
          "parameters": {
            "url": "={{ $json.links }}",
            "options": {}
          },
          "typeVersion": 4.3
        },
        {
          "id": "65f844a0-8176-45e8-8406-7a3ad97e4f1d",
          "name": "Parse Job Fields",
          "type": "n8n-nodes-base.html",
          "position": [
            -2000,
            752
          ],
          "parameters": {
            "options": {},
            "operation": "extractHtmlContent",
            "extractionValues": {
              "values": [
                {
                  "key": "title",
                  "cssSelector": "div h1"
                },
                {
                  "key": "company",
                  "cssSelector": "div span a"
                },
                {
                  "key": "location",
                  "cssSelector": "div span[class*='topcard__flavor topcard__flavor--bullet']"
                },
                {
                  "key": "description",
                  "cssSelector": "div.description__text.description__text--rich"
                },
                {
                  "key": "jobid",
                  "attribute": "data-semaphore-content-urn",
                  "cssSelector": "a[data-item-type=\"semaphore\"]",
                  "returnValue": "attribute"
                }
              ]
            }
          },
          "typeVersion": 1.2
        },
        {
          "id": "10d92bc9-de31-4c26-9286-d9ff99207505",
          "name": "Clean and Format Data",
          "type": "n8n-nodes-base.set",
          "position": [
            -1792,
            752
          ],
          "parameters": {
            "options": {},
            "assignments": {
              "assignments": [
                {
                  "id": "162abbd4-7d0a-4797-a33a-5ed00eb141e4",
                  "name": "description",
                  "type": "string",
                  "value": "={{ $json.description.replace(/[*_#`]+/g, '') }}\n"
                },
                {
                  "id": "4be2abdb-8efb-4d3b-b56f-beeabe60d9d2",
                  "name": "jobid",
                  "type": "string",
                  "value": "={{ $json.jobid.replace(/[^0-9]/g, '') }}\n"
                },
                {
                  "id": "9144a640-874a-46e7-bb54-4ae80baea2bc",
                  "name": "applyLink",
                  "type": "string",
                  "value": "={{ \"https://www.linkedin.com/jobs/view/\" + $json.jobid.split(\":\").pop().replace(/\\s+/g, '') }}\n"
                },
                {
                  "id": "bbeadaaa-983d-4952-802b-0c77ea1b25a8",
                  "name": "title",
                  "type": "string",
                  "value": "={{ $json['title'].replace(/[_\\*\\[\\]()~`>#+\\-=|{}.!]/g, '\\\\$&') }}"
                },
                {
                  "id": "800f03e2-59ef-443b-9f5a-80a33f68b8a0",
                  "name": "location",
                  "type": "string",
                  "value": "={{ $json.location }}"
                },
                {
                  "id": "7898e088-b042-400f-831a-e47e89d59567",
                  "name": "company",
                  "type": "string",
                  "value": "={{ $json.company }}"
                }
              ]
            }
          },
          "typeVersion": 3.4
        },
        {
          "id": "98893655-a8fb-4e17-9464-4ed29f4e6362",
          "name": "Generate Match Score & Cover Letter",
          "type": "@n8n/n8n-nodes-langchain.agent",
          "position": [
            -1584,
            752
          ],
          "parameters": {
            "text": "=You are an expert career assistant.\n\nYour task is to:\n1. Carefully read the candidate's resume and the job description below.\n2. Calculate a job-matching score from 0 to 100 (integer only) based on skills, experience, and keywords.\n3. Write a strong, tailored cover letter (minimum 2 paragraphs) that highlights the strongest matches between the resume and the job.\n   - Do NOT include the candidate's name, address, date, company address, greeting ('Dear Hiring Manager'), or closing/sign-off.\n   - Start directly with the first paragraph.\n   - Use natural, professional language.\n\nOutput MUST be 100% valid JSON and nothing else — no explanations, no markdown, no extra text.\n\nReturn exactly this format (with properly escaped quotes inside the cover letter):\n\n{\"score\":<dynamic_integer_score>,\"coverLetter\":\"First paragraph here...\\n\\nSecond paragraph...\\n\\nThird paragraph...\"}\n\nSpecial rules:\n- Escape every double quote inside the cover letter with \\\"\n- Escape every backslash with \\\\ if needed\n- Use \\n\\n for paragraph breaks\n- Never use triple backticks or code blocks\n\nJob Description:\n{{ $json.description }}\n\nCandidate Resume (full text):\n{{ $('Extract Text from PDF').item.json.text }}\n",
            "options": {},
            "promptType": "define"
          },
          "typeVersion": 3
        },
        {
          "id": "4868d582-7d4d-4def-a4be-6b62c52183cf",
          "name": "Parse and Clean JSON Response",
          "type": "n8n-nodes-base.set",
          "position": [
            -1232,
            752
          ],
          "parameters": {
            "mode": "raw",
            "options": {},
            "jsonOutput": "={{\n  (() => {\n    let raw = $json.output || \"\";\n\n    // Remove markdown fences\n    raw = raw.replace(/```json/gi, \"\")\n             .replace(/```/g, \"\")\n             .trim();\n\n    // Extract JSON boundaries\n    const start = raw.indexOf(\"{\");\n    const end = raw.lastIndexOf(\"}\");\n\n    if (start === -1 || end === -1) {\n      return JSON.stringify({ error: \"No JSON found\" });\n    }\n\n    // Clean ONLY dangerous characters (no over-escaping)\n    let jsonText = raw.substring(start, end + 1)\n                      .replace(/\\r?\\n/g, \"\\\\n\")  // newline → \\n\n                      .replace(/\\t/g, \"\\\\t\");    // tab → \\t\n\n    try {\n      const parsed = JSON.parse(jsonText);\n\n      return JSON.stringify({\n        score: parsed.score ?? \"\",\n        coverLetter: parsed.coverLetter ?? \"\"\n      });\n\n    } catch (err) {\n      return JSON.stringify({\n        error: \"Still invalid JSON\",\n        jsonText\n      });\n    }\n  })()\n}}\n"
          },
          "typeVersion": 3.4
        },
        {
          "id": "8ff1cfbb-1846-441b-8d23-bbe04e25794f",
          "name": "Check Score Threshold",
          "type": "n8n-nodes-base.if",
          "position": [
            -880,
            752
          ],
          "parameters": {
            "options": {},
            "conditions": {
              "options": {
                "version": 2,
                "leftValue": "",
                "caseSensitive": true,
                "typeValidation": "strict"
              },
              "combinator": "and",
              "conditions": [
                {
                  "id": "08d8b9d9-4dd9-4ec0-ba77-486ff4777ea0",
                  "operator": {
                    "type": "number",
                    "operation": "gte"
                  },
                  "leftValue": "={{ $json.score }}",
                  "rightValue": 10
                }
              ]
            }
          },
          "typeVersion": 2.2
        },
        {
          "id": "6c8e6d4f-ec7a-4cc7-aa78-f25adfb498aa",
          "name": "Notify User of Match",
          "type": "n8n-nodes-base.telegram",
          "position": [
            -480,
            736
          ],
          "webhookId": "3e2cb097-a7f9-4db7-adb4-1bf2b6314d0c",
          "parameters": {
            "text": "=Title: {{ $json['Title '] }}\nCompany: {{ $json.Company }}\nLocation: {{ $json.Location }}\nJob Score: {{ $json.score }}\nApply: {{ $json.Link }}\nCover Letter: {{ $json['Cover Letter '] }}",
            "chatId": "1217561018",
            "additionalFields": {}
          },
          "credentials": {
            "telegramApi": {
              "id": "SvaHxyiOrdqJLzm1",
              "name": "Linkendin_bot"
            }
          },
          "typeVersion": 1.2
        }
      ],
      "active": false,
      "pinData": {},
      "settings": {
        "callerPolicy": "workflowsFromSameOwner",
        "availableInMCP": false,
        "executionOrder": "v1"
      },
      "versionId": "81744254-077b-41d7-ab93-5065c8a36a1f",
      "connections": {
        "Extract Job URLs": {
          "main": [
            [
              {
                "node": "Split URLs into Individual Items",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Parse Job Fields": {
          "main": [
            [
              {
                "node": "Clean and Format Data",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Ollama Chat Model": {
          "ai_languageModel": [
            [
              {
                "node": "Generate Match Score & Cover Letter",
                "type": "ai_languageModel",
                "index": 0
              }
            ]
          ]
        },
        "Check Start Command": {
          "main": [
            [
              {
                "node": "Send Welcome Message",
                "type": "main",
                "index": 0
              }
            ],
            [
              {
                "node": "Download cv from Drive",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Notify User of Match": {
          "main": [
            []
          ]
        },
        "Check Score Threshold": {
          "main": [
            [
              {
                "node": "Notify User of Match",
                "type": "main",
                "index": 0
              }
            ],
            [
              {
                "node": "Jobs: Batch Processing Loop",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Clean and Format Data": {
          "main": [
            [
              {
                "node": "Generate Match Score & Cover Letter",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Extract Text from PDF": {
          "main": [
            [
              {
                "node": "Load User Preferences",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Load User Preferences": {
          "main": [
            [
              {
                "node": "Merge User Message with Config",
                "type": "main",
                "index": 1
              }
            ]
          ]
        },
        "Download cv from Drive": {
          "main": [
            [
              {
                "node": "Extract Text from PDF",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Fetch Job Details HTML": {
          "main": [
            [
              {
                "node": "Parse Job Fields",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Google Gemini Chat Model": {
          "ai_languageModel": [
            []
          ]
        },
        "Fetch Search Results HTML": {
          "main": [
            [
              {
                "node": "Extract Job URLs",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "LinkedIn: Build Search URL": {
          "main": [
            [
              {
                "node": "Fetch Search Results HTML",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Jobs: Batch Processing Loop": {
          "main": [
            [],
            [
              {
                "node": "Fetch Job Details HTML",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Append or update row in sheet": {
          "main": [
            [
              {
                "node": "Check Score Threshold",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Parse and Clean JSON Response": {
          "main": [
            [
              {
                "node": "Append or update row in sheet",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Trigger: New Telegram Message": {
          "main": [
            [
              {
                "node": "Check Start Command",
                "type": "main",
                "index": 0
              },
              {
                "node": "Merge User Message with Config",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Merge User Message with Config": {
          "main": [
            [
              {
                "node": "LinkedIn: Build Search URL",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Split URLs into Individual Items": {
          "main": [
            [
              {
                "node": "Jobs: Batch Processing Loop",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Generate Match Score & Cover Letter": {
          "main": [
            [
              {
                "node": "Parse and Clean JSON Response",
                "type": "main",
                "index": 0
              }
            ]
          ]
        }
      }
    }