<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[How I Automated My Job Search Using n8n]]></title><description><![CDATA[How I Automated My Job Search Using n8n]]></description><link>https://aijobapplications.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 20 Sep 2026 23:18:30 GMT</lastBuildDate><atom:link href="https://aijobapplications.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How I Built a Fully-Automated Job Application Bot Using n8n + AI 🚀]]></title><description><![CDATA[Overview — what the workflow does
This n8n automation finds recent LinkedIn job posts (via SerpAPI/Google search), scrapes each post for job + recruiter contact info, stores results in Google Sheets, extracts the candidate’s resume from Google Drive,...]]></description><link>https://aijobapplications.hashnode.dev/how-i-built-a-fully-automated-job-application-bot-using-n8n-ai</link><guid isPermaLink="true">https://aijobapplications.hashnode.dev/how-i-built-a-fully-automated-job-application-bot-using-n8n-ai</guid><category><![CDATA[jobs]]></category><category><![CDATA[#JobApplications]]></category><category><![CDATA[LinkedIn]]></category><category><![CDATA[naukri 360]]></category><category><![CDATA[n8n]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Rahul Mane]]></dc:creator><pubDate>Sat, 25 Oct 2025 15:38:39 GMT</pubDate><content:encoded><![CDATA[<h3 id="heading-overview-what-the-workflow-does">Overview — what the workflow does</h3>
<p>This n8n automation finds recent LinkedIn job posts (via SerpAPI/Google search), scrapes each post for job + recruiter contact info, stores results in Google Sheets, extracts the candidate’s resume from Google Drive, uses an LLM (Google Gemini) to generate a personalized application email, and then sends that email through Gmail.</p>
<h3 id="heading-high-level-flow">High-level flow</h3>
<ul>
<li><p>Manual trigger starts the flow.</p>
</li>
<li><p>Query SerpAPI (Google search) for LinkedIn posts matching your hiring keywords and location.</p>
</li>
<li><p>Extract only LinkedIn post URLs.</p>
</li>
<li><p>Fetch each LinkedIn post HTML and run a parsing function to extract title, company, JD, location, email, phone.</p>
</li>
<li><p>Save or update each lead into a Google Sheet (email used as unique key).</p>
</li>
<li><p>Download &amp; extract candidate resume from Google Drive (text extraction).</p>
</li>
<li><p>Merge resume text with the scraped job info and call an AI Agent (Google Gemini) to create an HTML-formatted email JSON.</p>
</li>
<li><p>Filter flows without a valid recruiter email.</p>
</li>
<li><p>Send the generated email via Gmail.</p>
</li>
<li><p>Looping and batching are used to process many posts safely.</p>
</li>
</ul>
<h3 id="heading-n8n-workflow">N8N Workflow :</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761404534518/eed4f8a6-37de-47bd-aee9-9516dc7ff7c4.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-node-by-node-explanation">Node-by-node explanation</h3>
<ol>
<li>Manual Trigger</li>
</ol>
<ul>
<li><p><strong>Purpose:</strong> Start pipeline manually for testing or ad-hoc runs.</p>
</li>
<li><p><strong>Notes:</strong>You can replace this with automatic scheduled trigger(Currently its manual trigger).</p>
</li>
</ul>
<ol start="2">
<li><p>Fetch Google Results2 (HTTP Request → SerpAPI)</p>
<ul>
<li><p><strong>Purpose:</strong> Query SerpAPI with a Google search for <code>site:</code><a target="_blank" href="http://linkedin.com/posts"><code>linkedin.com/posts</code></a> <code>hiring Node.js typescript</code> in a target location (Pune) and time filter (<code>tbs=qdr:m</code> = last month).</p>
</li>
<li><p><strong>Why SerpAPI:</strong> Returns structured search results (organic_results) that are easier to parse than scraping Google directly.</p>
</li>
<li><p><strong>Key param:</strong> <code>api_key=&lt;APIKEY&gt;</code></p>
</li>
<li><p>SerpApi : <a target="_blank" href="http://serpapi.com/">Link</a>.</p>
</li>
</ul>
</li>
<li><p>Extract LinkedIn URLs2</p>
<ul>
<li><p><strong>Purpose:</strong> Filter <code>organic_results</code> to only items whose link includes <a target="_blank" href="http://linkedin.com/posts"><code>linkedin.com/posts</code></a>.</p>
</li>
<li><p><strong>Why:</strong> Search results include many domains — this ensures we only process real LinkedIn post links.</p>
</li>
</ul>
</li>
<li><p>Fetch LinkedIn Post HTML2 (HTTP Request)</p>
<ul>
<li><p><strong>Purpose:</strong> Request the LinkedIn post page and return raw HTML (<code>responseFormat: string</code>) for parsing.</p>
</li>
<li><p><strong>Notes:</strong> LinkedIn may return dynamic content; raw HTML must have the meta tags used in parsing (og:description, og:title). Handle potential bot blocks or missing meta tags.</p>
</li>
</ul>
</li>
<li><p>Loop Over Items (SplitInBatches)</p>
<ul>
<li><p><strong>Purpose:</strong> Prevent rate-limit issues and control concurrency. Processes items in small batches.</p>
</li>
<li><p><strong>Why:</strong> Reduces risk of being blocked by LinkedIn/SerpAPI and avoids hitting Gmail/Sheets quotas.</p>
</li>
</ul>
</li>
<li><p>Extract Recruiter Info2 (Function — large parser)</p>
<ul>
<li><p><strong>Purpose:</strong> This is the heart of the scraper. It:</p>
<ul>
<li><p>Normalizes obfuscated Unicode characters (e.g., <code>＠</code> / bold Unicode).</p>
</li>
<li><p>Extracts <code>og:description</code> and <code>og:title</code>.</p>
</li>
<li><p>Derives job title (multiple fallbacks), company name, job description, location, email, and phone.</p>
</li>
<li><p>Filters results down to items that have a valid email before returning them.</p>
</li>
</ul>
</li>
<li><p><strong>Important details in the function:</strong></p>
<ul>
<li><p>Multiple title-extraction strategies (first-line patterns + <code>og:title</code> + fallback).</p>
</li>
<li><p>Email extraction checks <code>mailto%3A</code> links and raw text with regex.</p>
</li>
<li><p>Phone cleanup enforces numeric length (Currently not in work avoid using phone numbers).</p>
</li>
<li><p>Returns only items with <code>extractedEmail</code> (prevents sending blind emails).</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p>Append or update row in sheet (Google Sheets)</p>
<ul>
<li><p><strong>Purpose:</strong> Append new leads or update existing rows by matching on <code>email</code> to avoid duplicates.</p>
</li>
<li><p><strong>Why:</strong> Acts as a persistent job-leads database and audit trail.</p>
</li>
<li><p><strong>Schema mapped columns:</strong> Title, companyName, JD, email, phoneNumber.</p>
</li>
<li><p><strong>Note:</strong> Use robust column mapping and escape/trim JDs because job descriptions can be long or include HTML.</p>
</li>
</ul>
</li>
</ol>
<ol start="8">
<li><p>Download file (Google Drive) → Extract from File (extractFromFile)</p>
<ul>
<li><ul>
<li><p><strong>Purpose:</strong> Download the candidate’s resume (PDF) from Drive and extract text (operation <code>pdf</code>).</p>
<ul>
<li><p><strong>How it integrates:</strong> The extracted resume text is merged with scraped job data later so the AI can craft a targeted mail.</p>
</li>
<li><p><strong>Important:</strong> The workflow uses a fixed <code>fileId</code> for the resume for multi-candidate flows, make this dynamic or pull from a folder.</p>
</li>
<li><p><strong>Notes:</strong> This node require OAuth setup and has sending quotas .</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>Merge / Merge1 (Merge nodes)</p>
<ul>
<li><p><strong>Purpose:</strong> Combine the resume text and the scraped job/recruiter info into one data object for the AI.</p>
</li>
<li><p><strong>Details:</strong> Merge ensures AI receives both the job context and the candidate’s resume content.</p>
</li>
</ul>
</li>
<li><p>AI Agent (Langchain agent) + Google Gemini Chat Model</p>
<ul>
<li><p><strong>Purpose:</strong> Use the LLM to create a short, professional, personalized email (JSON output with <code>mailBody</code>, <code>mailSubject</code>, <code>recruiterEmail</code>).</p>
</li>
<li><p><strong>Prompting approach:</strong> The prompt defines JSON output and HTML formatting for mailBody (use <code>&lt;br&gt;</code> for breaks). The Structured Output Parser enforces schema.</p>
</li>
<li><p><strong>Why LLM:</strong> Generates human-like, role-specific emails that reference resume highlights and job details.</p>
</li>
</ul>
</li>
<li><p>Structured Output Parser</p>
<ul>
<li><strong>Purpose:</strong> Validates and parses the LLM response to ensure it fits the expected JSON schema. This avoids malformed outputs being sent.</li>
</ul>
</li>
<li><p>Filter</p>
<ul>
<li><p><strong>Purpose:</strong> Ensures only outputs with a non-empty <code>recruiterEmail</code> proceed to sending.</p>
</li>
<li><p><strong>Why necessary:</strong> LLM or parser might produce incomplete outputs; filter prevents sending to blank/invalid addresses.</p>
</li>
</ul>
</li>
<li><p>Send a message (Gmail)</p>
<ul>
<li><p><strong>Purpose:</strong> Send the generated HTML email to the recruiter’s email address with <code>mailSubject</code> and <code>mailBody</code> from the LLM output.</p>
</li>
<li><p><strong>Notes:</strong> Gmail node require OAuth setup and has sending quotas .</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-suggested-improvements-amp-advanced-options">Suggested improvements &amp; advanced options</h3>
<ul>
<li><p><strong>Auto-schedule:</strong> Replace Manual Trigger with Cron for regular scanning (e.g., hourly or daily).</p>
</li>
<li><p><strong>Human-in-the-loop:</strong> Add a Slack/Telegram notification for approval before sending batches of emails.</p>
</li>
<li><p><strong>Retry &amp; backoff:</strong> Add retry logic and exponential backoff for failed HTTP requests.</p>
</li>
<li><p><strong>Rate-limit aware queueing:</strong> Integrate a queue (Redis or built-in n8n) if volume grows.</p>
</li>
</ul>
<h3 id="heading-final-summary-tldr">Final summary (TL;DR)</h3>
<p>This n8n workflow automates job lead discovery and outreach by:</p>
<ol>
<li><p>Searching Google (via SerpAPI) for LinkedIn hiring posts.</p>
</li>
<li><p>Scraping each post to extract job + recruiter contact info.</p>
</li>
<li><p>Storing leads in Google Sheets (deduped by email).</p>
</li>
<li><p>Downloading and extracting candidate resume from Google Drive.</p>
</li>
<li><p>Using an LLM to craft a tailored HTML email that includes resume info.</p>
</li>
<li><p>Automatically sending the email via Gmail to recruiters that have valid emails.</p>
</li>
</ol>
<p>It combines scraping, parsing, LLM generation, persistence, and email delivery and with small hardening steps (rate limits, validation, security) becomes a reliable automated outreach pipeline.</p>
<h3 id="heading-copy-this-json-into-n8n-and-speed-up-your-job-applications-instantly">Copy this JSON into n8n and speed up your job applications instantly! 🚀</h3>
<pre><code class="lang-json">{
  <span class="hljs-attr">"nodes"</span>: [
    {
      <span class="hljs-attr">"parameters"</span>: {},
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Manual Trigger"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"n8n-nodes-base.manualTrigger"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">1</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-2848</span>,
        <span class="hljs-number">800</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"f3fc205e-7b4c-42ef-b789-5ac95f2f3a37"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {
        <span class="hljs-attr">"url"</span>: <span class="hljs-string">"=https://serpapi.com/search.json?q=site:linkedin.com/posts+hiring+Node.js+typescript&amp;location=Pune,+India&amp;tbs=qdr:m&amp;filter=0&amp;api_key=&lt;APIKEY&gt;"</span>,
        <span class="hljs-attr">"options"</span>: {}
      },
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Fetch Google Results2"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"n8n-nodes-base.httpRequest"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">1</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-2592</span>,
        <span class="hljs-number">800</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"71298061-b7b0-45ff-9e52-577126f24e58"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {
        <span class="hljs-attr">"functionCode"</span>: <span class="hljs-string">"const results = $json.organic_results || []; return results.filter(r =&gt; r.link.includes('linkedin.com/posts')).map(r =&gt; ({ json: { link: r.link } }));"</span>
      },
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Extract LinkedIn URLs2"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"n8n-nodes-base.function"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">1</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-2352</span>,
        <span class="hljs-number">800</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"6537628c-9abc-4bdf-b0aa-a61f277fde59"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {
        <span class="hljs-attr">"url"</span>: <span class="hljs-string">"={{$json.link}}"</span>,
        <span class="hljs-attr">"responseFormat"</span>: <span class="hljs-string">"string"</span>,
        <span class="hljs-attr">"options"</span>: {}
      },
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Fetch LinkedIn Post HTML2"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"n8n-nodes-base.httpRequest"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">1</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-2096</span>,
        <span class="hljs-number">800</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"72b62222-01d2-4534-bc6d-5533c68087e7"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {
        <span class="hljs-attr">"functionCode"</span>: <span class="hljs-string">"const results = [];\n\n// Function to normalize obfuscated Unicode characters (e.g., bold letters in emails) to ASCII\nconst unicodeToAsciiMap = {\n    '𝐚': 'a', '𝐛': 'b', '𝐜': 'c', '𝐝': 'd', '𝐞': 'e', '𝐟': 'f', '𝐠': 'g', '𝐡': 'h', '𝐢': 'i', '𝐣': 'j', '𝐤': 'k', '𝐥': 'l', '𝐦': 'm', \n    '𝐧': 'n', '𝐨': 'o', '𝐩': 'p', '𝐪': 'q', '𝐫': 'r', '𝐬': 's', '𝐭': 't', '𝐮': 'u', '𝐯': 'v', '𝐰': 'w', '𝐱': 'x', '𝐲': 'y', '𝐳': 'z',\n    '＠': '@', '．': '.'\n};\n\nfunction normalizeUnicode(text) {\n    if (!text) return text;\n    let result = text;\n    for (const [unicode, ascii] of Object.entries(unicodeToAsciiMap)) {\n        result = result.replace(new RegExp(unicode, 'g'), ascii);\n    }\n    return result.replace(/[\\u200B-\\u200D\\uFEFF]/g, ''); \n}\n\n// Loop over every item in the incoming array\nfor (const item of items) {\n    const htmlContent = item.json.data;\n\n    // --- 1. Pre-process HTML ---\n    let cleanedHtmlContent = htmlContent.replace(/urn:li:activity:\\d{18,}/g, '');\n    \n    // --- 2. Extract Full Description and Normalize ---\n    const descriptionMatch = cleanedHtmlContent.match(/&lt;meta property=\"og:description\" content=\"(.*?)\"/s);\n    let fullDescription = descriptionMatch &amp;&amp; descriptionMatch[1] ? descriptionMatch[1].trim() : \"\";\n    fullDescription = fullDescription.replace(/&amp;#10;/g, '\\n');\n    \n    const normalizedDescription = normalizeUnicode(fullDescription);\n    const descriptionLines = normalizedDescription.split('\\n').map(line =&gt; line.trim()).filter(line =&gt; line.length &gt; 0);\n    const firstLine = descriptionLines.length &gt; 0 ? descriptionLines[0] : '';\n    \n    let jobTitle = null;\n\n    // --- 3. Extract Job Title (IMPROVED AND SAFELY GUARDED LOGIC) ---\n    \n    // Priority 1: Search common opening patterns in the first line\n    const firstLineTitleRegex = /(?:🚀\\s*We Are Hiring\\s*\\||📢\\s*We’re hiring)\\s*(.*?)(?:\\n|$)/i;\n    const titleMatch1 = firstLine.match(firstLineTitleRegex);\n    if (titleMatch1 &amp;&amp; titleMatch1[1]) {\n        jobTitle = titleMatch1[1].trim();\n    }\n    \n    // Priority 2: Fallback to &lt;meta property=\"og:title\"&gt; and clean it up\n    if (!jobTitle) {\n        const ogTitleMatch = cleanedHtmlContent.match(/&lt;meta property=\"og:title\" content=\"(.*?)\"&gt;/);\n        \n        // Initialize metaTitle to an empty string for safety\n        let metaTitle = ogTitleMatch &amp;&amp; ogTitleMatch[1] ? ogTitleMatch[1] : '';\n        \n        if (metaTitle) {\n            // Remove hashtags, company names, and separators\n            metaTitle = metaTitle.replace(/#\\w+/g, '').replace(/\\|.*?LLC/i, '').replace(/\\|/g, '').trim();\n            // Remove leading/trailing dashes/spaces\n            metaTitle = metaTitle.replace(/^[-\\s]+|[-\\s]+$/g, '').trim();\n        }\n        \n        // Now it is safe to check the length, as metaTitle is guaranteed to be a string\n        if (metaTitle.length &gt; 5) {\n            jobTitle = metaTitle;\n        }\n    }\n    \n    // Priority 3: Fallback to the entire first line\n    if (!jobTitle &amp;&amp; firstLine.length &gt; 0 &amp;&amp; firstLine.length &lt; 150) {\n        jobTitle = firstLine;\n    }\n\n\n    // --- 4. Extract Company Name ---\n    const companyTitleMatch = cleanedHtmlContent.match(/&lt;meta property=\"og:title\" content=\".*? \\| (.*?)\"&gt;/);\n    let companyName = companyTitleMatch &amp;&amp; companyTitleMatch[1] ? companyTitleMatch[1].trim() : null;\n    \n    if (!companyName) {\n        const companyDescMatch = normalizedDescription.match(/📍 (.*?)\\n/);\n        companyName = companyDescMatch &amp;&amp; companyDescMatch[1] ? companyDescMatch[1].trim().split(',')[0] : null;\n    }\n\n    // --- 5. Extract Job Description ---\n    let jobDescription = fullDescription;\n    // Safely remove the header lines if a title was found\n    if (jobTitle &amp;&amp; descriptionLines.length &gt; 1) {\n         // Use the end of the second line as the starting point for the description\n         const secondLine = descriptionLines[1];\n         const headerEndIndex = fullDescription.indexOf(secondLine) + secondLine.length;\n         if (headerEndIndex &gt; 0) {\n            jobDescription = fullDescription.substring(headerEndIndex).trim();\n         }\n    }\n\n    // --- 6. Extract Job Location ---\n    let jobLocation = null;\n    const locationKeywordsRegex = /Location:\\s*(.*?)(?:\\n|Type:|Apply Now:)/i;\n    const locationKeywordMatch = jobDescription.match(locationKeywordsRegex);\n\n    if (locationKeywordMatch &amp;&amp; locationKeywordMatch[1]) {\n        jobLocation = locationKeywordMatch[1].trim();\n    } \n    \n    if (!jobLocation) {\n        const locationLineMatch = normalizedDescription.match(/📍 (.*?)\\n/);\n        if (locationLineMatch &amp;&amp; locationLineMatch[1] &amp;&amp; locationLineMatch[1].includes(',')) {\n            jobLocation = locationLineMatch[1].split(',').slice(1).join(',').trim();\n            if (jobLocation === '') jobLocation = null;\n        } else if (locationLineMatch &amp;&amp; locationLineMatch[1]) {\n            if (locationLineMatch[1] !== companyName) {\n                 jobLocation = locationLineMatch[1].trim();\n            }\n        }\n    }\n\n\n    // --- 7. Extract Email ---\n    let extractedEmail = null;\n\n    // Priority 1: Check the mailto link's URL-encoded value\n    const mailtoRegex = /mailto%3A(.*?)[&amp;\"']/i;\n    const mailtoMatch = cleanedHtmlContent.match(mailtoRegex);\n    if (mailtoMatch &amp;&amp; mailtoMatch[1]) {\n        extractedEmail = decodeURIComponent(mailtoMatch[1]);\n    }\n\n    // Priority 2: Run on the **normalized** full description content\n    if (!extractedEmail &amp;&amp; normalizedDescription) {\n        const plainEmailRegex = /([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6})/g;\n        const plainEmailMatches = normalizedDescription.match(plainEmailRegex);\n        \n        if (plainEmailMatches &amp;&amp; plainEmailMatches.length &gt; 0) {\n            extractedEmail = [...new Set(plainEmailMatches)][0];\n        }\n    }\n\n    // --- 8. Extract Phone Number ---\n    let extractedNumber = null;\n    const phoneRegex = /(\\+?\\d{1,4}[-.\\s()]?(\\d{2,4})[-.\\s()]?(\\d{3,4})[-.\\s()]?(\\d{4,5}))/g;\n    const potentialNumbers = cleanedHtmlContent.match(phoneRegex);\n\n    if (potentialNumbers) {\n        const uniqueNumbers = [...new Set(potentialNumbers)];\n        for (let num of uniqueNumbers) {\n            const cleanedNum = num.replace(/[^0-9]/g, '');\n            if (cleanedNum.length &gt;= 8 &amp;&amp; cleanedNum.length &lt;= 15) {\n                extractedNumber = num.trim();\n                break;\n            }\n        }\n    }\n\n    // --- 9. Filter Logic: Only push results that have an email ---\n    if (extractedEmail) {\n        results.push({\n            json: {\n                jobTitle: jobTitle,\n                companyName: companyName,\n                jobDescription: jobDescription,\n                jobLocation: jobLocation,\n                emailjs: extractedEmail,\n                phoneNumber: extractedNumber\n            }\n        });\n    }\n}\n\nreturn results;"</span>
      },
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Extract Recruiter Info2"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"n8n-nodes-base.function"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">1</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-1776</span>,
        <span class="hljs-number">544</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"41e0f9b7-85ef-428b-a14e-e67a8128356b"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {
        <span class="hljs-attr">"options"</span>: {}
      },
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"n8n-nodes-base.splitInBatches"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">3</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-1872</span>,
        <span class="hljs-number">1056</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"10512a94-50bd-4146-9720-482b18a2fe39"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Loop Over Items"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {},
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"n8n-nodes-base.noOp"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Replace Me"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">1</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-1104</span>,
        <span class="hljs-number">1008</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"e1b08df7-c3a9-4c7e-82a9-4383e5882330"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {
        <span class="hljs-attr">"operation"</span>: <span class="hljs-string">"appendOrUpdate"</span>,
        <span class="hljs-attr">"documentId"</span>: {
          <span class="hljs-attr">"__rl"</span>: <span class="hljs-literal">true</span>,
          <span class="hljs-attr">"value"</span>: <span class="hljs-string">"1cd77WEywNQYJlE_YAX8Q0mPepXQ94cYSDlak1g7W4jg"</span>,
          <span class="hljs-attr">"mode"</span>: <span class="hljs-string">"list"</span>,
          <span class="hljs-attr">"cachedResultName"</span>: <span class="hljs-string">"post scraper"</span>,
          <span class="hljs-attr">"cachedResultUrl"</span>: <span class="hljs-string">"https://docs.google.com/spreadsheets/d/1cd77WEywNQYJlE_YAX8Q0mPepXQ94cYSDlak1g7W4jg/edit?usp=drivesdk"</span>
        },
        <span class="hljs-attr">"sheetName"</span>: {
          <span class="hljs-attr">"__rl"</span>: <span class="hljs-literal">true</span>,
          <span class="hljs-attr">"value"</span>: <span class="hljs-string">"gid=0"</span>,
          <span class="hljs-attr">"mode"</span>: <span class="hljs-string">"list"</span>,
          <span class="hljs-attr">"cachedResultName"</span>: <span class="hljs-string">"Sheet1"</span>,
          <span class="hljs-attr">"cachedResultUrl"</span>: <span class="hljs-string">"https://docs.google.com/spreadsheets/d/1cd77WEywNQYJlE_YAX8Q0mPepXQ94cYSDlak1g7W4jg/edit#gid=0"</span>
        },
        <span class="hljs-attr">"columns"</span>: {
          <span class="hljs-attr">"mappingMode"</span>: <span class="hljs-string">"defineBelow"</span>,
          <span class="hljs-attr">"value"</span>: {
            <span class="hljs-attr">"Title"</span>: <span class="hljs-string">"={{ $json.jobTitle }}"</span>,
            <span class="hljs-attr">"companyName"</span>: <span class="hljs-string">"={{ $json.companyName }}"</span>,
            <span class="hljs-attr">"JD"</span>: <span class="hljs-string">"={{ $json.jobDescription }}"</span>,
            <span class="hljs-attr">"email"</span>: <span class="hljs-string">"={{ $json.emailjs }}"</span>,
            <span class="hljs-attr">"phoneNumber"</span>: <span class="hljs-string">"={{ $json.phoneNumber }}"</span>
          },
          <span class="hljs-attr">"matchingColumns"</span>: [
            <span class="hljs-string">"email"</span>
          ],
          <span class="hljs-attr">"schema"</span>: [
            {
              <span class="hljs-attr">"id"</span>: <span class="hljs-string">"Title"</span>,
              <span class="hljs-attr">"displayName"</span>: <span class="hljs-string">"Title"</span>,
              <span class="hljs-attr">"required"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-attr">"defaultMatch"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-attr">"display"</span>: <span class="hljs-literal">true</span>,
              <span class="hljs-attr">"type"</span>: <span class="hljs-string">"string"</span>,
              <span class="hljs-attr">"canBeUsedToMatch"</span>: <span class="hljs-literal">true</span>,
              <span class="hljs-attr">"removed"</span>: <span class="hljs-literal">false</span>
            },
            {
              <span class="hljs-attr">"id"</span>: <span class="hljs-string">"companyName"</span>,
              <span class="hljs-attr">"displayName"</span>: <span class="hljs-string">"companyName"</span>,
              <span class="hljs-attr">"required"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-attr">"defaultMatch"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-attr">"display"</span>: <span class="hljs-literal">true</span>,
              <span class="hljs-attr">"type"</span>: <span class="hljs-string">"string"</span>,
              <span class="hljs-attr">"canBeUsedToMatch"</span>: <span class="hljs-literal">true</span>
            },
            {
              <span class="hljs-attr">"id"</span>: <span class="hljs-string">"JD"</span>,
              <span class="hljs-attr">"displayName"</span>: <span class="hljs-string">"JD"</span>,
              <span class="hljs-attr">"required"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-attr">"defaultMatch"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-attr">"display"</span>: <span class="hljs-literal">true</span>,
              <span class="hljs-attr">"type"</span>: <span class="hljs-string">"string"</span>,
              <span class="hljs-attr">"canBeUsedToMatch"</span>: <span class="hljs-literal">true</span>
            },
            {
              <span class="hljs-attr">"id"</span>: <span class="hljs-string">"email"</span>,
              <span class="hljs-attr">"displayName"</span>: <span class="hljs-string">"email"</span>,
              <span class="hljs-attr">"required"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-attr">"defaultMatch"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-attr">"display"</span>: <span class="hljs-literal">true</span>,
              <span class="hljs-attr">"type"</span>: <span class="hljs-string">"string"</span>,
              <span class="hljs-attr">"canBeUsedToMatch"</span>: <span class="hljs-literal">true</span>,
              <span class="hljs-attr">"removed"</span>: <span class="hljs-literal">false</span>
            },
            {
              <span class="hljs-attr">"id"</span>: <span class="hljs-string">"phoneNumber"</span>,
              <span class="hljs-attr">"displayName"</span>: <span class="hljs-string">"phoneNumber"</span>,
              <span class="hljs-attr">"required"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-attr">"defaultMatch"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-attr">"display"</span>: <span class="hljs-literal">true</span>,
              <span class="hljs-attr">"type"</span>: <span class="hljs-string">"string"</span>,
              <span class="hljs-attr">"canBeUsedToMatch"</span>: <span class="hljs-literal">true</span>
            },
            {
              <span class="hljs-attr">"id"</span>: <span class="hljs-string">"emailBody"</span>,
              <span class="hljs-attr">"displayName"</span>: <span class="hljs-string">"emailBody"</span>,
              <span class="hljs-attr">"required"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-attr">"defaultMatch"</span>: <span class="hljs-literal">false</span>,
              <span class="hljs-attr">"display"</span>: <span class="hljs-literal">true</span>,
              <span class="hljs-attr">"type"</span>: <span class="hljs-string">"string"</span>,
              <span class="hljs-attr">"canBeUsedToMatch"</span>: <span class="hljs-literal">true</span>
            }
          ],
          <span class="hljs-attr">"attemptToConvertTypes"</span>: <span class="hljs-literal">false</span>,
          <span class="hljs-attr">"convertFieldsToString"</span>: <span class="hljs-literal">false</span>
        },
        <span class="hljs-attr">"options"</span>: {}
      },
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"n8n-nodes-base.googleSheets"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">4.7</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-1392</span>,
        <span class="hljs-number">624</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"7d3da9ee-efb0-46ca-8b42-e4c87415ce51"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Append or update row in sheet"</span>,
      <span class="hljs-attr">"alwaysOutputData"</span>: <span class="hljs-literal">false</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {
        <span class="hljs-attr">"sendTo"</span>: <span class="hljs-string">"={{ $json.output.recruiterEmail }}"</span>,
        <span class="hljs-attr">"subject"</span>: <span class="hljs-string">"={{ $json.output.mailSubject }}"</span>,
        <span class="hljs-attr">"message"</span>: <span class="hljs-string">"={{ $json.output.mailBody }}"</span>,
        <span class="hljs-attr">"options"</span>: {
          <span class="hljs-attr">"appendAttribution"</span>: <span class="hljs-literal">false</span>,
          <span class="hljs-attr">"attachmentsUi"</span>: {
            <span class="hljs-attr">"attachmentsBinary"</span>: [
              {}
            ]
          }
        }
      },
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"n8n-nodes-base.gmail"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">2.1</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">32</span>,
        <span class="hljs-number">128</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"fa7ead25-bb81-4043-a53f-d1408ea0f520"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Send a message"</span>,
      <span class="hljs-attr">"webhookId"</span>: <span class="hljs-string">"82f6e577-9203-47db-9463-36d847ac3a70"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {
        <span class="hljs-attr">"promptType"</span>: <span class="hljs-string">"define"</span>,
        <span class="hljs-attr">"text"</span>: <span class="hljs-string">"=You are a concise, professional email writer.  \n\nGenerate a short, well-formatted, and personalized email to the recruiter based on the provided resume and job details.  \n\nGuidelines:\n- Use the candidate’s **full name** exactly as given in the `CandidateName` field from the resume.  \n- Start with a greeting like “Hi” or “Hello” followed by the recruiter’s name if available.  \n- The email should be professional and naturally written in paragraph format.  \n- Mention the candidate’s total experience and notice period (60 days).  \n- Keep the tone polite and confident, expressing interest in the specific job title and company.  \n- End with a professional signature including name, phone number, email, and links (GitHub and LinkedIn if available).  \n- Output strictly in **JSON format** with the email text formatted in HTML (use `&lt;br&gt;` for line breaks).  \n\nInput:\nCandidateName: &lt;ENTER YOUR NAME&gt;  \nResume: {{ $json.text }}  \nJob Title:&lt;ENTER YOUR JOB ROLE&gt; (eg : Node js developer)  \nCompany Name: {{ $json.companyName }}  \nRecruiter Email: {{ $json.email }}  \n\nOutput JSON format:\n\n{\n  \"mailBody\": \"&lt;WRITE CUSTOME MAIL BODY as per your needs&gt;\",\n  \"mailSubject\": \"Application for &lt;JOB TITLE&gt;\",\n  \"recruiterEmail\": \"{{ $json.email }}\"\n}\n"</span>,
        <span class="hljs-attr">"hasOutputParser"</span>: <span class="hljs-literal">true</span>,
        <span class="hljs-attr">"options"</span>: {}
      },
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"@n8n/n8n-nodes-langchain.agent"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">2.2</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-896</span>,
        <span class="hljs-number">400</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"67964336-92b3-4f96-b9c2-4525a8122b64"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"AI Agent"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {
        <span class="hljs-attr">"options"</span>: {}
      },
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"@n8n/n8n-nodes-langchain.lmChatGoogleGemini"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">1</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-896</span>,
        <span class="hljs-number">640</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"28faeabf-e18b-4f8d-a2b4-219759aa211d"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Google Gemini Chat Model"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {
        <span class="hljs-attr">"operation"</span>: <span class="hljs-string">"pdf"</span>,
        <span class="hljs-attr">"options"</span>: {}
      },
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"n8n-nodes-base.extractFromFile"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">1</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-1904</span>,
        <span class="hljs-number">176</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"edb2f3e3-20f2-4afd-90ee-bfd8fe6dba83"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Extract from File"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {
        <span class="hljs-attr">"operation"</span>: <span class="hljs-string">"download"</span>,
        <span class="hljs-attr">"fileId"</span>: {
          <span class="hljs-attr">"__rl"</span>: <span class="hljs-literal">true</span>,
          <span class="hljs-attr">"value"</span>: <span class="hljs-string">"1Tgl9pTP807QO--DW2kDn-7cdF2eIqPHr"</span>,
          <span class="hljs-attr">"mode"</span>: <span class="hljs-string">"list"</span>,
          <span class="hljs-attr">"cachedResultName"</span>: <span class="hljs-string">"rahulMane_senior_engineer.pdf"</span>,
          <span class="hljs-attr">"cachedResultUrl"</span>: <span class="hljs-string">"https://drive.google.com/file/d/1Tgl9pTP807QO--DW2kDn-7cdF2eIqPHr/view?usp=drivesdk"</span>
        },
        <span class="hljs-attr">"options"</span>: {}
      },
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"n8n-nodes-base.googleDrive"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">3</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-2576</span>,
        <span class="hljs-number">240</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"c5cceb2c-a269-4c5f-b255-c65658605217"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Download file"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {},
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"n8n-nodes-base.merge"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">3.2</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-1152</span>,
        <span class="hljs-number">224</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"c92aef43-2ec8-4114-8678-1f324d2507b2"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Merge"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {
        <span class="hljs-attr">"jsonSchemaExample"</span>: <span class="hljs-string">"{\n  \"mailBody\": \"...\",          \n  \"mailSubject\": \"Application for Node js developer \", \n  \"recruiterEmail\": \"{{ $json.email }}\"\n}"</span>
      },
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"@n8n/n8n-nodes-langchain.outputParserStructured"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">1.3</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-720</span>,
        <span class="hljs-number">608</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"c506d304-8d1f-4b2d-aa8c-47e3fe701072"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Structured Output Parser"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {
        <span class="hljs-attr">"mode"</span>: <span class="hljs-string">"combine"</span>,
        <span class="hljs-attr">"combineBy"</span>: <span class="hljs-string">"combineAll"</span>,
        <span class="hljs-attr">"options"</span>: {}
      },
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"n8n-nodes-base.merge"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">3.2</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-368</span>,
        <span class="hljs-number">352</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"1190cb85-f143-46f2-bef2-40bef773dc3b"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Merge1"</span>
    },
    {
      <span class="hljs-attr">"parameters"</span>: {
        <span class="hljs-attr">"conditions"</span>: {
          <span class="hljs-attr">"options"</span>: {
            <span class="hljs-attr">"caseSensitive"</span>: <span class="hljs-literal">true</span>,
            <span class="hljs-attr">"leftValue"</span>: <span class="hljs-string">""</span>,
            <span class="hljs-attr">"typeValidation"</span>: <span class="hljs-string">"strict"</span>,
            <span class="hljs-attr">"version"</span>: <span class="hljs-number">2</span>
          },
          <span class="hljs-attr">"conditions"</span>: [
            {
              <span class="hljs-attr">"id"</span>: <span class="hljs-string">"261f952e-51fc-469b-a93f-ef726f089bb0"</span>,
              <span class="hljs-attr">"leftValue"</span>: <span class="hljs-string">"={{ $json.output.recruiterEmail }}"</span>,
              <span class="hljs-attr">"rightValue"</span>: <span class="hljs-string">""</span>,
              <span class="hljs-attr">"operator"</span>: {
                <span class="hljs-attr">"type"</span>: <span class="hljs-string">"string"</span>,
                <span class="hljs-attr">"operation"</span>: <span class="hljs-string">"notEmpty"</span>,
                <span class="hljs-attr">"singleValue"</span>: <span class="hljs-literal">true</span>
              }
            }
          ],
          <span class="hljs-attr">"combinator"</span>: <span class="hljs-string">"and"</span>
        },
        <span class="hljs-attr">"options"</span>: {}
      },
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"n8n-nodes-base.filter"</span>,
      <span class="hljs-attr">"typeVersion"</span>: <span class="hljs-number">2.2</span>,
      <span class="hljs-attr">"position"</span>: [
        <span class="hljs-number">-160</span>,
        <span class="hljs-number">128</span>
      ],
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"5907fbd4-ccab-49ca-a9fa-8153a398fc54"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Filter"</span>
    }
  ],
  <span class="hljs-attr">"connections"</span>: {
    <span class="hljs-attr">"Manual Trigger"</span>: {
      <span class="hljs-attr">"main"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Fetch Google Results2"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          },
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Download file"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"Fetch Google Results2"</span>: {
      <span class="hljs-attr">"main"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Extract LinkedIn URLs2"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"Extract LinkedIn URLs2"</span>: {
      <span class="hljs-attr">"main"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Fetch LinkedIn Post HTML2"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"Fetch LinkedIn Post HTML2"</span>: {
      <span class="hljs-attr">"main"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Loop Over Items"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"Extract Recruiter Info2"</span>: {
      <span class="hljs-attr">"main"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Append or update row in sheet"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"Loop Over Items"</span>: {
      <span class="hljs-attr">"main"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Extract Recruiter Info2"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ],
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Replace Me"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"Replace Me"</span>: {
      <span class="hljs-attr">"main"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Loop Over Items"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"Append or update row in sheet"</span>: {
      <span class="hljs-attr">"main"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Merge"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">1</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"AI Agent"</span>: {
      <span class="hljs-attr">"main"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Merge1"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">1</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"Google Gemini Chat Model"</span>: {
      <span class="hljs-attr">"ai_languageModel"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"AI Agent"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"ai_languageModel"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"Extract from File"</span>: {
      <span class="hljs-attr">"main"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Merge"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"Download file"</span>: {
      <span class="hljs-attr">"main"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Extract from File"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          },
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Merge1"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"Merge"</span>: {
      <span class="hljs-attr">"main"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"AI Agent"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"Structured Output Parser"</span>: {
      <span class="hljs-attr">"ai_outputParser"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"AI Agent"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"ai_outputParser"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"Merge1"</span>: {
      <span class="hljs-attr">"main"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Filter"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ]
      ]
    },
    <span class="hljs-attr">"Filter"</span>: {
      <span class="hljs-attr">"main"</span>: [
        [
          {
            <span class="hljs-attr">"node"</span>: <span class="hljs-string">"Send a message"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"main"</span>,
            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>
          }
        ]
      ]
    }
  },
  <span class="hljs-attr">"pinData"</span>: {},
  <span class="hljs-attr">"meta"</span>: {
    <span class="hljs-attr">"templateCredsSetupCompleted"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"instanceId"</span>: <span class="hljs-string">"eeea41cfca39b08d03ae9a581049579dadb68e970667301d5dabb4db7eb16e0b"</span>
  }
}
</code></pre>
<h2 id="heading-note">Note :</h2>
<p>If you’d like me to personally set this up on your system, you can schedule a call by clicking the link below.</p>
<p><a target="_blank" href="https://topmate.io/thecleancoder/">Schedule a call</a></p>
]]></content:encoded></item></channel></rss>