{"workflow":{"id":13463,"name":"Auto-label Gmail with Ollama AI and draft smart replies","views":134,"recentViews":1,"totalViews":134,"createdAt":"2026-02-17T11:01:15.995Z","description":"## **Who is this for**\n\n\nThis workflow is built for professionals, founders, freelancers, and anyone drowning in email who wants to automatically triage their inbox using AI — sorting emails into categories, applying Gmail labels, and generating reply drafts for important messages, all running locally with Ollama (zero paid API costs).\n\n\n## **What this workflow does**\n\n\nIt watches your Gmail inbox for new unread emails, uses a local AI model (Ollama) to classify each email into one of six categories (Urgent, Action Required, Follow-up, Newsletter, Automated, or Spam/Promotional), automatically applies the matching Gmail label, generates reply drafts for high-priority emails, and logs every processed email to Google Sheets for analytics.\n\n\n## **How it works**\n\n- Gmail Trigger watches your inbox for new unread emails at a configurable interval (default: every 30 minutes).\n- Extract Email Data parses the sender, subject, body, attachments, and metadata into clean fields — handles all Gmail node output formats.\n- AI Classifier (Ollama, running locally) analyzes the email content and returns a structured classification with category, priority, confidence score, summary, suggested action, sentiment, and a reply draft for important messages.\n- Extract Classification robustly parses the AI response (handles markdown fences, nested objects, and edge cases) and merges it with email metadata.\n- Smart Router sends each email down one of six dedicated paths based on its classification.\n- Gmail Label nodes automatically apply the correct label to each email in your inbox.\n- Reply Draft nodes create Gmail drafts for Urgent and Action Required emails — ready for you to review, edit, and send from your Drafts folder.\n- Log Entry tracks every processed email in Google Sheets with category, priority, confidence, summary, and timestamp for analytics and review.\n\n\n## **Setup steps**\n\n\n- Gmail OAuth — Connect your Google account. Grant read, modify, and compose permissions.\n- Create Gmail Labels — In Gmail, manually create these labels (the workflow applies them automatically):\n🔴 Urgent\n📋 Action Required\n💬 Follow-up\n📰 Newsletter\n🤖 Automated\n🚫 Spam-Promo\n- Get Label IDs — Use the Gmail API or n8n's Gmail node (operation: \"Get Many Labels\") to find each label's ID. Update the labelIds in each Gmail Label node with your actual IDs.\n- Ollama — Ensure Ollama is running locally (http://localhost:11434) with your preferred model pulled (e.g., ollama pull mistral). Change the model name in the Ollama Chat Model node if needed.\n- Google Sheets (optional) — Connect your Google Sheets OAuth credential and set a spreadsheet ID in the logging node. Create a sheet with columns: Date, From, Subject, Category, Priority, Confidence, Reason, Summary, Key Action, Has Reply Draft, Sentiment, Auto Archive, Gmail ID, Processed At.\n- Test — Send yourself a few test emails (urgent request, newsletter, promotional) and run the workflow manually to verify classification accuracy.\n\n\n## **Requirements**\n\n\n- Gmail account with OAuth credentials (read, modify, compose permissions)\n- Ollama running locally with a pulled model (mistral, llama3, gemma2, etc.)\n- Google Sheets account with OAuth credentials (optional, for logging)\n- n8n instance (self-hosted recommended for Ollama connectivity)\n\n\n## **How to customize**\n\n\n- Swap mistral for llama3, gemma2, deepseek, or any Ollama-compatible model.\n- Add more categories by editing the AI system prompt and adding outputs to the Switch node.\n- Change the reply draft tone (formal, casual, friendly) in the AI system prompt.\n- Add Slack or Telegram notifications for urgent emails by branching from the Label nodes.\n- Add auto-archive for newsletters and spam by adding a Gmail \"Remove Labels\" node (remove INBOX label).\n- Decrease the polling interval for near-real-time processing.\n- Add sender whitelist/blacklist logic in a Code node before the AI classifier.","workflow":{"id":"WORKFLOW_ID_PLACEHOLDER","meta":{"instanceId":"00000000000000000000000000000000000000000000000000000000000000000000"},"name":"Classify Gmail emails with AI and auto-label with smart reply drafts using Ollama","tags":[],"nodes":[{"id":"e654e5c9-b2d2-4fda-b7c9-848a63fc2d93","name":"Sticky Note - Main Overview","type":"n8n-nodes-base.stickyNote","position":[-400,-112],"parameters":{"color":4,"width":740,"height":1000,"content":"## Classify Gmail emails with AI and auto-label with smart reply drafts\n\nAutomatically classify every incoming email using a local AI model (Ollama), apply Gmail labels, and generate smart reply drafts for important messages — zero paid APIs required.\n\n### How it works\n1. **Gmail Trigger** watches your inbox for new unread emails every 30 minutes.\n2. **Extract Email Data** parses the sender, subject, body, and metadata into clean fields.\n3. **AI Classifier** (Ollama, local) analyzes the email and classifies it into one of 6 categories: 🔴 Urgent, 📋 Action Required, 💬 Follow-up, 📰 Newsletter, 🤖 Automated, or 🚫 Spam/Promotional.\n4. **Smart Router** sends each email down its dedicated path based on classification.\n5. **Gmail Labels** are automatically applied so your inbox is organized without lifting a finger.\n6. **Reply Drafts** are generated by AI for Urgent and Action Required emails — ready for you to review, edit, and send.\n7. **Summary Log** tracks every processed email in Google Sheets for analytics and review.\n\n### Setup steps\n1. **Gmail OAuth** — Connect your Google account with read, modify, and compose permissions.\n2. **Create Gmail Labels** — In Gmail, manually create these labels:\n   - `🔴 Urgent`, `📋 Action Required`, `💬 Follow-up`, `📰 Newsletter`, `🤖 Automated`, `🚫 Spam-Promo`\n3. **Get Label IDs** — Use Gmail API or n8n to find each label's ID. Update the `labelIds` in each Gmail Label node.\n4. **Ollama** — Ensure Ollama is running locally with your preferred model pulled (default: `mistral`). Change the model name in the Ollama Chat Model node if needed.\n5. **Google Sheets** (optional) — Connect your credential and set a spreadsheet ID for the logging node.\n6. **Test** — Send yourself test emails (urgent, newsletter, promotional) and run manually to verify accuracy.\n\n### Customization\n- Swap `mistral` for `llama3`, `gemma2`, or any Ollama model.\n- Add more categories by editing the AI prompt and adding Switch outputs.\n- Change the reply draft tone (formal, casual, friendly) in the AI prompt.\n- Add Slack/Telegram notifications for urgent emails.\n- Add auto-archive for newsletters and spam.\n- Decrease the polling interval for near-real-time processing.\n- Add sender whitelist/blacklist logic before the AI node."},"typeVersion":1},{"id":"9fb47ffc-8479-4013-80dd-ea78e55d6227","name":"Sticky Note - Email Intake","type":"n8n-nodes-base.stickyNote","position":[160,960],"parameters":{"color":6,"width":560,"height":260,"content":"## 📥 Email Intake\nGmail trigger watches inbox for unread emails, then extracts and cleans email data"},"typeVersion":1},{"id":"6c54a558-173b-44b8-80f8-38825cb5d8c6","name":"Sticky Note - AI Classification","type":"n8n-nodes-base.stickyNote","position":[768,960],"parameters":{"color":6,"width":520,"height":308,"content":"## 🤖 AI Classification\nOllama analyzes email content and returns category, priority, and reply draft"},"typeVersion":1},{"id":"c3a16e2d-adc1-4e00-a31a-c409814efb02","name":"Sticky Note - Route and Label","type":"n8n-nodes-base.stickyNote","position":[1328,768],"parameters":{"color":6,"width":960,"height":1004,"content":"## 🔀 Route, Label & Draft\nSwitch by category, apply Gmail labels, create reply drafts for important emails"},"typeVersion":1},{"id":"59d64a60-80df-426e-a485-43872e4bead0","name":"Sticky Note - Logging","type":"n8n-nodes-base.stickyNote","position":[2352,960],"parameters":{"color":6,"width":400,"height":296,"content":"## 📊 Logging\nEvery processed email is logged to Google Sheets for analytics"},"typeVersion":1},{"id":"31261316-e9da-490d-9bfa-3f3d30364b22","name":"Sticky Note - Warning Labels","type":"n8n-nodes-base.stickyNote","position":[1344,1840],"parameters":{"color":3,"width":360,"content":"## ⚠️ Create Gmail Labels First\nYou must manually create these labels in Gmail before activating:\n`🔴 Urgent`, `📋 Action Required`, `💬 Follow-up`, `📰 Newsletter`, `🤖 Automated`, `🚫 Spam-Promo`\nThen update the Label IDs in each labeling node."},"typeVersion":1},{"id":"b0f03be3-f1c2-4f44-8ec9-ee2fd8865420","name":"Sticky Note - Warning Ollama","type":"n8n-nodes-base.stickyNote","position":[784,1344],"parameters":{"color":3,"width":300,"height":140,"content":"## ⚠️ Check Ollama Model\nDefault model: `mistral`. Make sure it's pulled:\n`ollama pull mistral`\nOr change to `llama3`, `gemma2`, etc."},"typeVersion":1},{"id":"db9674d4-8f0e-4594-85c3-fd60cce764c6","name":"📥 Gmail Trigger","type":"n8n-nodes-base.gmailTrigger","position":[208,1088],"parameters":{"simple":false,"filters":{"readStatus":"unread"},"options":{},"pollTimes":{"item":[{"mode":"everyX","unit":"minutes","value":30}]}},"credentials":{"gmailOAuth2":{"id":"credential-id","name":"Gmail account"}},"typeVersion":1.2},{"id":"950c6313-8ef5-4f82-a8b0-2918e868bbfe","name":"🔧 Extract Email Data","type":"n8n-nodes-base.code","position":[448,1088],"parameters":{"jsCode":"// Extract and clean email data for AI processing\nconst items = $input.all();\nconst processedEmails = [];\n\nfor (const item of items) {\n  const email = item.json;\n  \n  // ============================================\n  // SAFELY EXTRACT HEADERS (handles all formats)\n  // ============================================\n  \n  function safeString(value) {\n    if (!value) return '';\n    if (typeof value === 'string') return value;\n    if (Array.isArray(value)) return value.map(v => safeString(v)).join(', ');\n    if (typeof value === 'object') {\n      // Gmail sometimes returns { name: \"John\", email: \"user@example.com\" }\n      if (value.value) return safeString(value.value);\n      if (value.text) return safeString(value.text);\n      if (value.email && value.name) return `${value.name} <${value.email}>`;\n      if (value.email) return value.email;\n      if (value.address) return value.address;\n      return JSON.stringify(value);\n    }\n    return String(value);\n  }\n  \n  function getHeader(headers, name) {\n    if (!headers || !Array.isArray(headers)) return '';\n    const found = headers.find(h => \n      h && h.name && h.name.toLowerCase() === name.toLowerCase()\n    );\n    return found ? safeString(found.value) : '';\n  }\n  \n  // Try multiple Gmail node output formats\n  let fromHeader = '';\n  let subjectHeader = '';\n  let dateHeader = '';\n  let toHeader = '';\n  let ccHeader = '';\n  let replyToHeader = '';\n  \n  // Format 1: Gmail Trigger v1 (flat fields)\n  if (email.from) {\n    fromHeader = safeString(email.from);\n    subjectHeader = safeString(email.subject || '');\n    dateHeader = safeString(email.date || email.internalDate || '');\n    toHeader = safeString(email.to || '');\n    ccHeader = safeString(email.cc || '');\n    replyToHeader = safeString(email.replyTo || '');\n  }\n  \n  // Format 2: Gmail API raw (payload.headers array)\n  if (email.payload && email.payload.headers) {\n    fromHeader = fromHeader || getHeader(email.payload.headers, 'from');\n    subjectHeader = subjectHeader || getHeader(email.payload.headers, 'subject');\n    dateHeader = dateHeader || getHeader(email.payload.headers, 'date');\n    toHeader = toHeader || getHeader(email.payload.headers, 'to');\n    ccHeader = ccHeader || getHeader(email.payload.headers, 'cc');\n    replyToHeader = replyToHeader || getHeader(email.payload.headers, 'reply-to');\n  }\n  \n  // Format 3: Some Gmail nodes use headers directly\n  if (email.headers) {\n    const h = email.headers;\n    fromHeader = fromHeader || safeString(h.from || h.From || '');\n    subjectHeader = subjectHeader || safeString(h.subject || h.Subject || '');\n    dateHeader = dateHeader || safeString(h.date || h.Date || '');\n    toHeader = toHeader || safeString(h.to || h.To || '');\n    ccHeader = ccHeader || safeString(h.cc || h.Cc || '');\n  }\n  \n  // Format 4: labelIds at top level (Gmail Trigger v2)\n  if (!fromHeader && email.labelIds) {\n    fromHeader = safeString(email.from || '');\n    subjectHeader = safeString(email.subject || '');\n  }\n  \n  // ============================================\n  // PARSE SENDER NAME AND EMAIL\n  // ============================================\n  let senderName = '';\n  let senderEmail = '';\n  let senderDomain = '';\n  \n  // Ensure fromHeader is definitely a string before regex\n  fromHeader = String(fromHeader || '');\n  subjectHeader = String(subjectHeader || '');\n  \n  try {\n    // Try \"Name <email>\" format\n    const senderMatch = fromHeader.match(/^\"?([^\"<]+)\"?\\s*<?([^>]*)>?$/);\n    if (senderMatch && senderMatch[2]) {\n      senderName = senderMatch[1].trim();\n      senderEmail = senderMatch[2].trim();\n    } else if (fromHeader.includes('@')) {\n      // Just an email address\n      senderEmail = fromHeader.trim();\n      senderName = senderEmail.split('@')[0];\n    } else {\n      senderName = fromHeader;\n      senderEmail = fromHeader;\n    }\n    \n    senderDomain = senderEmail.includes('@') ? senderEmail.split('@')[1] : '';\n  } catch (e) {\n    senderName = fromHeader;\n    senderEmail = fromHeader;\n    senderDomain = '';\n  }\n  \n  // ============================================\n  // EXTRACT BODY TEXT\n  // ============================================\n  let bodyText = '';\n  \n  // Try direct text fields first (most Gmail trigger versions)\n  if (email.text) {\n    bodyText = safeString(email.text);\n  } else if (email.textPlain) {\n    bodyText = safeString(email.textPlain);\n  } else if (email.snippet) {\n    bodyText = safeString(email.snippet);\n  } else if (email.textHtml) {\n    bodyText = safeString(email.textHtml);\n  }\n  \n  // Try payload body\n  if (!bodyText && email.payload) {\n    if (email.payload.body && email.payload.body.data) {\n      try {\n        bodyText = Buffer.from(email.payload.body.data, 'base64').toString('utf-8');\n      } catch (e) {}\n    }\n    \n    // Try multipart\n    if (!bodyText && email.payload.parts) {\n      for (const part of email.payload.parts) {\n        if (part.mimeType === 'text/plain' && part.body && part.body.data) {\n          try {\n            bodyText = Buffer.from(part.body.data, 'base64').toString('utf-8');\n            break;\n          } catch (e) {}\n        }\n      }\n      // Fallback to HTML part\n      if (!bodyText) {\n        for (const part of email.payload.parts) {\n          if (part.mimeType === 'text/html' && part.body && part.body.data) {\n            try {\n              bodyText = Buffer.from(part.body.data, 'base64').toString('utf-8');\n              break;\n            } catch (e) {}\n          }\n        }\n      }\n    }\n  }\n  \n  // Use snippet as last resort\n  if (!bodyText && email.snippet) {\n    bodyText = safeString(email.snippet);\n  }\n  \n  // Clean body text\n  bodyText = String(bodyText || '')\n    .replace(/<[^>]+>/g, ' ')       // Strip HTML\n    .replace(/\\r\\n/g, '\\n')         // Normalize newlines\n    .replace(/\\n{3,}/g, '\\n\\n')     // Max 2 newlines\n    .replace(/&nbsp;/g, ' ')\n    .replace(/&amp;/g, '&')\n    .replace(/&lt;/g, '<')\n    .replace(/&gt;/g, '>')\n    .replace(/&quot;/g, '\"')\n    .replace(/&#39;/g, \"'\")\n    .replace(/\\s+/g, ' ')           // Collapse whitespace\n    .trim()\n    .substring(0, 3000);            // Limit for AI\n  \n  // ============================================\n  // DETECT FLAGS\n  // ============================================\n  const hasAttachments = !!(\n    (email.payload && email.payload.parts && email.payload.parts.some(p => p.filename && p.filename.length > 0)) ||\n    email.attachments ||\n    (Array.isArray(email.attachments) && email.attachments.length > 0)\n  );\n  \n  const isReply = subjectHeader.toLowerCase().startsWith('re:');\n  const isForward = subjectHeader.toLowerCase().startsWith('fwd:') || subjectHeader.toLowerCase().startsWith('fw:');\n  \n  // ============================================\n  // BUILD OUTPUT\n  // ============================================\n  processedEmails.push({\n    json: {\n      // Gmail metadata\n      gmailId: email.id || email.messageId || '',\n      threadId: email.threadId || '',\n      labelIds: email.labelIds || [],\n      \n      // Parsed fields\n      from: fromHeader,\n      senderName: senderName,\n      senderEmail: senderEmail,\n      senderDomain: senderDomain,\n      to: toHeader,\n      cc: ccHeader,\n      replyTo: replyToHeader || senderEmail,\n      subject: subjectHeader,\n      date: dateHeader,\n      \n      // Content\n      bodyText: bodyText,\n      bodyPreview: bodyText.substring(0, 300),\n      \n      // Flags\n      hasAttachments: hasAttachments,\n      isReply: isReply,\n      isForward: isForward,\n      \n      // Processing\n      processedAt: new Date().toISOString()\n    }\n  });\n}\n\nif (processedEmails.length === 0) {\n  return [{ json: { error: 'No emails to process', processedAt: new Date().toISOString() } }];\n}\n\nreturn processedEmails;"},"typeVersion":2},{"id":"ce560c12-b054-404e-be51-d210d1b677d1","name":"🤖 AI Email Classifier","type":"@n8n/n8n-nodes-langchain.agent","position":[800,1088],"parameters":{"text":"=Classify this email and generate a reply draft if needed.\n\n--- EMAIL DATA ---\nFrom: {{ $json.from }}\nTo: {{ $json.to }}\nCC: {{ $json.cc }}\nSubject: {{ $json.subject }}\nDate: {{ $json.date }}\nHas Attachments: {{ $json.hasAttachments }}\nIs Reply: {{ $json.isReply }}\nIs Forward: {{ $json.isForward }}\nSender Domain: {{ $json.senderDomain }}\n\n--- EMAIL BODY ---\n{{ $json.bodyText }}\n\n--- CLASSIFY AND RESPOND ---","options":{"systemMessage":"You are an expert email triage assistant. Your job is to classify incoming emails and generate appropriate reply drafts for important ones.\n\n---\n\nEMAIL CATEGORIES (choose exactly one):\n\n1. urgent\n   - Requires immediate attention or response within hours\n   - Time-sensitive requests, deadlines today/tomorrow\n   - Boss/client escalations, critical issues\n   - Payment/billing problems that need immediate action\n   - Meeting in the next few hours that needs confirmation\n   - Keywords: ASAP, urgent, immediately, deadline, critical, emergency, end of day, EOD\n\n2. action_required\n   - Needs a response or action but not time-critical\n   - Meeting requests, document reviews, approval requests\n   - Questions that need thoughtful answers\n   - Project updates requiring input\n   - Invitations needing RSVP\n   - Collaboration requests\n\n3. follow_up\n   - Informational but may need future action\n   - Status updates, FYI emails\n   - Shared documents for review later\n   - Introductions and networking\n   - Ongoing conversation threads\n   - Thank you emails that might need acknowledgment\n\n4. newsletter\n   - Subscribed content, digests, roundups\n   - Blog post notifications\n   - Industry news, product updates from services you use\n   - Weekly/monthly summaries\n   - Educational content, webinar invites\n   - Has unsubscribe link\n\n5. automated\n   - System-generated notifications\n   - Order confirmations, shipping updates\n   - Password resets, login alerts\n   - Calendar notifications\n   - CI/CD pipeline alerts\n   - Monitoring alerts, server notifications\n   - Sent from noreply@ or notification@ addresses\n\n6. spam_promo\n   - Unsolicited marketing, cold outreach you did not request\n   - Promotional offers, discount codes\n   - \"You've been selected\" type emails\n   - Link-heavy promotional content\n   - Mass marketing campaigns\n   - Emails from unknown senders with salesy language\n\n---\n\nCLASSIFICATION RULES:\n\n1. Look at the sender domain — noreply@, notification@, marketing@ are strong signals.\n2. Check the subject line for urgency keywords.\n3. Analyze the body for calls to action, deadlines, or questions directed at the recipient.\n4. If the email is a reply in a thread (is_reply = true), it's more likely action_required or follow_up.\n5. Forwarded emails often need action or are FYI.\n6. Short emails with direct questions = action_required or urgent.\n7. Long emails with links and images = newsletter or spam_promo.\n8. When in doubt between newsletter and spam_promo, check if the sender seems legitimate.\n9. When in doubt between action_required and follow_up, lean toward action_required.\n\n---\n\nREPLY DRAFT RULES:\n\n- Generate a reply draft ONLY for: urgent, action_required, and follow_up categories.\n- Do NOT generate replies for: newsletter, automated, spam_promo.\n- Reply tone: Professional but warm. Not robotic.\n- Reply length: 30-80 words. Short and actionable.\n- Start with context acknowledgment, then address the ask.\n- End with a clear next step or question.\n- Do NOT include subject line in the reply body.\n- Do NOT include greetings like \"Dear\" — use first name.\n- Sign off with just \"Best,\" or \"Thanks,\" (the user will add their name).\n\n---\n\nPRIORITY SCORING:\n- 1 = Low (newsletters, automated, spam)\n- 2 = Medium (follow-up, informational)\n- 3 = High (action required, needs response)\n- 4 = Critical (urgent, time-sensitive)\n\n---\n\nRESPOND WITH ONLY RAW JSON. No markdown fences. No explanation. Start with { end with }.\n\n{\n  \"category\": \"urgent\" or \"action_required\" or \"follow_up\" or \"newsletter\" or \"automated\" or \"spam_promo\",\n  \"priority\": 1 to 4,\n  \"confidence\": 0.0 to 1.0,\n  \"reason\": \"One sentence explaining why this classification was chosen\",\n  \"summary\": \"2-3 sentence summary of what the email is about\",\n  \"keyAction\": \"What the recipient needs to do (if anything)\" or \"No action needed\",\n  \"replyDraft\": \"The suggested reply text\" or \"\",\n  \"replySubject\": \"Re: original subject\" or \"\",\n  \"suggestedLabel\": \"🔴 Urgent\" or \"📋 Action Required\" or \"💬 Follow-up\" or \"📰 Newsletter\" or \"🤖 Automated\" or \"🚫 Spam-Promo\",\n  \"shouldAutoArchive\": true or false,\n  \"sentimentTone\": \"positive\" or \"neutral\" or \"negative\" or \"urgent\"\n}"},"promptType":"define","hasOutputParser":true},"typeVersion":2.1},{"id":"abdbf241-4eb7-47b4-983d-23da8b06848f","name":"🎯 Extract Classification","type":"n8n-nodes-base.code","position":[1088,1088],"parameters":{"jsCode":"// Extract AI classification from response\nconst emailData = $('🔧 Extract Email Data').item.json;\nconst rawAiOutput = $json;\n\nlet classData = {};\n\nfunction extractJSON(str) {\n  if (typeof str !== 'string') return null;\n  let cleaned = str.replace(/```json\\s*/gi, '').replace(/```\\s*/g, '').trim();\n  try { return JSON.parse(cleaned); } catch (e) {\n    const match = cleaned.match(/\\{[\\s\\S]*\"category\"\\s*:[\\s\\S]*\\}/);\n    if (match) { try { return JSON.parse(match[0]); } catch (e2) { return null; } }\n    return null;\n  }\n}\n\nfunction findAIResponse(obj, depth = 0) {\n  if (depth > 5 || !obj || typeof obj !== 'object') return null;\n  if (obj.category && typeof obj.category === 'string') return obj;\n  const props = ['output', 'text', 'message', 'content', 'response', 'result', 'data', 'json', 'kwargs', 'lc_kwargs'];\n  for (const prop of props) {\n    if (obj[prop] !== undefined) {\n      if (typeof obj[prop] === 'string') { const p = extractJSON(obj[prop]); if (p && p.category) return p; }\n      else if (typeof obj[prop] === 'object') { const f = findAIResponse(obj[prop], depth + 1); if (f) return f; }\n    }\n  }\n  for (const key of Object.keys(obj)) {\n    if (props.includes(key)) continue;\n    const val = obj[key];\n    if (typeof val === 'string' && val.includes('\"category\"')) { const p = extractJSON(val); if (p && p.category) return p; }\n    else if (typeof val === 'object' && val !== null) { const f = findAIResponse(val, depth + 1); if (f) return f; }\n  }\n  return null;\n}\n\ntry {\n  if (rawAiOutput && rawAiOutput.category) { classData = rawAiOutput; }\n  else { const found = findAIResponse(rawAiOutput); if (found) classData = found; }\n  if (!classData.category) { const s = JSON.stringify(rawAiOutput); const p = extractJSON(s); if (p && p.category) classData = p; }\n} catch (error) {}\n\nconst validCategories = ['urgent', 'action_required', 'follow_up', 'newsletter', 'automated', 'spam_promo'];\n\nif (!classData.category || !validCategories.includes(classData.category)) {\n  classData = {\n    category: 'follow_up',\n    priority: 2,\n    confidence: 0.5,\n    reason: 'Could not parse AI response — defaulting to follow_up',\n    summary: emailData.bodyPreview || 'Email content',\n    keyAction: 'Review manually',\n    replyDraft: '',\n    replySubject: '',\n    suggestedLabel: '💬 Follow-up',\n    shouldAutoArchive: false,\n    sentimentTone: 'neutral'\n  };\n}\n\nreturn {\n  json: {\n    // Email data\n    gmailId: emailData.gmailId,\n    threadId: emailData.threadId,\n    from: emailData.from,\n    senderName: emailData.senderName,\n    senderEmail: emailData.senderEmail,\n    senderDomain: emailData.senderDomain,\n    to: emailData.to,\n    subject: emailData.subject,\n    date: emailData.date,\n    bodyPreview: emailData.bodyPreview,\n    hasAttachments: emailData.hasAttachments,\n    isReply: emailData.isReply,\n    replyTo: emailData.replyTo,\n    \n    // AI classification\n    category: classData.category,\n    priority: classData.priority || 2,\n    confidence: parseFloat(classData.confidence) || 0,\n    reason: classData.reason || '',\n    summary: classData.summary || '',\n    keyAction: classData.keyAction || '',\n    replyDraft: classData.replyDraft || '',\n    replySubject: classData.replySubject || `Re: ${emailData.subject}`,\n    suggestedLabel: classData.suggestedLabel || '💬 Follow-up',\n    shouldAutoArchive: classData.shouldAutoArchive === true,\n    sentimentTone: classData.sentimentTone || 'neutral',\n    \n    // Meta\n    processedAt: new Date().toISOString()\n  }\n};"},"typeVersion":2},{"id":"24539ed4-1050-4e06-a2d3-3bef0ddaedb9","name":"🔀 Route by Category","type":"n8n-nodes-base.switch","position":[1344,1088],"parameters":{"rules":{"values":[{"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":false,"typeValidation":"strict"},"combinator":"and","conditions":[{"operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.category }}","rightValue":"urgent"}]},"renameOutput":true},{"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":false,"typeValidation":"strict"},"combinator":"and","conditions":[{"operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.category }}","rightValue":"action_required"}]},"renameOutput":true},{"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":false,"typeValidation":"strict"},"combinator":"and","conditions":[{"operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.category }}","rightValue":"follow_up"}]},"renameOutput":true},{"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":false,"typeValidation":"strict"},"combinator":"and","conditions":[{"operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.category }}","rightValue":"newsletter"}]},"renameOutput":true},{"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":false,"typeValidation":"strict"},"combinator":"and","conditions":[{"operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.category }}","rightValue":"automated"}]},"renameOutput":true},{"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":false,"typeValidation":"strict"},"combinator":"and","conditions":[{"operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.category }}","rightValue":"spam_promo"}]},"renameOutput":true}]},"options":{"allMatchingOutputs":false}},"typeVersion":3.2},{"id":"1b2f61c6-0e8e-41ed-85b1-7ede8ddf12db","name":"🏷️ Label: Urgent","type":"n8n-nodes-base.gmail","position":[1600,800],"webhookId":"00000000-0000-0000-0000-000000000001","parameters":{"labelIds":["YOUR_LABEL_ID_URGENT"],"messageId":"={{ $json.gmailId }}","operation":"addLabels"},"credentials":{"gmailOAuth2":{"id":"credential-id","name":"Gmail account"}},"typeVersion":2.2},{"id":"6698eeaa-a2fd-429e-b552-f09438535441","name":"📝 Draft Reply (Urgent)","type":"n8n-nodes-base.gmail","position":[1840,800],"webhookId":"00000000-0000-0000-0000-000000000002","parameters":{"message":"={{ $json.replyDraft }}","options":{"threadId":"={{ $json.threadId }}"},"subject":"={{ $json.replySubject }}","resource":"draft"},"credentials":{"gmailOAuth2":{"id":"credential-id","name":"Gmail account"}},"typeVersion":2.2},{"id":"d338bc75-a2b5-41bc-96a1-88aa96a1fc25","name":"🏷️ Label: Action Required","type":"n8n-nodes-base.gmail","position":[1600,960],"webhookId":"00000000-0000-0000-0000-000000000003","parameters":{"labelIds":["YOUR_LABEL_ID_ACTION_REQUIRED"],"messageId":"={{ $json.gmailId }}","operation":"addLabels"},"credentials":{"gmailOAuth2":{"id":"credential-id","name":"Gmail account"}},"typeVersion":2.2},{"id":"1540bf40-50a9-4cea-8255-27bf0aa0cccd","name":"📝 Draft Reply (Action)","type":"n8n-nodes-base.gmail","position":[1840,960],"webhookId":"00000000-0000-0000-0000-000000000004","parameters":{"message":"={{ $json.replyDraft }}","options":{"threadId":"={{ $json.threadId }}"},"subject":"={{ $json.replySubject }}","resource":"draft"},"credentials":{"gmailOAuth2":{"id":"credential-id","name":"Gmail account"}},"typeVersion":2.2},{"id":"ef532b54-ad93-4805-94a4-af104ef20588","name":"🏷️ Label: Follow-up","type":"n8n-nodes-base.gmail","position":[1600,1120],"webhookId":"00000000-0000-0000-0000-000000000005","parameters":{"labelIds":["YOUR_LABEL_ID_FOLLOW_UP"],"messageId":"={{ $json.gmailId }}","operation":"addLabels"},"credentials":{"gmailOAuth2":{"id":"credential-id","name":"Gmail account"}},"typeVersion":2.2},{"id":"c360cea5-623d-45eb-8ce0-c6b7c4db9deb","name":"🏷️ Label: Newsletter","type":"n8n-nodes-base.gmail","position":[1600,1248],"webhookId":"00000000-0000-0000-0000-000000000006","parameters":{"labelIds":["YOUR_LABEL_ID_NEWSLETTER"],"messageId":"={{ $json.gmailId }}","operation":"addLabels"},"credentials":{"gmailOAuth2":{"id":"credential-id","name":"Gmail account"}},"typeVersion":2.2},{"id":"4304e340-abe5-4b39-b3de-c07831ed52cf","name":"🏷️ Label: Automated","type":"n8n-nodes-base.gmail","position":[1600,1408],"webhookId":"00000000-0000-0000-0000-000000000007","parameters":{"labelIds":["YOUR_LABEL_ID_AUTOMATED"],"messageId":"={{ $json.gmailId }}","operation":"addLabels"},"credentials":{"gmailOAuth2":{"id":"credential-id","name":"Gmail account"}},"typeVersion":2.2},{"id":"139f1b21-d3bf-4e64-bb24-31e752bbde15","name":"🏷️ Label: Spam-Promo","type":"n8n-nodes-base.gmail","position":[1600,1600],"webhookId":"00000000-0000-0000-0000-000000000008","parameters":{"labelIds":["YOUR_LABEL_ID_SPAM_PROMO"],"messageId":"={{ $json.gmailId }}","operation":"addLabels"},"credentials":{"gmailOAuth2":{"id":"credential-id","name":"Gmail account"}},"typeVersion":2.2},{"id":"91a158e1-ccc9-4238-a69b-0418d60cb82d","name":"📋 Prepare Log Entry","type":"n8n-nodes-base.code","position":[2080,1088],"parameters":{"jsCode":"// Merge all paths back for logging\nconst item = $input.all()[0].json;\n\n// Try to get original classification data from the appropriate upstream node\nlet classificationData = {};\n\ntry {\n  classificationData = $('🎯 Extract Classification').item.json;\n} catch (e) {\n  classificationData = item;\n}\n\nreturn {\n  json: {\n    // For Google Sheets logging\n    Date: classificationData.date || new Date().toISOString(),\n    From: classificationData.from || '',\n    Subject: classificationData.subject || '',\n    Category: classificationData.category || '',\n    Priority: classificationData.priority || '',\n    Confidence: classificationData.confidence || '',\n    Reason: classificationData.reason || '',\n    Summary: classificationData.summary || '',\n    'Key Action': classificationData.keyAction || '',\n    'Has Reply Draft': classificationData.replyDraft ? 'Yes' : 'No',\n    Sentiment: classificationData.sentimentTone || '',\n    'Auto Archive': classificationData.shouldAutoArchive ? 'Yes' : 'No',\n    'Gmail ID': classificationData.gmailId || '',\n    'Processed At': classificationData.processedAt || new Date().toISOString()\n  }\n};"},"typeVersion":2},{"id":"3518b511-57c9-4d97-aa32-9b79631e8994","name":"📊 Log to Sheet","type":"n8n-nodes-base.googleSheets","position":[2384,1088],"parameters":{"columns":{"value":{},"schema":[{"id":"Date","type":"string","display":true,"removed":false,"required":false,"displayName":"Date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"From","type":"string","display":true,"removed":false,"required":false,"displayName":"From","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Subject","type":"string","display":true,"removed":false,"required":false,"displayName":"Subject","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Category","type":"string","display":true,"removed":false,"required":false,"displayName":"Category","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Priority","type":"string","display":true,"removed":false,"required":false,"displayName":"Priority","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Confidence","type":"string","display":true,"removed":false,"required":false,"displayName":"Confidence","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Reason","type":"string","display":true,"removed":false,"required":false,"displayName":"Reason","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Summary","type":"string","display":true,"removed":false,"required":false,"displayName":"Summary","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Key Action","type":"string","display":true,"removed":false,"required":false,"displayName":"Key Action","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Has Reply Draft","type":"string","display":true,"removed":false,"required":false,"displayName":"Has Reply Draft","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Sentiment","type":"string","display":true,"removed":false,"required":false,"displayName":"Sentiment","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Auto Archive","type":"string","display":true,"removed":false,"required":false,"displayName":"Auto Archive","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Gmail ID","type":"string","display":true,"removed":false,"required":false,"displayName":"Gmail ID","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Processed At","type":"string","display":true,"removed":false,"required":false,"displayName":"Processed At","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"autoMapInputData","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":772918340,"cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit#gid=772918340","cachedResultName":"log entry"},"documentId":{"__rl":true,"mode":"list","value":"YOUR_GOOGLE_SHEET_ID","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit","cachedResultName":"Email Triage Log"}},"credentials":{"googleSheetsOAuth2Api":{"id":"credential-id","name":"Google Sheets account"}},"typeVersion":4.6},{"id":"b39e4a70-1ccc-421f-87d6-1ac95fe53c48","name":"Ollama Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOllama","position":[560,1328],"parameters":{"model":"mistral","options":{}},"credentials":{"ollamaApi":{"id":"credential-id","name":"Ollama account"}},"typeVersion":1}],"active":false,"pinData":{},"settings":{"binaryMode":"separate","availableInMCP":false,"executionOrder":"v1"},"versionId":"00000000-0000-0000-0000-000000000000","connections":{"Ollama Chat Model":{"ai_languageModel":[[{"node":"🤖 AI Email Classifier","type":"ai_languageModel","index":0}]]},"📥 Gmail Trigger":{"main":[[{"node":"🔧 Extract Email Data","type":"main","index":0}]]},"🏷️ Label: Urgent":{"main":[[{"node":"📝 Draft Reply (Urgent)","type":"main","index":0}]]},"📋 Prepare Log Entry":{"main":[[{"node":"📊 Log to Sheet","type":"main","index":0}]]},"🔀 Route by Category":{"main":[[{"node":"🏷️ Label: Urgent","type":"main","index":0}],[{"node":"🏷️ Label: Action Required","type":"main","index":0}],[{"node":"🏷️ Label: Follow-up","type":"main","index":0}],[{"node":"🏷️ Label: Newsletter","type":"main","index":0}],[{"node":"🏷️ Label: Automated","type":"main","index":0}],[{"node":"🏷️ Label: Spam-Promo","type":"main","index":0}]]},"🔧 Extract Email Data":{"main":[[{"node":"🤖 AI Email Classifier","type":"main","index":0}]]},"🏷️ Label: Automated":{"main":[[{"node":"📋 Prepare Log Entry","type":"main","index":0}]]},"🏷️ Label: Follow-up":{"main":[[{"node":"📋 Prepare Log Entry","type":"main","index":0}]]},"🤖 AI Email Classifier":{"main":[[{"node":"🎯 Extract Classification","type":"main","index":0}]]},"🏷️ Label: Newsletter":{"main":[[{"node":"📋 Prepare Log Entry","type":"main","index":0}]]},"🏷️ Label: Spam-Promo":{"main":[[{"node":"📋 Prepare Log Entry","type":"main","index":0}]]},"📝 Draft Reply (Action)":{"main":[[{"node":"📋 Prepare Log Entry","type":"main","index":0}]]},"📝 Draft Reply (Urgent)":{"main":[[{"node":"📋 Prepare Log Entry","type":"main","index":0}]]},"🎯 Extract Classification":{"main":[[{"node":"🔀 Route by Category","type":"main","index":0}]]},"🏷️ Label: Action Required":{"main":[[{"node":"📝 Draft Reply (Action)","type":"main","index":0}]]}}},"lastUpdatedBy":1,"workflowInfo":{"nodeCount":23,"nodeTypes":{"n8n-nodes-base.code":{"count":3},"n8n-nodes-base.gmail":{"count":8},"n8n-nodes-base.switch":{"count":1},"n8n-nodes-base.stickyNote":{"count":7},"n8n-nodes-base.gmailTrigger":{"count":1},"n8n-nodes-base.googleSheets":{"count":1},"@n8n/n8n-nodes-langchain.agent":{"count":1},"@n8n/n8n-nodes-langchain.lmChatOllama":{"count":1}}},"status":"published","readyToDemo":null,"user":{"name":"Tony Adijah","username":"togo","bio":"Automating the boring stuff so you don’t have to. 🤖 📐 n8n Workflows & Templates 🚀 Helping you save 10+ hours a week. 👇 Grab free workflows below.","verified":true,"links":["https://www.linkedin.com/in/tony-adijah-965903131/"],"avatar":"https://gravatar.com/avatar/e2635712dd01a1dae354636c1a925735948ada9697e9d55824f24558a3eab732?r=pg&d=retro&size=200"},"nodes":[{"id":18,"icon":"file:googleSheets.svg","name":"n8n-nodes-base.googleSheets","codex":{"data":{"alias":["CSV","Sheet","Spreadsheet","GS"],"resources":{"generic":[{"url":"https://n8n.io/blog/love-at-first-sight-ricardos-n8n-journey/","icon":"❤️","label":"Love at first sight: Ricardo’s n8n journey"},{"url":"https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/","icon":"🧬","label":"Why business process automation with n8n can change your daily life"},{"url":"https://n8n.io/blog/automatically-adding-expense-receipts-to-google-sheets-with-telegram-mindee-twilio-and-n8n/","icon":"🧾","label":"Automatically Adding Expense Receipts to Google Sheets with Telegram, Mindee, Twilio, and n8n"},{"url":"https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/","icon":"🎫","label":"Supercharging your conference registration process with n8n"},{"url":"https://n8n.io/blog/creating-triggers-for-n8n-workflows-using-polling/","icon":"⏲","label":"Creating triggers for n8n workflows using polling"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/migrating-community-metrics-to-orbit-using-n8n/","icon":"📈","label":"Migrating Community Metrics to Orbit using n8n"},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/your-business-doesnt-need-you-to-operate/","icon":" 🖥️","label":"Hey founders! Your business doesn't need you to operate"},{"url":"https://n8n.io/blog/how-honest-burgers-use-automation-to-save-100k-per-year/","icon":"🍔","label":"How Honest Burgers Use Automation to Save $100k per year"},{"url":"https://n8n.io/blog/how-a-digital-strategist-uses-n8n-for-online-marketing/","icon":"💻","label":"How a digital strategist uses n8n for online marketing"},{"url":"https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/","icon":"🧠","label":"Why this Product Manager loves workflow automation with n8n"},{"url":"https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/","icon":"🙌","label":"Sending Automated Congratulations with Google Sheets, Twilio, and n8n "},{"url":"https://n8n.io/blog/how-a-membership-development-manager-automates-his-work-and-investments/","icon":"📈","label":"How a Membership Development Manager automates his work and investments"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlesheets/"}],"credentialDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/"}]},"categories":["Data & Storage","Productivity"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"input\",\"output\"]","defaults":{"name":"Google Sheets"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MCIgaGVpZ2h0PSI2MCI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGZpbGw9IiMyOEI0NDYiIGQ9Ik0zNS42OSAxIDUyIDE3LjIyNXYzOS4wODdhMy42NyAzLjY3IDAgMCAxLTEuMDg0IDIuNjFBMy43IDMuNyAwIDAgMSA0OC4yOTMgNjBIMTIuNzA3YTMuNyAzLjcgMCAwIDEtMi42MjMtMS4wNzhBMy42NyAzLjY3IDAgMCAxIDkgNTYuMzEyVjQuNjg4YTMuNjcgMy42NyAwIDAgMSAxLjA4NC0yLjYxQTMuNyAzLjcgMCAwIDEgMTIuNzA3IDF6Ii8+PHBhdGggZmlsbD0iIzZBQ0U3QyIgZD0iTTM1LjY5IDEgNTIgMTcuMjI1SDM5LjM5N2MtMi4wNTQgMC0zLjcwNy0xLjgyOS0zLjcwNy0zLjg3MnoiLz48cGF0aCBmaWxsPSIjMjE5QjM4IiBkPSJNMzkuMjExIDE3LjIyNSA1MiAyMi40OHYtNS4yNTV6Ii8+PHBhdGggZmlsbD0iI0ZGRiIgZD0iTTIwLjEyIDMxLjk3NWMwLS44MTcuNjYyLTEuNDc1IDEuNDgzLTEuNDc1aDE3Ljc5NGMuODIxIDAgMS40ODIuNjU4IDEuNDgyIDEuNDc1djE1LjQ4N2MwIC44MTgtLjY2MSAxLjQ3NS0xLjQ4MiAxLjQ3NUgyMS42MDNhMS40NzYgMS40NzYgMCAwIDEtMS40ODItMS40NzRWMzEuOTc0em0yLjIyNSAxLjQ3NWg2LjY3MnYyLjIxMmgtNi42NzJ6bTAgNS4xNjJoNi42NzJ2Mi4yMTNoLTYuNjcyem0wIDUuMTYzaDYuNjcydjIuMjEyaC02LjY3MnptOS42MzgtMTAuMzI1aDYuNjcydjIuMjEyaC02LjY3MnptMCA1LjE2Mmg2LjY3MnYyLjIxM2gtNi42NzJ6bTAgNS4xNjNoNi42NzJ2Mi4yMTJoLTYuNjcyeiIvPjxwYXRoIGZpbGw9IiMyOEI0NDYiIGQ9Ik0zNC42OSAwIDUxIDE2LjIyNXYzOS4wODdhMy42NyAzLjY3IDAgMCAxLTEuMDg0IDIuNjFBMy43IDMuNyAwIDAgMSA0Ny4yOTMgNTlIMTEuNzA3YTMuNyAzLjcgMCAwIDEtMi42MjMtMS4wNzhBMy42NyAzLjY3IDAgMCAxIDggNTUuMzEyVjMuNjg4YTMuNjcgMy42NyAwIDAgMSAxLjA4NC0yLjYxQTMuNyAzLjcgMCAwIDEgMTEuNzA3IDB6Ii8+PHBhdGggZmlsbD0iIzZBQ0U3QyIgZD0iTTM0LjY5IDAgNTEgMTYuMjI1SDM4LjM5N2MtMi4wNTQgMC0zLjcwNy0xLjgyOS0zLjcwNy0zLjg3MnoiLz48cGF0aCBmaWxsPSIjMjE5QjM4IiBkPSJNMzguMjExIDE2LjIyNSA1MSAyMS40OHYtNS4yNTV6Ii8+PHBhdGggZmlsbD0iI0ZGRiIgZD0iTTE5LjEyIDMwLjk3NWMwLS44MTcuNjYyLTEuNDc1IDEuNDgzLTEuNDc1aDE3Ljc5NGMuODIxIDAgMS40ODIuNjU4IDEuNDgyIDEuNDc1djE1LjQ4N2MwIC44MTgtLjY2MSAxLjQ3NS0xLjQ4MiAxLjQ3NUgyMC42MDNhMS40NzYgMS40NzYgMCAwIDEtMS40ODItMS40NzRWMzAuOTc0em0yLjIyNSAxLjQ3NWg2LjY3MnYyLjIxMmgtNi42NzJ6bTAgNS4xNjJoNi42NzJ2Mi4yMTNoLTYuNjcyem0wIDUuMTYzaDYuNjcydjIuMjEyaC02LjY3MnptOS42MzgtMTAuMzI1aDYuNjcydjIuMjEyaC02LjY3MnptMCA1LjE2Mmg2LjY3MnYyLjIxM2gtNi42NzJ6bTAgNS4xNjNoNi42NzJ2Mi4yMTJoLTYuNjcyeiIvPjwvZz48L3N2Zz4="},"displayName":"Google Sheets","typeVersion":5,"nodeCategories":[{"id":3,"name":"Data & Storage"},{"id":4,"name":"Productivity"}]},{"id":112,"icon":"fa:map-signs","name":"n8n-nodes-base.switch","codex":{"data":{"alias":["Router","If","Path","Filter","Condition","Logic","Branch","Case"],"resources":{"generic":[{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/build-your-own-virtual-assistant-with-n8n-a-step-by-step-guide/","icon":"👦","label":"Build your own virtual assistant with n8n: A step by step guide"},{"url":"https://n8n.io/blog/automation-for-maintainers-of-open-source-projects/","icon":"🏷️","label":"How to automatically manage contributions to open-source projects"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.switch/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Flow"]}}},"group":"[\"transform\"]","defaults":{"name":"Switch","color":"#506000"},"iconData":{"icon":"map-signs","type":"icon"},"displayName":"Switch","typeVersion":3,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":356,"icon":"file:gmail.svg","name":"n8n-nodes-base.gmail","codex":{"data":{"alias":["email","human","form","wait","hitl","approval"],"resources":{"generic":[{"url":"https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/","icon":"🧬","label":"Why business process automation with n8n can change your daily life"},{"url":"https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/","icon":"🎫","label":"Supercharging your conference registration process with n8n"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/your-business-doesnt-need-you-to-operate/","icon":" 🖥️","label":"Hey founders! Your business doesn't need you to operate"},{"url":"https://n8n.io/blog/using-automation-to-boost-productivity-in-the-workplace/","icon":"💪","label":"Using Automation to Boost Productivity in the Workplace"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.gmail/"}],"credentialDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/"}]},"categories":["Communication","HITL"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"HITL":["Human in the Loop"]}}},"group":"[\"transform\"]","defaults":{"name":"Gmail"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTYiIGhlaWdodD0iMTkzIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PHBhdGggZmlsbD0iIzQyODVGNCIgZD0iTTU4LjE4MiAxOTIuMDVWOTMuMTRMMjcuNTA3IDY1LjA3NyAwIDQ5LjUwNHYxMjUuMDkxYzAgOS42NTggNy44MjUgMTcuNDU1IDE3LjQ1NSAxNy40NTV6Ii8+PHBhdGggZmlsbD0iIzM0QTg1MyIgZD0iTTE5Ny44MTggMTkyLjA1aDQwLjcyN2M5LjY1OSAwIDE3LjQ1NS03LjgyNiAxNy40NTUtMTcuNDU1VjQ5LjUwNWwtMzEuMTU2IDE3LjgzNy0yNy4wMjYgMjUuNzk4eiIvPjxwYXRoIGZpbGw9IiNFQTQzMzUiIGQ9Im01OC4xODIgOTMuMTQtNC4xNzQtMzguNjQ3IDQuMTc0LTM2Ljk4OUwxMjggNjkuODY4bDY5LjgxOC01Mi4zNjQgNC42NyAzNC45OTItNC42NyA0MC42NDRMMTI4IDE0NS41MDR6Ii8+PHBhdGggZmlsbD0iI0ZCQkMwNCIgZD0iTTE5Ny44MTggMTcuNTA0VjkzLjE0TDI1NiA0OS41MDRWMjYuMjMxYzAtMjEuNTg1LTI0LjY0LTMzLjg5LTQxLjg5LTIwLjk0NXoiLz48cGF0aCBmaWxsPSIjQzUyMjFGIiBkPSJtMCA0OS41MDQgMjYuNzU5IDIwLjA3TDU4LjE4MiA5My4xNFYxNy41MDRMNDEuODkgNS4yODZDMjQuNjEtNy42NiAwIDQuNjQ2IDAgMjYuMjN6Ii8+PC9zdmc+"},"displayName":"Gmail","typeVersion":2,"nodeCategories":[{"id":6,"name":"Communication"},{"id":28,"name":"HITL"}]},{"id":565,"icon":"fa:sticky-note","name":"n8n-nodes-base.stickyNote","codex":{"data":{"alias":["Comments","Notes","Sticky"],"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"input\"]","defaults":{"name":"Sticky Note","color":"#FFD233"},"iconData":{"icon":"sticky-note","type":"icon"},"displayName":"Sticky Note","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":824,"icon":"file:gmail.svg","name":"n8n-nodes-base.gmailTrigger","codex":{"data":{"resources":{"generic":[{"url":"https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/","icon":"🧬","label":"Why business process automation with n8n can change your daily life"},{"url":"https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/","icon":"🎫","label":"Supercharging your conference registration process with n8n"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/your-business-doesnt-need-you-to-operate/","icon":" 🖥️","label":"Hey founders! Your business doesn't need you to operate"},{"url":"https://n8n.io/blog/using-automation-to-boost-productivity-in-the-workplace/","icon":"💪","label":"Using Automation to Boost Productivity in the Workplace"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/trigger-nodes/n8n-nodes-base.gmailtrigger/"}],"credentialDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/"}]},"categories":["Communication"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"trigger\"]","defaults":{"name":"Gmail Trigger"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTYiIGhlaWdodD0iMTkzIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PHBhdGggZmlsbD0iIzQyODVGNCIgZD0iTTU4LjE4MiAxOTIuMDVWOTMuMTRMMjcuNTA3IDY1LjA3NyAwIDQ5LjUwNHYxMjUuMDkxYzAgOS42NTggNy44MjUgMTcuNDU1IDE3LjQ1NSAxNy40NTV6Ii8+PHBhdGggZmlsbD0iIzM0QTg1MyIgZD0iTTE5Ny44MTggMTkyLjA1aDQwLjcyN2M5LjY1OSAwIDE3LjQ1NS03LjgyNiAxNy40NTUtMTcuNDU1VjQ5LjUwNWwtMzEuMTU2IDE3LjgzNy0yNy4wMjYgMjUuNzk4eiIvPjxwYXRoIGZpbGw9IiNFQTQzMzUiIGQ9Im01OC4xODIgOTMuMTQtNC4xNzQtMzguNjQ3IDQuMTc0LTM2Ljk4OUwxMjggNjkuODY4bDY5LjgxOC01Mi4zNjQgNC42NyAzNC45OTItNC42NyA0MC42NDRMMTI4IDE0NS41MDR6Ii8+PHBhdGggZmlsbD0iI0ZCQkMwNCIgZD0iTTE5Ny44MTggMTcuNTA0VjkzLjE0TDI1NiA0OS41MDRWMjYuMjMxYzAtMjEuNTg1LTI0LjY0LTMzLjg5LTQxLjg5LTIwLjk0NXoiLz48cGF0aCBmaWxsPSIjQzUyMjFGIiBkPSJtMCA0OS41MDQgMjYuNzU5IDIwLjA3TDU4LjE4MiA5My4xNFYxNy41MDRMNDEuODkgNS4yODZDMjQuNjEtNy42NiAwIDQuNjQ2IDAgMjYuMjN6Ii8+PC9zdmc+"},"displayName":"Gmail Trigger","typeVersion":1,"nodeCategories":[{"id":6,"name":"Communication"}]},{"id":834,"icon":"file:code.svg","name":"n8n-nodes-base.code","codex":{"data":{"alias":["cpde","Javascript","JS","Python","Script","Custom Code","Function"],"details":"The Code node allows you to execute JavaScript in your workflow.","resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers","Data Transformation"]}}},"group":"[\"transform\"]","defaults":{"name":"Code"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTcxXzQ0MSkiPgo8cGF0aCBkPSJNMTcwLjI4MyA0OEgxOTYuNUMyMDMuMTI3IDQ4IDIwOC41IDQyLjYyNzQgMjA4LjUgMzZWMTJDMjA4LjUgNS4zNzI1OCAyMDMuMTI3IDAgMTk2LjUgMEgxNzAuMjgzQzEyNi4xIDAgOTAuMjgzIDM1LjgxNzIgOTAuMjgzIDgwVjE3NkM5MC4yODMgMjA2LjkyOCA2NS4yMTA5IDIzMiAzNC4yODMgMjMySDIzQzE2LjM3MjYgMjMyIDExIDIzNy4zNzIgMTEgMjQ0VjI2OEMxMSAyNzQuNjI3IDE2LjM3MjQgMjgwIDIyLjk5OTYgMjgwTDM0LjI4MyAyODBDNjUuMjEwOSAyODAgOTAuMjgzIDMwNS4wNzIgOTAuMjgzIDMzNlY0NDBDOTAuMjgzIDQ3OS43NjQgMTIyLjUxOCA1MTIgMTYyLjI4MyA1MTJIMTk2LjVDMjAzLjEyNyA1MTIgMjA4LjUgNTA2LjYyNyAyMDguNSA1MDBWNDc2QzIwOC41IDQ2OS4zNzMgMjAzLjEyNyA0NjQgMTk2LjUgNDY0SDE2Mi4yODNDMTQ5LjAyOCA0NjQgMTM4LjI4MyA0NTMuMjU1IDEzOC4yODMgNDQwVjMzNkMxMzguMjgzIDMwOS4wMjIgMTI4LjAxMSAyODQuNDQzIDExMS4xNjQgMjY1Ljk2MUMxMDYuMTA5IDI2MC40MTYgMTA2LjEwOSAyNTEuNTg0IDExMS4xNjQgMjQ2LjAzOUMxMjguMDExIDIyNy41NTcgMTM4LjI4MyAyMDIuOTc4IDEzOC4yODMgMTc2VjgwQzEzOC4yODMgNjIuMzI2OSAxNTIuNjEgNDggMTcwLjI4MyA0OFoiIGZpbGw9IiNGRjk5MjIiLz4KPHBhdGggZD0iTTMwNSAzNkMzMDUgNDIuNjI3NCAzMTAuMzczIDQ4IDMxNyA0OEgzNDIuOTc5QzM2MC42NTIgNDggMzc0Ljk3OCA2Mi4zMjY5IDM3NC45NzggODBWMTc2QzM3NC45NzggMjAyLjk3OCAzODUuMjUxIDIyNy41NTcgNDAyLjA5OCAyNDYuMDM5QzQwNy4xNTMgMjUxLjU4NCA0MDcuMTUzIDI2MC40MTYgNDAyLjA5OCAyNjUuOTYxQzM4NS4yNTEgMjg0LjQ0MyAzNzQuOTc4IDMwOS4wMjIgMzc0Ljk3OCAzMzZWNDMyQzM3NC45NzggNDQ5LjY3MyAzNjAuNjUyIDQ2NCAzNDIuOTc5IDQ2NEgzMTdDMzEwLjM3MyA0NjQgMzA1IDQ2OS4zNzMgMzA1IDQ3NlY1MDBDMzA1IDUwNi42MjcgMzEwLjM3MyA1MTIgMzE3IDUxMkgzNDIuOTc5QzM4Ny4xNjEgNTEyIDQyMi45NzggNDc2LjE4MyA0MjIuOTc4IDQzMlYzMzZDNDIyLjk3OCAzMDUuMDcyIDQ0OC4wNTEgMjgwIDQ3OC45NzkgMjgwSDQ5MEM0OTYuNjI3IDI4MCA1MDIgMjc0LjYyOCA1MDIgMjY4VjI0NEM1MDIgMjM3LjM3MyA0OTYuNjI4IDIzMiA0OTAgMjMyTDQ3OC45NzkgMjMyQzQ0OC4wNTEgMjMyIDQyMi45NzggMjA2LjkyOCA0MjIuOTc4IDE3NlY4MEM0MjIuOTc4IDM1LjgxNzIgMzg3LjE2MSAwIDM0Mi45NzkgMEgzMTdDMzEwLjM3MyAwIDMwNSA1LjM3MjU4IDMwNSAxMlYzNloiIGZpbGw9IiNGRjk5MjIiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTcxXzQ0MSI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="},"displayName":"Code","typeVersion":2,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]},{"id":1119,"icon":"fa:robot","name":"@n8n/n8n-nodes-langchain.agent","codex":{"data":{"alias":["LangChain","Chat","Conversational","Plan and Execute","ReAct","Tools"],"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent/"}]},"categories":["AI","Langchain"],"subcategories":{"AI":["Agents","Root Nodes"]}}},"group":"[\"transform\"]","defaults":{"name":"AI Agent","color":"#404040"},"iconData":{"icon":"robot","type":"icon"},"displayName":"AI Agent","typeVersion":3,"nodeCategories":[{"id":25,"name":"AI"},{"id":26,"name":"Langchain"}]},{"id":1151,"icon":"file:ollama.svg","name":"@n8n/n8n-nodes-langchain.lmChatOllama","codex":{"data":{"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmchatollama/"}]},"categories":["AI","Langchain"],"subcategories":{"AI":["Language Models","Root Nodes"],"Language Models":["Chat Models (Recommended)"]}}},"group":"[\"transform\"]","defaults":{"name":"Ollama Chat Model"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNDEuMzMzIiBoZWlnaHQ9IjM0MS4zMzMiIHZlcnNpb249IjEuMCIgdmlld0JveD0iMCAwIDE4MSAyNTYiPjxnIGZpbGw9IiM3RDdEODciPjxwYXRoIGQ9Ik0zNy43IDE5LjVjLTUuMiAxLjgtOC4zIDQuOS0xMS43IDExLjYtNC41IDguOS02LjIgMTkuMi01LjggMzUuNWwuMyAxNC4yLTUuOCA2LjFjLTE0LjggMTUuNS0xOC41IDM4LjctOS4yIDU3LjRsMy40IDYuOS0yIDQuNGMtMy40IDguMi01IDE2LjQtNSAyNi4zIDAgMTAuOCAxLjggMTkgNS44IDI2LjJsMi42IDQuOC0yLjEgNC45Yy0xLjIgMi43LTIuNiA3LjEtMy4yIDkuOC0xLjQgNi4yLTEuNSAyMi4xLS4xIDI1LjcgMSAyLjYgMS40IDIuNyA3LjYgMi43IDcuMyAwIDcgLjQgNS4zLTguNi0xLjUtOC4yLjItMTguOCA0LjItMjYuNiAzLjctNyAzLjgtMTAuNC41LTE0LjgtNC43LTYuNC02LjgtMTMuNi02LjktMjQtLjEtMTAuMyAxLjQtMTYgNi42LTI2LjEgMy4xLTYuMSAyLjktOC43LTEtMTIuMi0xLjEtMS0zLjEtNC4yLTQuMy03LTEuOS00LjItMi40LTYuOS0yLjMtMTQuMiAwLTExLjQgMi41LTE4LjMgOS41LTI2IDctNy42IDE0LjItMTEgMjMuOS0xMS4yIDQuMSAwIDcuOC0uMiA4LjItLjIuNC0uMSAxLjctMi4yIDIuOS00LjcgMy01LjkgOS42LTExLjkgMTYuNy0xNS4yIDQuOS0yLjMgNy0yLjcgMTQuNy0yLjcgNy45IDAgOS43LjQgMTQuOSAyLjkgNi44IDMuMyAxMy4zIDkuNCAxNS45IDE0LjggMSAyIDIuMyA0LjEgMyA0LjUuNi40IDQuNi44IDguNy44IDYuNy4xIDguMy41IDE0IDMuNiAxMi4zIDYuOCAxOS4zIDE4LjcgMTkuMyAzMy40LjEgNi43LS40IDktMi43IDE0LjItMS42IDMuNS0zLjUgNi44LTQuMyA3LjUtMy40IDIuOC0zLjUgNS44LS41IDExLjcgNS4yIDEwLjEgNi43IDE1LjggNi42IDI2LjEtLjEgMTAuNC0yLjIgMTcuNi02LjkgMjQtMy4zIDQuNC0zLjIgNy44LjUgMTQuOCA0IDcuOCA1LjcgMTguNCA0LjIgMjYuNi0xLjcgOS0yIDguNiA1LjMgOC42IDYuMiAwIDYuNi0uMSA3LjYtMi43IDEuNC0zLjYgMS4zLTE5LjUtLjEtMjUuNy0uNi0yLjctMi03LjEtMy4yLTkuOGwtMi4xLTQuOSAyLjYtNC44YzcuNi0xMy45IDcuOS0zNS45LjYtNTIuOGwtMi00LjcgMi41LTQuNmM5LjktMTguMyA2LjQtNDMuOS04LjEtNTkuMWwtNS44LTYuMS4zLTE0LjJjLjQtMTYuNC0xLjMtMjYuNi01LjgtMzUuNy02LjQtMTIuNi0xNy4yLTE1LjktMjYuMy03LjktNS40IDQuNy05LjIgMTMuOC0xMi4zIDI5LjgtLjMgMS40LTEgMi4yLTEuNyAxLjgtMTguMi04LTI5LjctOC41LTQ0LjMtMi4xTDY1IDU0LjlsLS40LTIuMkM2MSAzNC4yIDU2LjEgMjQuMiA0OSAyMC41Yy00LjMtMi4xLTcuNC0yLjQtMTEuMy0xbTcuNyAxNi44YzQuMiA3LjEgOC4xIDMwLjEgNS43IDMzLjYtLjUuOC0zLjEgMS42LTUuOCAxLjgtMi42LjItNi4yLjgtOCAxLjNsLTMuMS44LS43LTQuOWMtLjgtNS45LjItMTcuMiAyLjItMjQuOEMzNy4xIDM4LjQgNDAuNSAzMiA0MiAzMmMuNSAwIDIgMS45IDMuNCA0LjNtOTYuNS0xYzQgNi41IDYuOSAyMy45IDUuNiAzMy42bC0uNyA0LjktMy4xLS44Yy0xLjgtLjUtNS40LTEuMS04LTEuMy0yLjctLjItNS4zLTEtNS44LTEuOC0xLjItMS43LS4zLTE0LjEgMS43LTIyLjkgMS41LTYuNCA1LjctMTUgNy40LTE1IC40IDAgMS44IDEuNSAyLjkgMy4zIi8+PHBhdGggZD0iTTc3LjggMTE5LjljLTcuMyAyLjQtMTEuNiA1LjEtMTYuNSAxMC40LTUuNSA2LTcuNiAxMi03LjEgMjAuMS41IDcuNiAzLjUgMTIuOSAxMC42IDE4LjMgNi4yIDQuNyAxMi43IDYuMyAyNS43IDYuMyAxNy4yIDAgMjUuOC0zLjYgMzIuOS0xMy44IDQuMi01LjkgNC44LTE1LjUgMS42LTIzLTIuOS02LjgtMTEuMS0xNC4zLTE4LjgtMTcuMy04LTMuMS0yMC43LTMuNi0yOC40LTFtMjUuNyAxMGMxNi4xIDcuMSAxOS40IDIzLjIgNi42IDMxLjgtNC45IDMuMy05LjQgNC4zLTE5LjYgNC4zcy0xNC43LTEtMTkuNi00LjNjLTE3LjgtMTItMy4yLTM1LjYgMjEuMS0zNC4zIDMuOS4yIDguNiAxLjIgMTEuNSAyLjUiLz48cGF0aCBkPSJNODMuOCAxNDAuMWMtMi41IDEuNC0yLjIgNC40LjcgNi43IDIgMS42IDIuNCAyLjYgMS45IDQuOS0uNyAzLjYgMS41IDUuOCA1LjEgNC45IDIuMS0uNSAyLjUtMS4yIDIuNS00LjYgMC0yLjkuNS00LjIgMi01IDIuNy0xLjUgMi43LTYuNiAwLTcuNS0xLS4zLTIuOC0uMS00IC41LTEuNC43LTIuNi44LTMuOSAwLTIuMy0xLjItMi4yLTEuMi00LjMuMW0tNDQuMS0xOC45Yy0uOS43LTIuMyAzLTMuMiA1LTIuMSA1LjMtLjEgMTAuMyA0LjcgMTEuNiA0LjMgMS4xIDYgLjYgOS4yLTIuNyA0LTQuMSA0LjMtOC4xIDEuMS0xMS45LTIuMS0yLjUtMy40LTMuMi02LjQtMy4yLTIgMC00LjUuNi01LjQgMS4ybTg5LjggMmMtMy4yIDMuOC0yLjkgNy44IDEuMSAxMS45IDMuMiAzLjMgNC45IDMuOCA5LjIgMi43IDQuOS0xLjMgNi44LTYuMiA0LjYtMTEuOC0xLjktNC43LTMuOC02LTguNy02LTIuNyAwLTQuMS43LTYuMiAzLjIiLz48L2c+PC9zdmc+"},"displayName":"Ollama Chat Model","typeVersion":1,"nodeCategories":[{"id":25,"name":"AI"},{"id":26,"name":"Langchain"}]}],"categories":[{"id":41,"name":"Ticket Management"},{"id":49,"name":"AI Summarization"}],"image":[]}}