{"id":"gvtBkOKVVvbQCAFkztIv7","meta":{"instanceId":"7e8b6f52685b44af41a4db7413ae11ea45e1bca0d97fac82a65f08260302d00e","templateCredsSetupCompleted":true},"name":"Bank Statement Analyzer & Budget Tracker","tags":[],"nodes":[{"id":"881d092b-c4f8-46c2-aec3-1a7fdd012d47","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[704,80],"parameters":{"width":300,"height":388,"content":"## 🏦 Bank Statement Analyzer\n\n**What this workflow does:**\n1. Monitors Gmail for bank statements\n2. Extracts all transactions\n3. Categorizes spending\n4. Calculates savings rate\n5. Identifies large transactions\n6. Sends monthly summary\n\n**Perfect for:**\n- Personal finance tracking\n- Small business bookkeeping\n- Budget analysis"},"typeVersion":1},{"id":"c2351f31-8359-405b-874e-815c9f87d98d","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[1520,-112],"parameters":{"width":344,"height":296,"content":"## 📊 Spending Categories\n\n- Income\n- Utilities\n- Groceries\n- Dining\n- Shopping\n- Transport\n- Subscriptions\n- Healthcare\n- Entertainment\n- Transfers"},"typeVersion":1},{"id":"d90379fe-717d-458e-90da-77fda205fc61","name":"Gmail Trigger","type":"n8n-nodes-base.gmailTrigger","notes":"Monitor for bank statement emails","position":[1008,224],"parameters":{"filters":{"includeSpamTrash":false},"pollTimes":{"item":[{"mode":"everyMinute"}]}},"credentials":{"gmailOAuth2":{"id":"GFPq3crPajyoq1jG","name":"Gmail account"}},"typeVersion":1},{"id":"63171083-8064-420a-a76c-87ec0554580f","name":"PDF Vector - Extract Statement","type":"n8n-nodes-pdfvector.pdfVector","position":[1392,224],"parameters":{"prompt":"Extract all transactions from this bank statement including date, description, amount (positive for deposits, negative for withdrawals), running balance, and categorize each transaction.\n\nCategory rules:\n- Travel: airlines (DELTA, UNITED, AMERICAN), hotels (HILTON, MARRIOTT, HYATT), airbnb, booking.com\n- Transport: UBER, LYFT, taxi, gas stations (SHELL, CHEVRON, BP), parking\n- Subscriptions: NETFLIX, SPOTIFY, ADOBE, APPLE.COM, recurring monthly services\n- Groceries: WHOLE FOODS, TRADER JOE'S, COSTCO, PUBLIX, supermarkets\n- Dining: restaurants, STARBUCKS, MCDONALD'S, DOORDASH, UBER EATS\n- Shopping: AMAZON, TARGET, BEST BUY, WALMART, retail stores\n- Utilities: electric, gas, water, internet, phone (AT&T, COMCAST, VERIZON)\n- Healthcare: pharmacy (CVS, WALGREENS), doctors, gym (PLANET FITNESS)\n- Entertainment: movies (AMC), concerts, streaming, games\n- Other: anything that doesn't fit above","schema":"{\"type\":\"object\",\"properties\":{\"accountNumber\":{\"type\":\"string\"},\"statementPeriod\":{\"type\":\"object\",\"properties\":{\"startDate\":{\"type\":\"string\"},\"endDate\":{\"type\":\"string\"}}},\"openingBalance\":{\"type\":\"number\"},\"closingBalance\":{\"type\":\"number\"},\"totalDeposits\":{\"type\":\"number\"},\"totalWithdrawals\":{\"type\":\"number\"},\"transactions\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"date\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"amount\":{\"type\":\"number\"},\"category\":{\"type\":\"string\",\"enum\":[\"Income\",\"Utilities\",\"Groceries\",\"Dining\",\"Shopping\",\"Transport\",\"Travel\",\"Subscriptions\",\"Healthcare\",\"Entertainment\",\"Transfer\",\"Other\"]},\"balance\":{\"type\":\"number\"}}}}},\"required\":[\"closingBalance\",\"transactions\"],\"additionalProperties\":false}","resource":"document","inputType":"file","operation":"extract","binaryPropertyName":"attachment_0"},"credentials":{"pdfVectorApi":{"id":"vgcDBWZ0RFsP3P1T","name":"PDF Vector account"}},"typeVersion":1},{"id":"4c5423e8-0f2a-474a-bba5-a87a3e990041","name":"Analyze Spending","type":"n8n-nodes-base.code","position":[1584,224],"parameters":{"jsCode":"const statement = $input.first().json.data;\n\n// Calculate spending by category\nconst categoryTotals = {};\nlet totalSpending = 0;\nlet totalIncome = 0;\n\nstatement.transactions.forEach(tx => {\n  if (tx.amount < 0) {\n    totalSpending += Math.abs(tx.amount);\n    categoryTotals[tx.category] = (categoryTotals[tx.category] || 0) + Math.abs(tx.amount);\n  } else {\n    totalIncome += tx.amount;\n  }\n});\n\n// Format category breakdown\nconst categoryBreakdown = Object.entries(categoryTotals)\n  .sort((a, b) => b[1] - a[1])\n  .map(([cat, amount]) => `${cat}: $${amount.toFixed(2)} (${((amount/totalSpending)*100).toFixed(1)}%)`)\n  .join('\\n');\n\n// Find unusual transactions (over $500)\nconst largeTransactions = statement.transactions\n  .filter(tx => Math.abs(tx.amount) > 500)\n  .map(tx => `${tx.date}: ${tx.description} - $${tx.amount}`)\n  .join('\\n');\n\nreturn [{\n  json: {\n    ...statement,\n    totalSpending: totalSpending,\n    totalIncome: totalIncome,\n    savingsRate: totalIncome > 0 ? ((totalIncome - totalSpending) / totalIncome * 100).toFixed(1) : 0,\n    categoryTotals: categoryTotals,\n    categoryBreakdown: categoryBreakdown,\n    largeTransactions: largeTransactions || 'None',\n    transactionCount: statement.transactions.length,\n    processedAt: new Date().toISOString()\n  }\n}];"},"typeVersion":2},{"id":"111872d6-305e-48ac-a2a6-f120a406479f","name":"Log Monthly Summary","type":"n8n-nodes-base.googleSheets","position":[1792,224],"parameters":{"columns":{"value":{"Period End":"={{ $json.statementPeriod.endDate }}","Period Start":"={{ $json.statementPeriod.startDate }}","Total Income":"={{ $json.totalIncome }}","Processed Date":"={{ $json.processedAt.split('T')[0] }}","Savings Rate %":"={{ $json.savingsRate }}","Total Spending":"={{ $json.totalSpending }}","Closing Balance":"={{ $json.closingBalance }}","Opening Balance":"={{ $json.openingBalance }}","Transaction Count":"={{ $json.transactionCount }}"},"schema":[{"id":"Period Start","type":"string","display":true,"required":false,"displayName":"Period Start","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Period End","type":"string","display":true,"required":false,"displayName":"Period End","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Opening Balance","type":"string","display":true,"required":false,"displayName":"Opening Balance","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Closing Balance","type":"string","display":true,"required":false,"displayName":"Closing Balance","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Total Income","type":"string","display":true,"required":false,"displayName":"Total Income","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Total Spending","type":"string","display":true,"required":false,"displayName":"Total Spending","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Savings Rate %","type":"string","display":true,"required":false,"displayName":"Savings Rate %","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Transaction Count","type":"string","display":true,"required":false,"displayName":"Transaction Count","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Processed Date","type":"string","display":true,"required":false,"displayName":"Processed Date","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/18Jpu_lX1i9zkHo_TpS9lGYfvtRY7sHFo1qRbttj58YI/edit#gid=0","cachedResultName":"Trang tính1"},"documentId":{"__rl":true,"mode":"list","value":"18Jpu_lX1i9zkHo_TpS9lGYfvtRY7sHFo1qRbttj58YI","cachedResultUrl":"https://docs.google.com/spreadsheets/d/18Jpu_lX1i9zkHo_TpS9lGYfvtRY7sHFo1qRbttj58YI/edit?usp=drivesdk","cachedResultName":"Test-workflow"}},"credentials":{"googleSheetsOAuth2Api":{"id":"TIOoAEnXlfmG3Fk3","name":"Google Sheets account"}},"typeVersion":4.4},{"id":"3e8d146a-5598-42a8-a2f3-8b741167155e","name":"Send Analysis Report","type":"n8n-nodes-base.slack","position":[2000,224],"webhookId":"4995d78e-216e-46f5-81cf-a0b530cc61d2","parameters":{"text":"=📊 *Monthly Bank Statement Analysis*\n\n*Period:* {{ $('Analyze Spending').item.json.statementPeriod.startDate }} - {{ $('Analyze Spending').item.json.statementPeriod.endDate }}\n\n💰 *Summary*\n• Income: ${{ $('Analyze Spending').item.json.totalIncome.toFixed(2) }}\n• Spending: ${{ $('Analyze Spending').item.json.totalSpending.toFixed(2) }}\n• Savings Rate: {{ $('Analyze Spending').item.json.savingsRate }}%\n\n📈 *Spending by Category*\n{{ $('Analyze Spending').item.json.categoryBreakdown }}\n\n⚠️ *Large Transactions (>$500)*\n{{ $('Analyze Spending').item.json.largeTransactions }}","select":"channel","channelId":{"__rl":true,"mode":"list","value":"C0A0JMC9VED","cachedResultName":"all-workflow"},"otherOptions":{},"authentication":"oAuth2"},"credentials":{"slackOAuth2Api":{"id":"j091G2xIjKiVhm6H","name":"Slack account"}},"typeVersion":2.1},{"id":"05d46ff9-c8a2-4e6e-862c-a5540b6d5ad9","name":"Get a message","type":"n8n-nodes-base.gmail","position":[1184,224],"webhookId":"7dac1255-c0c1-4749-b885-e40c3442ca88","parameters":{"simple":false,"options":{"downloadAttachments":true},"messageId":"={{ $json.id }}","operation":"get"},"credentials":{"gmailOAuth2":{"id":"GFPq3crPajyoq1jG","name":"Gmail account"}},"typeVersion":2.2}],"active":false,"pinData":{},"settings":{"availableInMCP":false,"executionOrder":"v1"},"versionId":"5e51d6d2-1806-48d4-9e3d-a90454914129","connections":{"Get a message":{"main":[[{"node":"PDF Vector - Extract Statement","type":"main","index":0}]]},"Gmail Trigger":{"main":[[{"node":"Get a message","type":"main","index":0}]]},"Analyze Spending":{"main":[[{"node":"Log Monthly Summary","type":"main","index":0}]]},"Log Monthly Summary":{"main":[[{"node":"Send Analysis Report","type":"main","index":0}]]},"PDF Vector - Extract Statement":{"main":[[{"node":"Analyze Spending","type":"main","index":0}]]}}}