This workflow corresponds to n8n.io template #6033 β we link there as the canonical source.
This workflow follows the Agent β Google Sheets Tool recipe pattern β see all workflows that pair these two integrations.
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 β
{
"id": "VMjotXgKnVGgXh6r",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Siri AI Finance Assistant",
"tags": [],
"nodes": [
{
"id": "a763521a-d20a-4e62-89e8-7d80687d2cc9",
"name": "Recieve",
"type": "n8n-nodes-base.webhook",
"position": [
-200,
0
],
"parameters": {
"path": "a80191e2-2219-4157-a686-fe478130a27f",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "8981afa4-741d-41a0-b36e-0e88fd7843d6",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
360,
0
],
"parameters": {
"text": "={{ $json.raw_input }}",
"options": {
"systemMessage": "=## Overview\n\nYou are the user\u2019s personal finance assistant. Your job is to determine whether the user\u2019s input is for recording a transaction or reading account history, and call the correct tool accordingly. You should never ask the user for duplicate details \u2014 infer when possible and proceed with the appropriate tool call. \n\n**Must response in Hong Kong Chinese version\n\n###Tools\n\nUse these tools:\n\t\u2022\tAppend: Use this tool to record new expenses or income.\n\t\u2022\tRead: Use this tool to read and summarize spending records based on time range or category.\n\n### Instructions\n\t1.\tFirst, check today\u2019s date: {{ $now }}\n\t2.\tThen, analyze the user input from: {{ $json.raw_input }}\n\t3.\tDecide whether it\u2019s a write or read task.\n\t4.\tSend the properly formatted payload to the corresponding tool.\n\nIf the user does not specify date, category, or income/expense type, make reasonable assumptions without asking again.\n\n#### Write Example (Append)\n\nUser says: \u300c\u6211\u982d\u5148\u98df\u9ea5\u7576\u52de\u7528\u4e8652\u868a\u300d\n\u2192 Use tool: Append\n\u2192 Send Format:\n```json\n{\n \"Date\": \"2025-07-12\",\n \"Type\": \"Food\",\n \"Name\": \"Lunch (McDonald's)\",\n \"Amount\": 52.00,\n \"expenses/incomes\": \"Expense\",\n \"created time\": \"2025-07-12T14:30:00\"\n}\n```\n\u2192 Reply:\n\u5df2\u8a18\u9304\u652f\u51fa\uff1a\u9805\u76ee\u300c\u5348\u9910\uff08\u9ea5\u7576\u52de\uff09\u300d\u5206\u985e\u300c\u98f2\u98df\u300d\uff0c\u91d1\u984d $52\uff0c\u5df2\u5beb\u5165\u3002\n\n\u2e3b\n\n#### Read Example (Read)\n\nUser says: \u300c\u5e6b\u6211\u67e5\u904e\u53bb\u4e00\u661f\u671f\u7684\u958b\u652f\u300d\n\u2192 Use tool: Read\n\u2192 After reading data, reply:\n\u904e\u53bb 7 \u65e5\u4f60\u7684\u652f\u51fa\u7e3d\u984d\u70ba $250\uff0c\u5305\u62ec\uff1a7/8 \u5730\u9435 $14\u30017/10 \u5df4\u58eb $21\u30017/11 \u7684\u58eb $215\u3002\n\n\u2e3b\n\n#### Rules\n\t\u2022\tAlways call the tool, never just return plain JSON or text.\n\t\u2022\tUse numerical values only for money.\n\t\u2022\tMust response in Hong Kong Chinese version\n \u2022 Group records by monthly page (e.g., \u201c07/2025\u201d).\n\t\u2022\tKeep replies brief and human-readable.\n\t\u2022\tDo not ask the user to confirm inferred values unless absolutely necessary.\n\n"
},
"promptType": "define"
},
"typeVersion": 1.9
},
{
"id": "6acbd90d-80e7-4280-a6af-815fab5ccef9",
"name": "OpenRouter Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
200,
220
],
"parameters": {
"model": "google/gemini-2.0-flash-lite-001",
"options": {
"maxTokens": -1
}
},
"credentials": {
"openRouterApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "41fc8d6a-b550-4f4e-99c7-febad18d7044",
"name": "Respond",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
920,
0
],
"parameters": {
"options": {},
"respondWith": "allIncomingItems"
},
"typeVersion": 1.2
},
{
"id": "ce2f86f7-3246-4582-9d1d-3e12420308ed",
"name": "Append",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
520,
320
],
"parameters": {
"columns": {
"value": {
"Date": "={{ $fromAI('Date', ``, 'string') }}",
"Name": "={{ $fromAI('Name', ``, 'string') }}",
"Type": "={{ $fromAI('Type', ``, 'string') }}",
"Amount": "={{ $fromAI('Amount', ``, 'string') }}",
"created time": "={{$now}}",
"expenses/incomes": "={{ $fromAI('expenses_incomes', ``, 'string') }}"
},
"schema": [
{
"id": "Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Type",
"type": "string",
"display": true,
"required": false,
"displayName": "Type",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Amount",
"type": "string",
"display": true,
"required": false,
"displayName": "Amount",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "expenses/incomes",
"type": "string",
"display": true,
"required": false,
"displayName": "expenses/incomes",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "created time",
"type": "string",
"display": true,
"required": false,
"displayName": "created time",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1478323734,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1uZik4myIt4XHGs5fpv6ZEDdczVyaOpMe3vLmtLCy0Zc/edit#gid=1478323734",
"cachedResultName": "overall"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1uZik4myIt4XHGs5fpv6ZEDdczVyaOpMe3vLmtLCy0Zc",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1uZik4myIt4XHGs5fpv6ZEDdczVyaOpMe3vLmtLCy0Zc/edit?usp=drivesdk",
"cachedResultName": "ai_personal_expense"
},
"descriptionType": "manual",
"toolDescription": "Use this tool to record new expenses or income."
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.6
},
{
"id": "90f73019-e193-4e7e-805d-5f2f1f5ade08",
"name": "Read",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
680,
300
],
"parameters": {
"options": {
"dataLocationOnSheet": {
"values": {
"rangeDefinition": "detectAutomatically"
}
}
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1478323734,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1uZik4myIt4XHGs5fpv6ZEDdczVyaOpMe3vLmtLCy0Zc/edit#gid=1478323734",
"cachedResultName": "overall"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1uZik4myIt4XHGs5fpv6ZEDdczVyaOpMe3vLmtLCy0Zc",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1uZik4myIt4XHGs5fpv6ZEDdczVyaOpMe3vLmtLCy0Zc/edit?usp=drivesdk",
"cachedResultName": "ai_personal_expense"
},
"descriptionType": "manual",
"toolDescription": "Use this tool to read and summarize spending records based on time range or category."
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.6
},
{
"id": "4f597617-55ec-4ba2-84de-53e3ef2fbf01",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
340,
260
],
"parameters": {
"sessionKey": "={{ $json.raw_input }}",
"sessionIdType": "customKey",
"contextWindowLength": 3
},
"typeVersion": 1.3
},
{
"id": "a9399a79-3327-4c99-8c6d-0fc2de29dfb1",
"name": "FormatInput",
"type": "n8n-nodes-base.code",
"position": [
60,
0
],
"parameters": {
"jsCode": "const body = $json.body || {};\nconst rawInput = body.input || '';\nconst now = new Date();\n\nreturn [\n {\n json: {\n raw_input: rawInput, // \u539f\u59cb\u8f38\u5165\u53e5\uff0c\u4f8b\u5982\uff1a\u6211\u4eca\u671d\u98df\u65e9\u9910\u7528\u5497$50\u5e6b\u6211\u5beb\u8fd4\u4f62\n formatted_time: now.toISOString(), // 2025-07-12T15:32:00.000Z\n date: now.toISOString().split('T')[0], // 2025-07-12\n time: now.toTimeString().split(' ')[0], // 15:32:00\n }\n }\n];"
},
"typeVersion": 2
},
{
"id": "431bab20-a59d-4989-abfe-e5f55282b939",
"name": "FormatOutput",
"type": "n8n-nodes-base.code",
"position": [
720,
0
],
"parameters": {
"jsCode": "// \u5c07\u6240\u6709\u8f38\u51fa\u7684\u63db\u884c\u7b26\u79fb\u9664\nconst outputs = items.map(item => {\n const output = item.json.output || '';\n return output.replace(/\\n/g, '');\n});\n\n// \u6b63\u78ba\u56de\u50b3\u683c\u5f0f\uff0c\u6bcf\u7b46 json \u4e00\u5b9a\u8981\u662f object\nreturn [\n {\n json: {\n \u5e0c\u5e0c: outputs.join('')\n }\n }\n];"
},
"typeVersion": 2
},
{
"id": "f9f8c609-d126-43e3-8770-c142a67e345f",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-960,
-140
],
"parameters": {
"width": 700,
"height": 2060,
"content": "SIri AI 2.0 (Finance Assistant Version)\n\nPlease download:\n1. Shortcut\nhttps://www.icloud.com/shortcuts/9848032ea36c434bbdc8cf9631309a81\n2. this n8n workflow\n3. Google Drive API\n\nSteps:\n\ud83c\udf10 PART 1: n8n Setup\n\n\ud83e\udde9 1. Create a Webhook Trigger in n8n\n\t\u2022\tAdd a node: Webhook\n\t\u2022\tSet HTTP Method: POST\n\t\u2022\tSet Path: siri-finance\n\t\u2022\tEnable \u201cRespond to Webhook\u201d = \u2705\n\n\ud83e\udde0 2. Add AI Agent Node (e.g. OpenAI, Ollama, Gemini)\n\t\u2022\tUse system prompt like:\n\nYou are a finance assistant. Decide if the user wants to record or read transactions.\nIf it's recording, return a JSON object with date, type, name, amount, and expense/income.\nIf it's reading, return date range and type (Expense/Income).\nAlways reply with a human-friendly summary.\n\n\n\t\u2022\tInput: {{ $json.text }} (from webhook)\n\t\u2022\tOutput: structured json.output\n\n\ud83e\uddee 3. (Optional) Add Logic to write to DB / Supabase / Google Sheets\n\t\u2022\tAppend tool: Adds a new row\n\t\u2022\tRead tool: Queries past data\n\n\ud83d\udcac 4. Add a Function Node to format the final message\n\nconst raw = item.json.output || '';\nconst cleaned = raw\n .replace(/\\n/g, ' ')\n .replace(/<br\\s*\\/?>/g, ' ')\n .replace(/[^\\u4e00-\\u9fa5a-zA-Z0-9\\s\\$\uff1a\u3002\uff0c\u201c\u201d]/g, '')\n .trim();\nreturn [{ json: { reply: cleaned } }];\n\n\ud83d\udce9 5. Return final reply to Siri\n\t\u2022\tIn your Webhook Respond Node, set Body:\n\n{{ $json.reply }}\n\nNow your n8n flow is ready!\n\n\u2e3b\n\n\ud83d\udcf1 PART 2: iOS Shortcut Setup\n\n\u2699\ufe0f 1. Create a new Shortcut\n\t\u2022\tName it: \u8a18\u5e33\u52a9\u7406 (or Finance Bot)\n\t\u2022\tAdd Action: Ask for Input\n\t\u2022\tPrompt: \u201c\u8acb\u8aaa\u51fa\u4f60\u7684\u8a18\u5e33\u5167\u5bb9\u201d\n\t\u2022\tInput Type: Text\n\t\u2022\tAdd Action: Get Contents of URL\n\t\u2022\tMethod: POST\n\t\u2022\tURL: https://your-n8n-domain/webhook/siri-finance\n\t\u2022\tHeaders: Content-Type: application/json\n\t\u2022\tRequest Body:\n\n{\n \"text\": \"Provided Input\"\n}\n\n\t\u2022\tReplace \"Provided Input\" with Magic Variable \u2192 Input Result\n\n\ud83d\udd0a 2. Show Result\n\t\u2022\tAdd Action: Show Result\n\t\u2022\tContent: Get Contents of URL\n\n\ud83d\udde3\ufe0f 3. Optional: Add \u201cSpeak Text\u201d\n\t\u2022\tIf you want Siri to speak it back, add Speak Text after Show Result.\n\n\u2e3b\n\n\u2705 Example Usage\n\t\u2022\tYou: \u201cHey Siri, \u958b\u652f$50 \u65e9\u9910\u201d\n\t\u2022\tSiri: \u201c\u5df2\u8a18\u9304\u652f\u51fa\uff1a\u9805\u76ee \u65e9\u9910\uff0c\u91d1\u984d $50\uff0c\u5df2\u5beb\u5165\u201d\n\nOr\n\t\u2022\tYou: \u201c\u67e5\u4e00\u4e0b\u6211\u904e\u53bb7\u65e5\u7528\u4e86\u5e7e\u591a\u9322\u201d\n\t\u2022\tSiri: \u201c\u4f60\u904e\u53bb7\u65e5\u7e3d\u652f\u51fa\u70ba $7684.64\uff0c\u5305\u62ec\uff1a\u22ef\u22ef\u201d\n\n\u2e3b\n\n\ud83d\udce6 Files to Share\n\nYou can package the following:\n\t\u2022\t.shortcut file export\n\t\u2022\tSample n8n workflow .json\n\t\u2022\tOptional Supabase schema / Google Sheet template\n\n\u2e3b\n\n\ud83d\udca1 Tips for Newcomers\n\t\u2022\tKeep your Webhook public but protect with token if needed.\n\t\u2022\tEnsure you handle emoji and newline safely for iOS compatibility.\n\t\u2022\tAdd logging nodes in n8n to help debug Siri messages.\n\n\u2e3b\n\n\ud83d\udde3\ufe0f Optional Project Name\n\n\u201cSiri \u8a18\u5e33\u52a9\u7406\u201d / \u201cFinance VoiceBot\u201d\n\nA simple voice-first way to manage your daily expenses.\n\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "a8f06de3-3118-4a4d-b124-4603ed8b0b25",
"connections": {
"Read": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Append": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Recieve": {
"main": [
[
{
"node": "FormatInput",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "FormatOutput",
"type": "main",
"index": 0
}
]
]
},
"FormatInput": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"FormatOutput": {
"main": [
[
{
"node": "Respond",
"type": "main",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"OpenRouter Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"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.
googleSheetsOAuth2ApiopenRouterApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
π― What It Does:
Source: https://n8n.io/workflows/6033/ β original creator credit. Request a take-down β
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Enhance your support, onboarding, and internal knowledge workflows with an intelligent RAG-powered chatbot that responds using live data stored in Google Sheets. π€π Built for teams that rely on struct
π§ͺ LABR - nuevo asistente (REPARADO). Uses httpRequest, postgres, postgresTool, toolCalculator. Webhook trigger; 63 nodes.
π§ Gwen β The AI Voice Marketing Agent Gwen is your intelligent voice-powered marketing assistant built in n8n. She combines the power of OpenAI, ElevenLabs, and automation workflows to handle content
This workflow is an AI-powered Dental Appointment Assistant that automates appointment booking, rescheduling, and cancellations through Telegram or a Webhook. It uses intelligent agents to understand
This workflow acts as an AI-powered research assistant that takes a topic from the user, performs multi-step intelligent research, and stores the final report in Notion. It uses advanced search, conte