{"workflow":{"id":14135,"name":"Track expenses via chat with Claude Haiku and Google Sheets","views":30,"recentViews":2,"totalViews":30,"createdAt":"2026-03-18T09:31:08.437Z","description":"# 💰 AI Expense Tracker — Chat to Track Spending Instantly\n\n### Track your expenses by chatting naturally. No forms, no apps — just type and it's saved.\n\n---\n\n## 📖 Description\n\nThis workflow turns a simple chat interface into a powerful personal expense tracker. Just describe your spending in plain language — the AI understands it, categorizes it, and saves it to Google Sheets automatically.\n\n**Example inputs the AI understands:**\n- `spent 500 on lunch`\n- `uber 150`\n- `paid 1200 electricity bill`\n- `lunch in feb 25 cost 500` ← handles past dates too\n- `netflix 499`\n- `$50 hotel booking` ← detects currency\n\nNo rigid formats. No dropdowns. Just type naturally.\n\n---\n\n## ✨ Key Features\n\n- **Natural language input** — type expenses exactly how you'd say them\n- **AI-powered parsing** — Claude Haiku extracts amount, category, date, currency automatically\n- **9 auto-detected categories** — Food, Transport, Shopping, Bills, Entertainment, Health, Business, Education, Other\n- **Multi-currency support** — INR, USD, EUR, GBP\n- **Past date handling** — \"lunch in feb 25 cost 500\" saves to February 2025, not today\n- **Running monthly total** — each row stores the cumulative month total\n- **Monthly summary** — type `SUMMARY` or `summary february` for any month\n- **Works on empty sheet** — no errors on first use\n- **Invalid input handling** — friendly error if no amount detected\n\n---\n\n## 💬 Commands\n\n| What you type | What happens |\n| :--- | :--- |\n| `spent 500 on lunch` | ✅ Saved: 🍕 Food & Dining — Lunch · ₹500 |\n| `uber 150` | ✅ Saved: 🚗 Transport — Uber · ₹150 |\n| `1200 electricity bill` | ✅ Saved: 💡 Bills & Utilities · ₹1200 |\n| `lunch in feb 25 cost 500` | ✅ Saved to February 2025 correctly |\n| `SUMMARY` | 📊 Current month report with breakdown |\n| `summary february` | 📊 February report (current year) |\n| `summary february 2025` | 📊 February 2025 specific report |\n| `HELP` | 📖 Shows all commands and categories |\n\n---\n\n## 🛠 Setup Requirements\n\n### 1. Google Sheet\n\nCreate a new Google Sheet with these exact headers in Row 1:\n\n| Col | Header |\n| :---: | :--- |\n| A | `Date` |\n| B | `Amount` |\n| C | `Category` |\n| D | `Description` |\n| E | `Currency` |\n| F | `Month` |\n| G | `Raw Message` |\n| H | `Total` |\n\n### 2. Credentials needed\n\n| Credential | Used for | Free? |\n| :--- | :--- | :--- |\n| **Anthropic API** | Claude Haiku AI parsing | Paid (very low cost) |\n| **Google Sheets OAuth2** | Read & write expenses | Free |\n\n### 3. After importing\n\n1. Connect your **Anthropic** credential to the `Claude Haiku` node\n2. Connect your **Google Sheets** credential to all sheet nodes\n3. Update the Sheet ID in all Google Sheets nodes to point to your sheet\n4. Open the workflow chat and type your first expense\n\n---\n\n## 🏗 How It Works\n\n```\nYou type: \"spent 500 on car wash\"\n        ↓\nDetect Intent  →  classified as: expense\n        ↓\nRead All Expenses  →  loads sheet (works even if empty)\n        ↓\nPrepare Data  →  calculates existing month total\n        ↓\nAI Parse Expense (Claude Haiku)\n  →  amount: 500\n  →  category: Transport\n  →  description: Car wash\n  →  date: today\n  →  currency: INR\n        ↓\nParse & Total\n  →  derives Month from parsed date\n  →  computes new running total\n        ↓\nIs Valid? (amount &gt; 0 and is_expense = true)\n  ✅ YES → Save to Sheet → Reply with confirmation\n  ❌ NO  → Ask user to include an amount\n```\n\n**Summary flow:**\n\n```\nYou type: \"summary february\"\n        ↓\nDetect Intent  →  classified as: summary\n        ↓\nRead for Summary  →  loads all rows\n        ↓\nBuild Summary\n  →  detects \"february\" in message\n  →  filters rows by February (current year)\n  →  calculates total, breakdown by category, daily avg\n        ↓\nReturns formatted report\n```\n\n---\n\n## 📊 Sample Summary Output\n\n```\n📊 March 2026 Report\n\n💳 Total: ₹8,450\n📝 Entries: 12\n📈 Daily avg: ₹470\n🔝 Top: 🍕 Food & Dining\n\nBreakdown:\n🍕 Food & Dining: ₹3,200 (38%)\n🚗 Transport: ₹1,800 (21%)\n💡 Bills & Utilities: ₹1,200 (14%)\n🛍️ Shopping: ₹1,050 (12%)\n🎬 Entertainment: ₹800 (9%)\n🏥 Health: ₹400 (5%)\n```\n\n---\n\n## 📂 Auto-Detected Categories\n\n| Emoji | Category | Example keywords |\n| :---: | :--- | :--- |\n| 🍕 | Food & Dining | lunch, dinner, restaurant, zomato, swiggy, grocery |\n| 🚗 | Transport | uber, ola, petrol, metro, flight, car wash, parking |\n| 🛍️ | Shopping | amazon, flipkart, clothes, electronics, shoes |\n| 💡 | Bills & Utilities | electricity, wifi, rent, recharge, emi, gas |\n| 🎬 | Entertainment | netflix, movie, spotify, concert, gaming |\n| 🏥 | Health | medicine, doctor, gym, pharmacy, hospital |\n| 💼 | Business | office, software, domain, hosting, tools |\n| 📚 | Education | course, books, tuition, udemy, fees |\n| 💰 | Other | anything that doesn't match above |\n\n---\n\n## ⚙️ Workflow Nodes\n\n| Node | Type | Purpose |\n| :--- | :--- | :--- |\n| When chat message received | Chat Trigger | Entry point |\n| Detect Intent | Code | Classify: expense / summary / help |\n| Intent Switch | Switch | Route to correct path |\n| Read All Expenses | Google Sheets | Load rows (alwaysOutputData: true) |\n| Prepare Data | Code | Compute month total, handle empty sheet |\n| AI Parse Expense | LLM Chain | Extract fields using Claude Haiku |\n| Claude Haiku | Anthropic Model | AI model for parsing |\n| Parse & Total | Code | Validate, derive month, compute total |\n| Is Valid Expense? | IF | Check amount &gt; 0 |\n| Save Expense to Sheet | Google Sheets | Append new row |\n| Reply Saved | Code | Format confirmation message |\n| Reply Invalid | Code | Request amount from user |\n| Read for Summary | Google Sheets | Load all rows for report |\n| Build Summary | Code | Filter by month, compute breakdown |\n| Send Help | Code | Return command reference |\n\n---\n\n## 🔧 Customisation Ideas\n\n- **Add a budget alert** — warn when monthly total exceeds a set limit\n- **Telegram integration** — replace chat trigger with Telegram bot\n- **WhatsApp integration** — use Twilio WhatsApp as the input channel\n- **Weekly digest** — add a Schedule Trigger for automatic weekly reports\n- **Multi-user** — store user ID with each row to support team expense tracking\n- **Export to PDF** — generate monthly expense report as a PDF\n\n---\n\n## ⚠️ Important Notes\n\n- The `Read All Expenses` node has **Always Output Data** enabled — this is required so the flow works on an empty sheet\n- Month is derived from the **parsed date**, not today's date — so past-dated entries file correctly\n- The `Total` column stores the running month total at the time of each entry — it does not update retroactively if you delete rows\n\n---\n\n## 📦 Requirements Summary\n\n- n8n (cloud or self-hosted)\n- Anthropic API key (Claude Haiku — very low token usage)\n- Google account with Sheets access\n\n---\n\n*Built with n8n · Claude Haiku · Google Sheets By Nirav Gajera*","workflow":{"meta":{"instanceId":"18dd7b5b2a819da255b0592c0c20c9327ca21e0c36c31033c172c57edf46fb54","templateCredsSetupCompleted":true},"nodes":[{"id":"ff5c621a-0deb-4067-864d-04bd59b6c2e5","name":"When chat message received","type":"@n8n/n8n-nodes-langchain.chatTrigger","position":[6480,4560],"webhookId":"6a34ec84-459d-4cc4-83b6-06ae4c99dc8f","parameters":{"options":{}},"typeVersion":1.1},{"id":"9806596c-ad71-48dc-a7b4-e4ffbc992dbd","name":"Detect Intent","type":"n8n-nodes-base.code","position":[6704,4560],"parameters":{"jsCode":"\nconst chatInput = ($input.first().json.chatInput || $input.first().json.input || '').trim();\nconsole.log('Input:', chatInput);\nconst isSummary = /\\b(summary|report|total|spending|how much|breakdown|stats)\\b/i.test(chatInput);\nconst isHelp = /^(\\?|help|\\/help)$/i.test(chatInput);\nreturn [{ json: {\n  chat_input: chatInput,\n  intent: isSummary ? 'summary' : isHelp ? 'help' : 'expense'\n}}];\n"},"typeVersion":2},{"id":"9387f59f-2ce3-4d22-b8a8-7e48032f3ca2","name":"Intent Switch","type":"n8n-nodes-base.switch","position":[6928,4544],"parameters":{"rules":{"values":[{"conditions":{"options":{"leftValue":"","caseSensitive":false,"typeValidation":"loose"},"combinator":"and","conditions":[{"id":"i1","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.intent }}","rightValue":"expense"}]}},{"conditions":{"options":{"leftValue":"","caseSensitive":false,"typeValidation":"loose"},"combinator":"and","conditions":[{"id":"i2","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.intent }}","rightValue":"summary"}]}},{"conditions":{"options":{"leftValue":"","caseSensitive":false,"typeValidation":"loose"},"combinator":"and","conditions":[{"id":"i3","operator":{"type":"string","operation":"equals"},"leftValue":"={{ $json.intent }}","rightValue":"help"}]}}]},"options":{}},"typeVersion":3.2},{"id":"57ea0ffb-1a76-4f6c-8e60-0e7619c7f4a7","name":"Read All Expenses","type":"n8n-nodes-base.googleSheets","position":[7152,4368],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1n7izUA8ACWfN-XqwOQkEkZ6lspUXsY1PMlmko67tLSg/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1n7izUA8ACWfN-XqwOQkEkZ6lspUXsY1PMlmko67tLSg","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1n7izUA8ACWfN-XqwOQkEkZ6lspUXsY1PMlmko67tLSg/edit?usp=drivesdk","cachedResultName":"Expense track"}},"typeVersion":4.5,"alwaysOutputData":true},{"id":"b9f18554-7c19-4969-86de-0a81be8c53d2","name":"Prepare Data","type":"n8n-nodes-base.code","position":[7376,4368],"parameters":{"jsCode":"\n// This node ALWAYS outputs data regardless of how many rows the sheet has\n// Fixes: \"No item to return\" when sheet is empty\n\nconst allRows = $input.all();\nconst chatInput = $('Detect Intent').first().json.chat_input;\n\n// Calculate current month total from existing rows (0 if empty)\nconst now = new Date();\nconst currentMonth = now.toLocaleString('en-US', {month:'long'}) + ' ' + now.getFullYear();\n\nconst monthTotal = allRows\n  .filter(r => (r.json['Month'] || '') === currentMonth)\n  .reduce((sum, r) => sum + parseFloat(r.json['Amount'] || 0), 0);\n\nconsole.log('Rows in sheet:', allRows.length, '| Month total so far:', monthTotal);\n\n// Always return exactly 1 item so flow never stops\nreturn [{ json: {\n  chat_input:   chatInput,\n  month_total:  monthTotal,\n  current_month: currentMonth,\n  row_count:    allRows.length\n}}];\n"},"typeVersion":2},{"id":"a433bab2-5943-49d2-a770-b75ecd7baa62","name":"AI Parse Expense","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[7600,4368],"parameters":{"text":"=You are an expense parser. Extract expense details from this message and return ONLY a JSON object, nothing else.\n\nMessage: \"{{ $('Detect Intent').first().json.chat_input }}\"\nToday: {{ new Date().toISOString().split('T')[0] }}\n\nReturn ONLY this JSON:\n{\"amount\": <number>, \"description\": \"<2-4 words>\", \"category\": \"<Food & Dining|Transport|Shopping|Bills & Utilities|Entertainment|Health|Business|Education|Other>\", \"currency\": \"<INR|USD|EUR|GBP>\", \"date\": \"<YYYY-MM-DD>\", \"is_expense\": <true|false>}\n\nRules:\n- If the message is clearly an expense with an amount → is_expense: true\n- If no amount can be found → is_expense: false\n- currency default: INR\n- date default: today\n\nExamples:\n\"spent 500 on car wash\" → {\"amount\":500,\"description\":\"Car wash\",\"category\":\"Transport\",\"currency\":\"INR\",\"date\":\"{{ new Date().toISOString().split('T')[0] }}\",\"is_expense\":true}\n\"test 500\" → {\"amount\":500,\"description\":\"Test\",\"category\":\"Other\",\"currency\":\"INR\",\"date\":\"{{ new Date().toISOString().split('T')[0] }}\",\"is_expense\":true}\n\"lunch 450\" → {\"amount\":450,\"description\":\"Lunch\",\"category\":\"Food & Dining\",\"currency\":\"INR\",\"date\":\"{{ new Date().toISOString().split('T')[0] }}\",\"is_expense\":true}\n\"hello\" → {\"amount\":0,\"description\":\"\",\"category\":\"Other\",\"currency\":\"INR\",\"date\":\"{{ new Date().toISOString().split('T')[0] }}\",\"is_expense\":false}\n\nJSON only. No explanation.","promptType":"define"},"typeVersion":1.4},{"id":"627fd6e3-2232-4f76-bafe-a4b01fbc0e51","name":"Claude Haiku","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[7744,4544],"parameters":{"model":{"__rl":true,"mode":"list","value":"claude-haiku-4-5-20251001","cachedResultName":"Claude Haiku 4.5"},"options":{}},"typeVersion":1.3},{"id":"218d3c40-8eb1-4dd8-b1b9-8dc01fa525b0","name":"Parse & Total","type":"n8n-nodes-base.code","position":[7952,4368],"parameters":{"jsCode":"const rawText = ($json.text || $json.output || '').trim();\nconst prepared = $('Prepare Data').first().json;\nconst chatInput = prepared.chat_input;\nconsole.log('AI response:', rawText);\n\nlet parsed = null;\ntry { parsed = JSON.parse(rawText); } catch(e) {}\nif (!parsed) {\n  try { const m = rawText.match(/\\{[\\s\\S]*\\}/); if(m) parsed = JSON.parse(m[0]); } catch(e) {}\n}\n\nif (!parsed || !parsed.is_expense || !parsed.amount || parseFloat(parsed.amount) <= 0) {\n  return [{ json: {\n    valid: false,\n    reply: `I couldn't identify an expense amount in that message.\\n\\nPlease include an amount, like:\\n• \"spent 500 on lunch\"\\n• \"uber 150\"\\n• \"1200 electricity bill\"`\n  }}];\n}\n\nconst emo = {'Food & Dining':'🍕','Transport':'🚗','Shopping':'🛍️','Bills & Utilities':'💡','Entertainment':'🎬','Health':'🏥','Business':'💼','Education':'📚','Other':'💰'};\nconst cat      = parsed.category || 'Other';\nconst amount   = parseFloat(parsed.amount);\nconst currency = parsed.currency || 'INR';\nconst symbol   = currency === 'INR' ? '₹' : currency + ' ';\nconst dateStr  = parsed.date || new Date().toISOString().split('T')[0];\n\n// Derive month from parsed date (not today)\nconst parsedDate     = new Date(dateStr);\nconst entryMonth     = parsedDate.toLocaleString('en-US', {month:'long'}) + ' ' + parsedDate.getFullYear();\n\n// Running total for that specific month\nconst allRows        = $('Read All Expenses').all();\nconst entryMonthTotal = allRows\n  .filter(r => (r.json['Month'] || '') === entryMonth)\n  .reduce((sum, r) => sum + parseFloat(r.json['Amount'] || 0), 0);\nconst newTotal = entryMonthTotal + amount;\n\nconsole.log(`Saving: ${symbol}${amount} | ${cat} | ${parsed.description} | Month: ${entryMonth} | Total: ${newTotal}`);\n\nreturn [{ json: {\n  valid:         true,\n  Date:          dateStr,\n  Amount:        amount,\n  Category:      cat,\n  Description:   parsed.description || chatInput,\n  Currency:      currency,\n  Month:         entryMonth,\n  \"Raw Message\": chatInput,\n  Total:         newTotal,\n  _display: `${emo[cat]||'💰'} *${cat}* — ${parsed.description || chatInput}\\n💳 ${symbol}${amount}\\n📅 ${dateStr}\\n📊 ${entryMonth} total: ${symbol}${newTotal.toFixed(0)}`\n}}];"},"typeVersion":2},{"id":"2a720602-ff73-44f5-9669-986e57be1d4d","name":"Is Valid Expense?","type":"n8n-nodes-base.if","position":[8176,4368],"parameters":{"options":{},"conditions":{"options":{"leftValue":"","caseSensitive":false,"typeValidation":"loose"},"combinator":"and","conditions":[{"id":"v1","operator":{"type":"boolean","operation":"equals","rightType":"boolean"},"leftValue":"={{ $json.valid }}","rightValue":true}]}},"typeVersion":2.1},{"id":"52bdb900-a6c1-4676-83fb-c34f63ea9434","name":"Save Expense to Sheet","type":"n8n-nodes-base.googleSheets","position":[8400,4272],"parameters":{"columns":{"value":{"Date":"={{ $json.Date }}","Month":"={{ $json.Month }}","Total":"={{ $json.Total }}","Amount":"={{ $json.Amount }}","Category":"={{ $json.Category }}","Currency":"={{ $json.Currency }}","Description":"={{ $json.Description }}","Raw Message":"={{ $json['Raw Message'] }}"},"schema":[{"id":"Date","type":"string","display":true,"required":false,"displayName":"Date","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Amount","type":"string","display":true,"required":false,"displayName":"Amount","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Category","type":"string","display":true,"required":false,"displayName":"Category","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Description","type":"string","display":true,"required":false,"displayName":"Description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Currency","type":"string","display":true,"required":false,"displayName":"Currency","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Month","type":"string","display":true,"required":false,"displayName":"Month","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Raw Message","type":"string","display":true,"required":false,"displayName":"Raw Message","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Total","type":"string","display":true,"required":false,"displayName":"Total","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1n7izUA8ACWfN-XqwOQkEkZ6lspUXsY1PMlmko67tLSg/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1n7izUA8ACWfN-XqwOQkEkZ6lspUXsY1PMlmko67tLSg","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1n7izUA8ACWfN-XqwOQkEkZ6lspUXsY1PMlmko67tLSg/edit?usp=drivesdk","cachedResultName":"Expense track"}},"typeVersion":4.5},{"id":"de6afe46-3c00-459c-85e4-8cb613e5714b","name":"Reply Saved","type":"n8n-nodes-base.code","position":[8624,4272],"parameters":{"jsCode":"\nconst d = $('Parse & Total').first().json;\nreturn [{ json: { output: `✅ Expense saved!\\n\\n${d._display}` }}];\n"},"typeVersion":2},{"id":"7d347763-8d31-48c4-aba7-f7ed6f332b6d","name":"Reply Invalid","type":"n8n-nodes-base.code","position":[8400,4464],"parameters":{"jsCode":"\nconst d = $('Parse & Total').first().json;\nreturn [{ json: { output: d.reply || \"Please include an amount in your message.\" }}];\n"},"typeVersion":2},{"id":"e8261ff4-b303-47fd-a0f6-997f27f7b037","name":"Read for Summary","type":"n8n-nodes-base.googleSheets","position":[7264,4736],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1n7izUA8ACWfN-XqwOQkEkZ6lspUXsY1PMlmko67tLSg/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"1n7izUA8ACWfN-XqwOQkEkZ6lspUXsY1PMlmko67tLSg","cachedResultUrl":"https://docs.google.com/spreadsheets/d/1n7izUA8ACWfN-XqwOQkEkZ6lspUXsY1PMlmko67tLSg/edit?usp=drivesdk","cachedResultName":"Expense track"}},"typeVersion":4.5,"alwaysOutputData":true},{"id":"5da81e46-54f5-434c-bd13-21e6c8d1c00a","name":"Build Summary","type":"n8n-nodes-base.code","position":[7472,4736],"parameters":{"jsCode":"const rows = $input.all();\nconst now = new Date();\nconst chatInput = $('Detect Intent').first().json.chat_input;\n\n// Detect if user asked for specific month\nconst monthNames = ['january','february','march','april','may','june','july','august','september','october','november','december'];\nlet targetMonth = null;\n\nconst lower = chatInput.toLowerCase();\nfor (const m of monthNames) {\n  if (lower.includes(m)) {\n    const yearMatch = lower.match(/20(\\d{2})/);\n    const shortYearMatch = lower.match(/\\b(\\d{2})\\b/);\n    let year = now.getFullYear();\n    if (yearMatch) year = parseInt(yearMatch[0]);\n    else if (shortYearMatch) year = 2000 + parseInt(shortYearMatch[1]);\n    targetMonth = m.charAt(0).toUpperCase() + m.slice(1) + ' ' + year;\n    break;\n  }\n}\n\nif (!targetMonth) {\n  targetMonth = now.toLocaleString('en-US', {month:'long'}) + ' ' + now.getFullYear();\n}\n\nconsole.log('Summary for month:', targetMonth);\n\nconst thisMonth = rows.filter(r => (r.json['Month'] || '') === targetMonth);\n\nif (rows.length === 0 || thisMonth.length === 0) {\n  return [{ json: { output: `📊 No expenses found for *${targetMonth}*.\\n\\nTry: SUMMARY or \"summary march\"` }}];\n}\n\nconst total = thisMonth.reduce((s,r) => s + parseFloat(r.json['Amount']||0), 0);\nconst byCategory = {};\nfor (const r of thisMonth) {\n  const cat = r.json['Category'] || 'Other';\n  byCategory[cat] = (byCategory[cat]||0) + parseFloat(r.json['Amount']||0);\n}\nconst sorted = Object.entries(byCategory).sort((a,b) => b[1]-a[1]);\nconst emo = {'Food & Dining':'🍕','Transport':'🚗','Shopping':'🛍️','Bills & Utilities':'💡','Entertainment':'🎬','Health':'🏥','Business':'💼','Education':'📚','Other':'💰'};\nconst lines = sorted.map(([c,a]) => `${emo[c]||'💰'} ${c}: ₹${a.toFixed(0)} (${((a/total)*100).toFixed(0)}%)`).join('\\n');\n\nreturn [{ json: { output:\n  `📊 *${targetMonth} Report*\\n\\n` +\n  `💳 *Total: ₹${total.toFixed(0)}*\\n` +\n  `📝 Entries: ${thisMonth.length}\\n` +\n  `📈 Daily avg: ₹${(total/now.getDate()).toFixed(0)}\\n` +\n  `🔝 Top: ${emo[sorted[0]?.[0]]||'💰'} ${sorted[0]?.[0]}\\n\\n` +\n  `*Breakdown:*\\n${lines}`\n}}];"},"typeVersion":2},{"id":"885991be-8d6f-49f5-b742-c57e3da0aaa3","name":"Send Help","type":"n8n-nodes-base.code","position":[7152,4976],"parameters":{"jsCode":"\nreturn [{ json: { output:\n`💰 *Expense Tracker — Commands*\n\n📝 *Add expense (just type naturally):*\n• \"spent 500 on lunch\"\n• \"paid 1200 electricity bill\"\n• \"uber 150\"\n• \"test 500\"\n• \"₹450 groceries\"\n• \"netflix 499\"\n\n📊 *Monthly report:*\nType: SUMMARY\n\n💱 *Currencies:* ₹INR  $USD  €EUR  £GBP\n\n📂 *Auto-detected categories:*\n🍕 Food & Dining  🚗 Transport\n🛍️ Shopping       💡 Bills & Utilities\n🎬 Entertainment  🏥 Health\n💼 Business       📚 Education  💰 Other`\n}}];\n"},"typeVersion":2},{"id":"fcb94238-8ccf-4b7f-9dff-c6813d5eecb7","name":"Overview","type":"n8n-nodes-base.stickyNote","position":[6128,3968],"parameters":{"width":476,"height":508,"content":"## 💰 AI Expense Tracker\nTrack expenses by chatting naturally.\n\n**Just type your expense:**\n_\"spent 500 on lunch\"_\n_\"uber 150\"_\n_\"1200 electricity bill\"_\n\n**Commands:**\n• `SUMMARY` — current month report\n• `summary february` — specific month\n• `HELP` — all commands\n\n**Currencies:** ₹ INR · $ USD · € EUR · £ GBP"},"typeVersion":1},{"id":"fc55f4ca-d4d0-4f3d-aed3-4cf071cd0919","name":"Trigger Note","type":"n8n-nodes-base.stickyNote","position":[6192,4512],"parameters":{"color":5,"width":424,"height":196,"content":"## 1️⃣ Entry Point\nReceives every chat message.\nPasses `chatInput` to next node."},"typeVersion":1},{"id":"fd4f6cce-59fc-4a26-8976-fb13377c9798","name":"Intent Note","type":"n8n-nodes-base.stickyNote","position":[6624,4288],"parameters":{"color":5,"height":424,"content":"## 2️⃣ Detect Intent\nReads the message and classifies:\n• **expense** — anything with an amount\n• **summary** — report/total/breakdown\n• **help** — help/?"},"typeVersion":1},{"id":"452c8436-94d9-4e03-91a7-50e2406911db","name":"Switch Note","type":"n8n-nodes-base.stickyNote","position":[6880,4288],"parameters":{"color":5,"width":220,"height":430,"content":"## 3️⃣ Routes to 3 paths\n**Output 0** → Expense flow\n**Output 1** → Summary flow\n**Output 2** → Help message"},"typeVersion":1},{"id":"29e8945f-d2ce-40c9-9730-8e63edd4a359","name":"Read Note","type":"n8n-nodes-base.stickyNote","position":[7104,4080],"parameters":{"color":6,"width":204,"height":456,"content":"## 4️⃣ Read Sheet\nLoads all existing rows.\n`alwaysOutputData: true` ensures\nflow continues even if sheet is empty."},"typeVersion":1},{"id":"fbf91c41-741b-49c3-865b-471c296d0737","name":"Prepare Note","type":"n8n-nodes-base.stickyNote","position":[7312,4080],"parameters":{"color":6,"width":220,"height":450,"content":"## 5️⃣ Prepare Data\nComputes running month total\nfrom existing rows.\nAlways outputs 1 item → flow\nnever stops on empty sheet."},"typeVersion":1},{"id":"fe8321dd-c9c0-4733-a70c-ad759db0bf8f","name":"AI Note","type":"n8n-nodes-base.stickyNote","position":[7552,4080],"parameters":{"color":6,"width":300,"height":454,"content":"## 6️⃣ AI Parse\nClaude Haiku reads the message\nand extracts:\n• amount · description\n• category · currency · date\n• is_expense (true/false)\n\nReturns clean JSON only."},"typeVersion":1},{"id":"740ca285-5709-4730-a206-0572bdb160ff","name":"Parse Note","type":"n8n-nodes-base.stickyNote","position":[7872,4080],"parameters":{"color":6,"width":230,"height":450,"content":"## 7️⃣ Parse & Total\nValidates AI response.\nDerives Month from parsed date\n(not today — handles past entries).\nCalculates running monthly total."},"typeVersion":1},{"id":"00edd05c-dcd0-437f-9c4a-c5c1a994680e","name":"Valid Note","type":"n8n-nodes-base.stickyNote","position":[8112,4080],"parameters":{"color":6,"width":212,"height":452,"content":"## 8️⃣ Valid?\n✅ TRUE → Save to sheet\n❌ FALSE → Ask user\nto add an amount"},"typeVersion":1},{"id":"decba3df-1e53-4a14-9c87-bdc3a9303fca","name":"Save Note","type":"n8n-nodes-base.stickyNote","position":[8352,4064],"parameters":{"color":6,"width":492,"height":536,"content":"## 9️⃣ Save + Reply\nAppends new row to sheet.\nReplies with confirmation:\n✅ Category · Amount · Date\n📊 Running month total"},"typeVersion":1},{"id":"9ad784c3-e3f3-41eb-85a7-72f6d3c475a0","name":"Summary Note","type":"n8n-nodes-base.stickyNote","position":[7104,4560],"parameters":{"color":2,"width":596,"height":358,"content":"## 📊 SUMMARY FLOW\nReads all rows → filters by month.\nDetects specific month from message\n_(e.g. \"summary february 2026\")_\nDefaults to current month.\nShows total, breakdown, daily avg."},"typeVersion":1},{"id":"a1a82af4-5888-4681-8c82-1465c2eff8b0","name":"Sheet Columns","type":"n8n-nodes-base.stickyNote","position":[6144,4288],"parameters":{"color":7,"width":200,"height":180,"content":"## 📋 Sheet Columns\nA: Date\nB: Amount\nC: Category\nD: Description\nE: Currency\nF: Month\nG: Raw Message\nH: Total _(running monthly)_"},"typeVersion":1}],"pinData":{},"connections":{"Claude Haiku":{"ai_languageModel":[[{"node":"AI Parse Expense","type":"ai_languageModel","index":0}]]},"Prepare Data":{"main":[[{"node":"AI Parse Expense","type":"main","index":0}]]},"Detect Intent":{"main":[[{"node":"Intent Switch","type":"main","index":0}]]},"Intent Switch":{"main":[[{"node":"Read All Expenses","type":"main","index":0}],[{"node":"Read for Summary","type":"main","index":0}],[{"node":"Send Help","type":"main","index":0}]]},"Parse & Total":{"main":[[{"node":"Is Valid Expense?","type":"main","index":0}]]},"AI Parse Expense":{"main":[[{"node":"Parse & Total","type":"main","index":0}]]},"Read for Summary":{"main":[[{"node":"Build Summary","type":"main","index":0}]]},"Is Valid Expense?":{"main":[[{"node":"Save Expense to Sheet","type":"main","index":0}],[{"node":"Reply Invalid","type":"main","index":0}]]},"Read All Expenses":{"main":[[{"node":"Prepare Data","type":"main","index":0}]]},"Save Expense to Sheet":{"main":[[{"node":"Reply Saved","type":"main","index":0}]]},"When chat message received":{"main":[[{"node":"Detect Intent","type":"main","index":0}]]}}},"lastUpdatedBy":1,"workflowInfo":{"nodeCount":27,"nodeTypes":{"n8n-nodes-base.if":{"count":1},"n8n-nodes-base.code":{"count":7},"n8n-nodes-base.switch":{"count":1},"n8n-nodes-base.stickyNote":{"count":12},"n8n-nodes-base.googleSheets":{"count":3},"@n8n/n8n-nodes-langchain.chainLlm":{"count":1},"@n8n/n8n-nodes-langchain.chatTrigger":{"count":1},"@n8n/n8n-nodes-langchain.lmChatAnthropic":{"count":1}}},"status":"published","readyToDemo":null,"user":{"name":"Nirav Gajera","username":"niravgajera","bio":"Full-stack Developer | PHP | Laravel | Vue.js | CodeIgniter | Nova | AWS | AI Automation ","verified":true,"links":["https://www.linkedin.com/in/nirav-gajera1/"],"avatar":"https://gravatar.com/avatar/7157fd8f0a74088248a6780d0536d9062ebdfb7cf7ed879b5ccee0b23403095d?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":20,"icon":"fa:map-signs","name":"n8n-nodes-base.if","codex":{"data":{"alias":["Router","Filter","Condition","Logic","Boolean","Branch"],"details":"The IF node can be used to implement binary conditional logic in your workflow. You can set up one-to-many conditions to evaluate each item of data being inputted into the node. That data will either evaluate to TRUE or FALSE and route out of the node accordingly.\n\nThis node has multiple types of conditions: Bool, String, Number, and Date & Time.","resources":{"generic":[{"url":"https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/","icon":"🏭","label":"Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"},{"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/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/create-a-toxic-language-detector-for-telegram/","icon":"🤬","label":"Create a toxic language detector for Telegram in 4 step"},{"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-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/","icon":"⚙️","label":"Automate your data processing pipeline in 9 steps"},{"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/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"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/automation-for-maintainers-of-open-source-projects/","icon":"🏷️","label":"How to automatically manage contributions to open-source projects"},{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"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-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/","icon":"🎖","label":"Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"},{"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/core-nodes/n8n-nodes-base.if/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Flow"]}}},"group":"[\"transform\"]","defaults":{"name":"If","color":"#408000"},"iconData":{"icon":"map-signs","type":"icon"},"displayName":"If","typeVersion":2,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"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":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":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":1123,"icon":"fa:link","name":"@n8n/n8n-nodes-langchain.chainLlm","codex":{"data":{"alias":["LangChain"],"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm/"}]},"categories":["AI","Langchain"],"subcategories":{"AI":["Chains","Root Nodes"]}}},"group":"[\"transform\"]","defaults":{"name":"Basic LLM Chain","color":"#909298"},"iconData":{"icon":"link","type":"icon"},"displayName":"Basic LLM Chain","typeVersion":2,"nodeCategories":[{"id":25,"name":"AI"},{"id":26,"name":"Langchain"}]},{"id":1145,"icon":"file:anthropic.svg","name":"@n8n/n8n-nodes-langchain.lmChatAnthropic","codex":{"data":{"alias":["claude","sonnet","opus"],"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmchatanthropic/"}]},"categories":["AI","Langchain"],"subcategories":{"AI":["Language Models","Root Nodes"],"Language Models":["Chat Models (Recommended)"]}}},"group":"[\"transform\"]","defaults":{"name":"Anthropic Chat Model"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NiIgaGVpZ2h0PSIzMiIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzdEN0Q4NyIgZD0iTTMyLjczIDBoLTYuOTQ1TDM4LjQ1IDMyaDYuOTQ1ek0xMi42NjUgMCAwIDMyaDcuMDgybDIuNTktNi43MmgxMy4yNWwyLjU5IDYuNzJoNy4wODJMMTkuOTI5IDB6bS0uNzAyIDE5LjMzNyA0LjMzNC0xMS4yNDYgNC4zMzQgMTEuMjQ2eiIvPjwvc3ZnPg=="},"displayName":"Anthropic Chat Model","typeVersion":1,"nodeCategories":[{"id":25,"name":"AI"},{"id":26,"name":"Langchain"}]},{"id":1247,"icon":"fa:comments","name":"@n8n/n8n-nodes-langchain.chatTrigger","codex":{"data":{"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-langchain.chattrigger/"}]},"categories":["Core Nodes","Langchain"]}},"group":"[\"trigger\"]","defaults":{"name":"When chat message received"},"iconData":{"icon":"comments","type":"icon"},"displayName":"Chat Trigger","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"},{"id":26,"name":"Langchain"}]}],"categories":[{"id":43,"name":"Personal Productivity"},{"id":47,"name":"AI Chatbot"}],"image":[]}}