The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"nodes": [
{
"id": "d7430a67-f736-411e-8f19-2af80ede461c",
"name": "Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"maxTries": 2,
"position": [
2528,
-240
],
"parameters": {
"text": "={{ $('Telegram Trigger').item.json.message.text }}{{ $json.text }}",
"options": {
"maxIterations": 50,
"systemMessage": "=You are an expert personal finance assistant specializing in expense tracking and financial awareness. Your primary goal is to help users maintain accurate financial records while providing intelligent insights about their spending patterns.\nSystem Variables\n\nCurrent Date: {{ $now.toFormat('dd/MM/yyyy') }}\nBase Currency: USD (United States Dollar)\nDate Format: dd/MM/yyyy\n\nPrimary Functions\n1. Expense Processing & Categorization\nWhen a user reports an expense, follow this structured approach:\nRequired Information to Extract:\n\nExpense Date: Use current date unless user specifies otherwise\nExpense Amount (USD): Convert to USD if needed using Exchange Rate tool\nExpense Description: Create clear, descriptive text based on expense details (Very important note : please make sure to not add that money is converted from another currency in descreption.)\nExpense Category: Auto-assign from predefined categories (see Category Reference)\n\nParse the expense from user input\nCurrency conversion (if needed):\n\nUse ISO 4217 currency codes (USD for $, EUR for \u20ac, etc.)\nCall Exchange_Rate tool to get current USD conversion rate\nUse Calculator tool to compute final USD amount\n\nCategory Reference System\nAuto-assign expenses to these categories with their emojis:\nCategoryEmojiExamplesFood & Drink\ud83c\udf54Restaurants, groceries, coffee, snacksTransport\ud83d\ude97Fuel, taxi, bus, parking, car maintenanceHousing & Bills\ud83c\udfe0Rent, utilities, internet, phone billsSubscriptions\ud83d\udce6Netflix, Spotify, software, membershipsEntertainment\ud83c\udfacMovies, games, concerts, hobbiesHealth & Fitness\ud83c\udfe5Doctor visits, pharmacy, gym, supplementsShopping\ud83d\udecd\ufe0fClothing, electronics, household itemsTravel\u2708\ufe0fFlights, hotels, vacation expensesEducation\ud83c\udf93Courses, books, training, workshopsPersonal Care\ud83d\udc87\u200d\u2640\ufe0fHaircuts, cosmetics, spa, groomingMiscellaneous\ud83d\uddc2\ufe0fGifts, donations, uncategorized items\nResponse Formats\n\nAuto-categorize using the given category Reference system \nGenerate descriptive text that clearly explains the expense\nValidate completeness - if any required field is unclear, ask for clarification\nExpense Category Must be formatted like this before inserting : [Category Emoji] [Category Name]\nAppend Expenses to Google Sheet using the Add_Expenses_Tool tool - Each Expense in a new row dont update the old ones - Use Read_Rows_Tool before Each append to see where you gonna add new rows to make sure not deleting old ones!\nConfirm addition with formatted summary\n\n2. Financial Reporting & Alerts\nHandle requests for spending summaries with intelligent alerting:\n\nDaily Spending Queries:\n\nUse Total_Spent_Tool tool to fetch daily total\nIf daily total \u2264 100 USD: Show standard total\nIf daily total > 100 USD: Add alert message \"\u26a0\ufe0f Warning: Daily expense limit exceeded.\"\n\nWeekly/Monthly Spending Queries:\n\nUse Total_Spent_Tool tool to fetch respective totals\nShow clean total without additional alerts\nFormat: \"Total spent per [Week/Month]: [Amount] USD\"\n\nBalance Inquiries:\n\nUse Balance_Tool checker tool\nProvide current balance with contextual insights if patterns emerge\n\nExpense Analysis & Filtering:\nHandle detailed expense breakdowns and filtering requests:\nCategory-Based Analysis:\n\nUse Expenses_Tool tool to fetch all expenses from specific categories\nFilter and display expenses by category (Food & Drink, Transport, etc.)\nCalculate category totals and provide spending insights\n\nDate Range Analysis:\n\nUse Expenses_Tool tool to fetch expenses within specified date ranges\nSupport various date formats: specific dates, date ranges, months, weeks\nExamples: \"last week\", \"January 2024\", \"01/01/2024 to 15/01/2024\"\n\nCombined Filtering:\n\nAllow filtering by both category AND date range simultaneously\nExample: \"Show all Food & Drink expenses from last month\"\n\n\nExpense Confirmation Template:\nYour Expense has been added successfully \u2705\n\n\ud83d\udcc5 Expense Date: [dd/MM/yyyy]\n\ud83d\udcdd Expense Description: [Clear description]\n\ud83d\udcb0 Expense Amount (USD): [X.XX USD]\n\ud83d\udcc2 Expense Category: [Category Emoji] [Category Name]\n\nSpending Summary Template:\n\ud83d\udcb8 **Spending Summary**\n\ud83d\udcca Total spent [today/this week/this month]: **[Amount] USD**\n[Alert message if applicable]\n\nBalance Report Template:\n\ud83d\udcb3 **Current Balance**\nAvailable: **[Amount] USD**\n[Additional insights if relevant]\n\nExpense Analysis Template:\n\ud83d\udcca **Expense Analysis**\n\ud83d\udd0d Filter: [Category/Date Range/Both]\n\ud83d\udcc8 Total: **[Amount] USD**\n\ud83d\udccb **Breakdown:**\n- [Date] - [Description] - [Amount] USD\n- [Date] - [Description] - [Amount] USD\n[Continue for all matching expenses]\n\n\ud83d\udca1 **Insights:** [Brief analysis of spending patterns if applicable]\nOperational Guidelines\nExpense Analysis & Filtering:\n\nCategory Filtering: Accept category names with or without emojis, case-insensitive\nDate Parsing: Understand various date formats and natural language:\n\nSpecific dates: \"15/01/2024\", \"January 15, 2024\"\nRanges: \"01/01/2024 to 31/01/2024\", \"last week\", \"this month\"\nRelative terms: \"yesterday\", \"last 7 days\", \"past month\"\n\n\nData Sorting: Present filtered results chronologically (newest first)\nSummary Statistics: Always include totals and count of filtered expenses\nSmart Insights: Identify patterns like highest spending days or frequent merchants\n\nCurrency Handling:\n\nAlways convert foreign currencies to USD using current exchange rates\nUse proper ISO 4217 codes for API calls\nRound final amounts to 2 decimal places\n\nData Validation:\n\nVerify all expense entries are successfully added to the sheet before confirming\nDouble-check calculations when currency conversion is involved\nEnsure category assignment is logical and consistent\n\nUser Experience:\n\nAsk for clarification only when essential information is genuinely missing\nProvide helpful suggestions when categorizing ambiguous expenses\nMaintain a friendly, supportive tone while being financially responsible\n\nError Handling:\n\nIf tools fail, inform user clearly and suggest alternatives\nIf unclear expense descriptions, ask specific clarifying questions\nIf currency conversion fails, request amount in USD directly\n\nRemember: Your role is to be helpful, accurate, and supportive in managing the user's financial tracking needs while encouraging healthy spending awareness."
},
"promptType": "define"
},
"retryOnFail": true,
"typeVersion": 1.7
},
{
"id": "dcf32051-0a46-4800-998e-ee29da8b1a63",
"name": "Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"position": [
256,
-352
],
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"typeVersion": 1.2
},
{
"id": "c972c32e-47b2-4666-ad83-156be726b6b8",
"name": "MCP Client",
"type": "@n8n/n8n-nodes-langchain.mcpClientTool",
"position": [
2736,
160
],
"parameters": {
"sseEndpoint": "your-sse-endpoint"
},
"typeVersion": 1
},
{
"id": "50722293-ea6d-4975-a8f7-692546264a47",
"name": "MCP Server Trigger",
"type": "@n8n/n8n-nodes-langchain.mcpTrigger",
"position": [
1520,
-976
],
"parameters": {
"path": "path"
},
"typeVersion": 1
},
{
"id": "289cdc37-cd08-4bb1-b957-4236770a2734",
"name": "Calculator",
"type": "@n8n/n8n-nodes-langchain.toolCalculator",
"position": [
1216,
-832
],
"parameters": {},
"typeVersion": 1
},
{
"id": "cb952c7a-053c-4c75-b032-514160347571",
"name": "Total_Spent_Tool",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
1600,
-768
],
"parameters": {
"options": {
"dataLocationOnSheet": {
"values": {
"range": "C1:C10",
"rangeDefinition": "specifyRangeA1"
}
}
},
"sheetName": {
"__rl": true,
"mode": "id",
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Sheet', ``, 'string') }}"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1W6XWZmhVvofPABn6CR-4q0tlj05dFidkFGWD1vf_9xI",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1W6XWZmhVvofPABn6CR-4q0tlj05dFidkFGWD1vf_9xI/edit?usp=drivesdk",
"cachedResultName": "Telegram AI Expense Assistant with Multi-Currency Support "
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "cb8b4fac-7459-4ed6-a9b2-b9d3d59174cc",
"name": "Balance_Tool",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
1728,
-784
],
"parameters": {
"options": {
"dataLocationOnSheet": {
"values": {
"range": "A1:A7",
"rangeDefinition": "specifyRangeA1"
}
}
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1850220256,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1W6XWZmhVvofPABn6CR-4q0tlj05dFidkFGWD1vf_9xI/edit#gid=1850220256",
"cachedResultName": "Balance&Total_Spent"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1W6XWZmhVvofPABn6CR-4q0tlj05dFidkFGWD1vf_9xI",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1W6XWZmhVvofPABn6CR-4q0tlj05dFidkFGWD1vf_9xI/edit?usp=drivesdk",
"cachedResultName": "Telegram AI Expense Assistant with Multi-Currency Support "
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "92916bf0-6e41-478a-b109-eb2ea9091531",
"name": "Expenses_Tool",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
1856,
-800
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1W6XWZmhVvofPABn6CR-4q0tlj05dFidkFGWD1vf_9xI/edit#gid=0",
"cachedResultName": "Expenses"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1W6XWZmhVvofPABn6CR-4q0tlj05dFidkFGWD1vf_9xI",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1W6XWZmhVvofPABn6CR-4q0tlj05dFidkFGWD1vf_9xI/edit?usp=drivesdk",
"cachedResultName": "Telegram AI Expense Assistant with Multi-Currency Support "
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.6
},
{
"id": "1b4becbb-d4b7-4a52-bcad-c9b31eeb18ae",
"name": "Exchange_Rate",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
1984,
-816
],
"parameters": {
"url": "=https://v6.exchangerate-api.com/v6/your_api_key/pair/USD/{{$fromAI('exchange_currency')}}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "ca479dc7-6651-4a25-b019-1525f22b42db",
"name": "Add_Expenses_Tool",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
1328,
-800
],
"parameters": {
"columns": {
"value": {
"Expense Date": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Expense_Date', ``, 'string') }}",
"Expense Category": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Expense_Category', ``, 'string') }}",
"Expense Description": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Expense_Description', ``, 'string') }}",
"Expense Amount (USD)": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Expense_Amount__USD_', ``, 'string') }}"
},
"schema": [
{
"id": "Expense Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Expense Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Expense Description",
"type": "string",
"display": true,
"required": false,
"displayName": "Expense Description",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Expense Amount (USD)",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Expense Amount (USD)",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Expense Category",
"type": "string",
"display": true,
"required": false,
"displayName": "Expense Category",
"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/1pnoXQ38DkXtdr4OuSivwv4vWS_XG8aqh8v0NzzhC4F0/edit#gid=0",
"cachedResultName": "Expenses"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1W6XWZmhVvofPABn6CR-4q0tlj05dFidkFGWD1vf_9xI",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1W6XWZmhVvofPABn6CR-4q0tlj05dFidkFGWD1vf_9xI/edit?usp=drivesdk",
"cachedResultName": "Telegram AI Expense Assistant with Multi-Currency Support "
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "708fc38e-4f99-4caa-b70e-9d1788a9a9d4",
"name": "Read_Rows_Tool",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
1456,
-784
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1W6XWZmhVvofPABn6CR-4q0tlj05dFidkFGWD1vf_9xI/edit#gid=0",
"cachedResultName": "Expenses"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1W6XWZmhVvofPABn6CR-4q0tlj05dFidkFGWD1vf_9xI",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1W6XWZmhVvofPABn6CR-4q0tlj05dFidkFGWD1vf_9xI/edit?usp=drivesdk",
"cachedResultName": "Telegram AI Expense Assistant with Multi-Currency Support "
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.6
},
{
"id": "fa5a0e77-4ed7-43cb-85d5-0e78b4b16429",
"name": "Rename Fields",
"type": "n8n-nodes-base.set",
"position": [
1072,
-352
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "cdfce35f-fc3d-4762-8cdd-8d1dc0646064",
"name": "Prompt",
"type": "string",
"value": "={{ $json.text }}{{ $('Telegram Trigger').item.json.message.text }}{{ $json.content.parts[0].text }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "515f83fb-a7cf-46a8-8125-b50745414318",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-16,
-608
],
"parameters": {
"width": 3184,
"height": 960,
"content": ""
},
"typeVersion": 1
},
{
"id": "f6dbcc7d-8c6c-42a3-8a64-66473f88b95b",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1168,
-1024
],
"parameters": {
"color": 3,
"width": 960,
"height": 416,
"content": ""
},
"typeVersion": 1
},
{
"id": "e3b086db-e833-40ae-b474-e3235f35a837",
"name": "Get Voice File from Telegram",
"type": "n8n-nodes-base.telegram",
"position": [
672,
-256
],
"parameters": {
"fileId": "={{ $json.message.voice.file_id }}",
"resource": "file",
"additionalFields": {}
},
"typeVersion": 1.2
},
{
"id": "400a7dfb-098b-4740-abdf-6a59b5258c18",
"name": "Convert Voice to Text (ElevenLabs)",
"type": "n8n-nodes-base.httpRequest",
"maxTries": 2,
"position": [
832,
-256
],
"parameters": {
"url": "https://api.elevenlabs.io/v1/speech-to-text",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "model_id",
"value": "scribe_v1"
},
{
"name": "file",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
}
]
},
"genericAuthType": "httpHeaderAuth"
},
"retryOnFail": true,
"typeVersion": 4.2
},
{
"id": "bc60dfa7-cea3-4b17-97b3-7e4d7ea71e23",
"name": "Route Input by Message Type",
"type": "n8n-nodes-base.switch",
"position": [
448,
-368
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "ee163b36-d8ec-4ffb-b302-5360099a424b",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.message.toJsonString() }}",
"rightValue": "text"
}
]
}
},
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0c4fcbc4-c2ab-414b-b666-30c6cf9a54b3",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.message.toJsonString() }}",
"rightValue": "audio"
}
]
}
},
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "3d1b0bdf-552f-4d5c-ab1d-6d6dbb85132e",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.message.document.mime_type }}",
"rightValue": "image"
}
]
}
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "d2c28ec4-47e9-40ca-b6ed-4f58ad753b01",
"name": "Download Receipt Image",
"type": "n8n-nodes-base.telegram",
"position": [
672,
-64
],
"parameters": {
"fileId": "={{ $('Telegram Trigger').item.json.message.document.thumbnail.file_id }}",
"resource": "file",
"additionalFields": {}
},
"typeVersion": 1.2
},
{
"id": "ed2d4b12-2d10-4b4b-b224-fd8da3f3c64b",
"name": "Extract Receipt Data",
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"position": [
864,
-64
],
"parameters": {
"text": "=You are an intelligent expense-tracking assistant. Your task is to analyze the provided receipt image and extract two specific pieces of information:\\n\\n1. **Expense Amount**: The final, total amount paid, including any taxes or tips. Always include the currency symbol (e.g., $, \u20ac, \u00a3).\\n2. **Expense Description**: A brief, overall description of the expense. If there are many small items, create a general description (e.g., \\\"Grocery shopping,\\\" \\\"Dinner with friends,\\\" \\\"Office supplies\\\").\\n\\nReturn the result in the following strict format:\\namount: [extracted amount with symbol], description: [generated description]\\n\\nHere are some examples of how to format the output:\\n\\n**Example 1:**\\n(If you were to provide an image of a gym receipt)\\namount: 20$, description: gym subscription\\n\\n**Example 2:**\\n(If you were to provide an image of a supermarket receipt with many items)\\namount: $112.54, description: Grocery shopping\\n\\n**Example 3:**\\n(If you were to provide an image of a simple coffee shop receipt)\\namount: \u20ac4.50, description: Coffee purchase\\n\\nNow, analyze the following receipt and provide the output in the specified format.",
"modelId": {
"__rl": true,
"mode": "list",
"value": "models/gemini-2.5-flash",
"cachedResultName": "models/gemini-2.5-flash"
},
"options": {},
"resource": "image",
"inputType": "binary",
"operation": "analyze"
},
"typeVersion": 1
},
{
"id": "f4b1a3bb-6f1c-44c4-80cb-9eb9105f51cf",
"name": "Classify Message Intent",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
1328,
-272
],
"parameters": {
"text": "={{ $json.Prompt }}",
"messages": {
"messageValues": [
{
"message": "=Determine whether the user's message is an expense entry or another type of message.\n\nCriteria:\n\nIf the message includes details about spending money, such as amounts, dates, or descriptions of purchases, classify it as expenses.\n\nIf the message is a greeting, a question about balances, summaries, or any other non-expense-related content, classify it as other.\n\nOutput:\nRespond with a single word: either expenses or other."
}
]
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.6
},
{
"id": "5e9ae67c-b22c-40d9-8873-dac4ca153af4",
"name": "Route to Expense or Query Processing",
"type": "n8n-nodes-base.if",
"position": [
1728,
-272
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "20a7cc02-6345-4ee7-9187-26bf4c826a41",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.text }}",
"rightValue": "other"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "68606aa4-a48d-41b1-8165-65254bdb256c",
"name": "Parse and Split Multiple Expenses",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
2000,
-240
],
"parameters": {
"text": "={{ $('Rename Fields').item.json.Prompt }}",
"batching": {},
"messages": {
"messageValues": [
{
"message": "=You are an 'Expense Splitter' assistant. Your single task is to parse a free-form text block, process each expense, and print the results according to a strict line-by-line format.\nInstructions:\nSplit: Separate the input text into individual expense items. Look for separators like newlines, commas, semicolons, or words like \"and\".\nNormalize Each Item:\nConvert Numbers: Change number words into digits (e.g., \"twenty five\" becomes \"25\").\nEnsure Currency Symbol: Add a dollar sign $ at the end of the amount if one is not present.\nCapitalize: Capitalize the description text appropriately (e.g., \"gym subscription\" becomes \"Gym Subscription\").\nFormat Output:\nEach processed expense must be on its own new line.\nEvery line must begin with the literal text \"expense\": \" followed by the quoted, processed expense string.\nCrucially, do not use commas between lines or wrap the final output in brackets [] or braces {}. The output must be a simple list of lines.\nExample 1:\nInput: Gym subscription twenty five dollars and a coffee for 5 dollars\nOutput:\n\"expense\": \"Gym Subscription 25$\"\n\"expense\": \"Coffee 5$\"\nExample 2:\nInput: Groceries 150$; gas for the car sixty dollars\nOutput:\n\"expense\": \"Groceries 150$\"\n\"expense\": \"Gas For The Car 60$\"\nExample 3 (Single Item):\nInput: monthly software license 15\nOutput:\n\"expense\": \"Monthly Software License 15$\""
}
]
},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "b04cd27b-3359-4204-a07c-ce426bcc7945",
"name": "Intent Classification Model",
"type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
"position": [
1312,
-112
],
"parameters": {
"model": "gpt-4.1",
"options": {}
},
"typeVersion": 1
},
{
"id": "fb977fc8-0e0c-4e62-9c63-3648f9fbabe8",
"name": "Expense Parsing Model",
"type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
"position": [
2000,
-96
],
"parameters": {
"model": "gpt-4.1",
"options": {}
},
"typeVersion": 1
},
{
"id": "3527a7d8-798f-4243-bacd-2b88ccf870d4",
"name": "Main Financial Assistant",
"type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
"position": [
2496,
-96
],
"parameters": {
"model": "gpt-4.1",
"options": {}
},
"typeVersion": 1
},
{
"id": "79325630-4d76-4795-9a13-3094bd5ea181",
"name": "Send Message",
"type": "n8n-nodes-base.telegram",
"position": [
2976,
-240
],
"parameters": {
"text": "={{ $json.output }}",
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"additionalFields": {
"appendAttribution": false
}
},
"typeVersion": 1.2
},
{
"id": "ee4e0426-1f2f-4ee6-94d8-82f5a8a2e0b7",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-544,
-1024
],
"parameters": {
"color": 5,
"width": 752,
"height": 1376,
"content": "## \ud83e\udd16 Your AI Financial Assistant is Here!\n### This n8n template transforms a Telegram bot into a powerful, multi-modal personal finance assistant. It can track your expenses from text, voice notes, and even receipt images, providing intelligent summaries and alerts to help you stay on top of your finances.\n\nUse it to effortlessly log daily purchases, get quick spending summaries, check your budget, and analyze your financial habits, all from the convenience of a Telegram chat.\n\n### How it Works\n* **Multi-Input Trigger:** The workflow starts when you send a message, voice note, or receipt image to your Telegram bot.\n* **Smart Routing:** An initial router detects the message type. Voice notes are transcribed to text using **ElevenLabs**, while receipt images are analyzed by **Google Gemini** to extract the total amount and a description.\n* **Intent Classification:** The user's message (now in text format) is analyzed by a **GPT-4** model to determine its intent: is the user logging a new expense or asking a question (like for a balance or summary)?\n* **Dual Processing Paths:**\n * **Queries & Summaries:** If it's a question, the request is sent directly to the main AI Agent.\n * **Expense Logging:** If it's an expense, the message first goes through a specialized **GPT-4** parser that can split and format multiple expenses from a single message (e.g., \"coffee for 5 and a taxi for 15\").\n* **The AI Agent Core:** The heart of the workflow is a powerful **AI Agent** using **GPT-4**. It uses a detailed system prompt to understand its role and can access a set of tools to perform actions:\n * It uses **Google Sheets Tools** to add new expenses, read existing data, calculate totals, and check balances.\n * It uses an **Exchange Rate Tool** to fetch real-time currency conversion rates.\n * It uses a **Calculator Tool** for any necessary math.\n* **Final Response:** After using its tools to complete the request, the Agent crafts a formatted, user-friendly response and sends it back to you via Telegram.\n\n### How to Use\n* **Connect Your Accounts:** You will need to add your credentials for Telegram, Google Sheets, Azure OpenAI (for GPT-4 models), ElevenLabs, and the ExchangeRate-API.\n**Set Up Your Google Sheet**\nTo get started, create a new Google Sheet. For the workflow to connect properly, you must create two specific tabs (sheets) at the bottom with the exact names and columns listed below.\n 1- **Expenses Tab**\nThis is where all your logged expenses will appear. Create a tab named **`Expenses`** and set up the following columns in the first row:\n* `Expense Date`\n* `Expense Description`\n* `Expense Amount (USD)`\n* `Expense Category`\n2- **Balance & Total Spent Tab**\nThis sheet works as your automated dashboard for summaries and your current balance. Create a tab named **`Balance&Total_Spent`**.\nOn this sheet, you only need to do **one thing manually**: enter your starting balance. A good place for this is cell `B3`, next to a label like \"Balance\".\nThe other fields, like **`Current Balance`**, **`Total Spent by Day`**, **`Total Spent by Week`**, and **`Total Spent by Month`**, should be set up with formulas to calculate automatically. Once set, you won't need to touch them again as the workflow and the sheet will handle all the updates.\n* **Chat with Your Bot:** Start a conversation with your Telegram bot!\n * **Log Expenses:** Send messages like \"Lunch for 15 dollars\", \"Groceries 120 EUR and gas for 50$\", or forward a voice note saying \"My gym subscription was forty five dollars.\"\n * **Upload Receipts:** Send a picture of a receipt to have it automatically logged.\n * **Ask Questions:** Ask \"What's my balance?\", \"How much did I spend today?\", or \"Show me all my transport expenses for last month.\"\n\n### Requirements\n* A Telegram Bot Token.\n* Google Sheets API credentials.\n* Azure OpenAI credentials with access to a GPT-4 model.\n* ElevenLabs API Key for voice-to-text.\n* An API key from a service like ExchangeRate-API for currency conversion."
},
"typeVersion": 1
},
{
"id": "dc36b69d-b563-4518-9c20-42d5901db257",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
208,
-1024
],
"parameters": {
"color": 3,
"width": 960,
"height": 416,
"content": "### The MCP Server & Client: How the AI Uses Tools\n\nThis workflow uses a powerful **MCP** pattern to allow the main AI Agent to use tools that aren't directly connected to it.\n\n* #### **MCP Server Trigger**\n This node acts as a central **listening hub**. It waits for the AI Agent to decide it needs to use a specific tool (like the Calculator or a Google Sheets function). All the individual tools are connected *to* this server.\n\n* #### **MCP Client**\n This node is the **messenger** for the AI Agent. When the Agent needs a tool, the MCP Client takes that request (e.g., \"add 15 to 20\") and sends it over to the MCP Server. The server then finds the correct tool (the Calculator), gets the result (35), and sends it back to the Agent via the Client.\n\n**In short:** This setup keeps the main workflow clean. The Agent doesn't need a direct connection to every single tool. It just needs one connection to the MCP Client, which can then access any tool connected to the MCP Server.\n\n***"
},
"typeVersion": 1
},
{
"id": "ee141420-06ad-4baf-9dbe-6f4ddff6c6fb",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2672,
112
],
"parameters": {
"color": 3,
"width": 208,
"height": 176,
"content": "\n"
},
"typeVersion": 1
},
{
"id": "11c6b701-949f-4999-a192-bc05054dac7f",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1248,
-480
],
"parameters": {
"color": 4,
"width": 384,
"height": 512,
"content": "#### **1. Intent Classification**\n**Purpose:** To quickly figure out *what the user wants*.\n**Task:** Its only job is to read the user's message and classify it as either `expenses` (if they're logging a purchase) or `other` (if they're asking a question). This simple, fast check determines which path the workflow takes next.\n"
},
"typeVersion": 1
},
{
"id": "6d89246a-a74b-4f3b-b82d-f6cfc82749e5",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1920,
-480
],
"parameters": {
"color": 4,
"width": 384,
"height": 528,
"content": "#### **2. Expense Parsing **\n**Purpose:** To clean up and structure complex expense entries.\n**Task:** This model is a specialist in formatting. When a user enters multiple items in one message (e.g., \"Groceries 150 and gas 60\"), this model's job is to break it down into clean, separate lines that the main agent can easily process one by one."
},
"typeVersion": 1
},
{
"id": "40a89d91-27c3-41c4-9f7b-650d433bc9a0",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
2448,
-480
],
"parameters": {
"color": 4,
"width": 432,
"height": 528,
"content": " #### **3. Main Financial Assistant**\n **Purpose:** To be the core decision-making brain.\n **Task:** It receives the user's final, formatted request and uses reasoning to decide which tools to use, in what order, to get the right answer. It manages everything from calling the Google Sheets tools to performing currency conversions and finally crafting the detailed response that gets sent back to the user."
},
"typeVersion": 1
},
{
"id": "89679e84-9d12-4bf6-b284-457018461e48",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
2128,
-1024
],
"parameters": {
"color": 3,
"width": 1040,
"height": 416,
"content": "These are the individual tools the AI Agent can use to perform actions and answer your questions. Each one gives the AI a specific skill.\n\n#### **Google Sheets Tools:**\n* **`Add_Expenses_Tool`**: The primary tool for logging new purchases. It takes the date, description, amount, and category from the AI and appends them as a new row in your \"Expenses\" sheet.\n* **`Read_Rows_Tool`**: A safeguard tool. Before adding a new expense, the AI uses this to check the sheet's current state. This helps it know where the next empty row is, ensuring it never overwrites existing data.\n* **`Total_Spent_Tool`**: The tool for calculating summaries. When you ask, \"How much did I spend today?\", the AI uses this tool to read the \"Balance&Total\\_Spent\" sheet, which contains pre-calculated formulas for daily, weekly, and monthly totals.\n* **`Balance_Tool`**: Used to answer \"What's my balance?\". It reads a specific cell in your sheet where your current available balance is stored.\n* **`Expenses_Tool`**: The most powerful query tool. It can fetch and filter rows from your \"Expenses\" sheet based on criteria the AI provides, such as a date range (\"last month\") or a specific category (\"Food & Drink\").\n\n#### **Utility Tools:**\n* **`Exchange_Rate`**: This tool makes an HTTP request to an external API to get the latest currency conversion rate. When you log an expense in a currency other than USD, the AI uses this tool to find the correct rate before using the Calculator.\n* **`Calculator`**: A simple but essential tool for performing mathematical calculations. The AI uses it primarily to convert expenses from other currencies into USD based on the rate provided by the `Exchange_Rate` tool."
},
"typeVersion": 1
}
],
"connections": {
"Agent": {
"main": [
[
{
"node": "Send Message",
"type": "main",
"index": 0
}
]
]
},
"Calculator": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"MCP Client": {
"ai_tool": [
[
{
"node": "Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Balance_Tool": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"Exchange_Rate": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"Expenses_Tool": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"Rename Fields": {
"main": [
[
{
"node": "Classify Message Intent",
"type": "main",
"index": 0
}
]
]
},
"Read_Rows_Tool": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"Telegram Trigger": {
"main": [
[
{
"node": "Route Input by Message Type",
"type": "main",
"index": 0
}
]
]
},
"Total_Spent_Tool": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"Add_Expenses_Tool": {
"ai_tool": [
[
{
"node": "MCP Server Trigger",
"type": "ai_tool",
"index": 0
}
]
]
},
"Extract Receipt Data": {
"main": [
[
{
"node": "Rename Fields",
"type": "main",
"index": 0
}
]
]
},
"Expense Parsing Model": {
"ai_languageModel": [
[
{
"node": "Parse and Split Multiple Expenses",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Download Receipt Image": {
"main": [
[
{
"node": "Extract Receipt Data",
"type": "main",
"index": 0
}
]
]
},
"Classify Message Intent": {
"main": [
[
{
"node": "Route to Expense or Query Processing",
"type": "main",
"index": 0
}
]
]
},
"Main Financial Assistant": {
"ai_languageModel": [
[
{
"node": "Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Intent Classification Model": {
"ai_languageModel": [
[
{
"node": "Classify Message Intent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Route Input by Message Type": {
"main": [
[
{
"node": "Rename Fields",
"type": "main",
"index": 0
}
],
[
{
"node": "Get Voice File from Telegram",
"type": "main",
"index": 0
}
],
[
{
"node": "Download Receipt Image",
"type": "main",
"index": 0
}
]
]
},
"Get Voice File from Telegram": {
"main": [
[
{
"node": "Convert Voice to Text (ElevenLabs)",
"type": "main",
"index": 0
}
]
]
},
"Parse and Split Multiple Expenses": {
"main": [
[
{
"node": "Agent",
"type": "main",
"index": 0
}
]
]
},
"Convert Voice to Text (ElevenLabs)": {
"main": [
[
{
"node": "Rename Fields",
"type": "main",
"index": 0
}
]
]
},
"Route to Expense or Query Processing": {
"main": [
[
{
"node": "Agent",
"type": "main",
"index": 0
}
],
[
{
"node": "Parse and Split Multiple Expenses",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googleSheetsOAuth2Api
About this workflow
Awesome N8N Templates. Uses agent, telegramTrigger, mcpClientTool, mcpTrigger. Event-driven trigger; 33 nodes.
Source: https://github.com/ScraperNode/awesome-n8n-templates/blob/main/templates/ai-and-llm/8035-multi-modal-expense-tracking-with-gpt-4-gemini-ocr-and-voice-via-telegram/workflow.json — original creator credit. Request a take-down →