
Siri AI Finance Assistant
説明
Categories
📊 Productivity🤖 AI & Machine Learning
Nodes Used
n8n-nodes-base.coden8n-nodes-base.coden8n-nodes-base.webhookn8n-nodes-base.stickyNote@n8n/n8n-nodes-langchain.agentn8n-nodes-base.googleSheetsTooln8n-nodes-base.googleSheetsTooln8n-nodes-base.respondToWebhook@n8n/n8n-nodes-langchain.lmChatOpenRouter@n8n/n8n-nodes-langchain.memoryBufferWindow
Price無料
Views0
最終更新11/28/2025
workflow.json
{
"id": "VMjotXgKnVGgXh6r",
"meta": {
"instanceId": "4b2fb6f84ef91181f85de1277717d6717566b015633b0c427e51a39fe81532f2",
"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
],
"webhookId": "a80191e2-2219-4157-a686-fe478130a27f",
"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’s personal finance assistant. Your job is to determine whether the user’s 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 — 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•\tAppend: Use this tool to record new expenses or income.\n\t•\tRead: Use this tool to read and summarize spending records based on time range or category.\n\n### Instructions\n\t1.\tFirst, check today’s date: {{ $now }}\n\t2.\tThen, analyze the user input from: {{ $json.raw_input }}\n\t3.\tDecide whether it’s 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: 「我頭先食麥當勞用了52蚊」\n→ Use tool: Append\n→ 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→ Reply:\n已記錄支出:項目「午餐(麥當勞)」分類「飲食」,金額 $52,已寫入。\n\n⸻\n\n#### Read Example (Read)\n\nUser says: 「幫我查過去一星期的開支」\n→ Use tool: Read\n→ After reading data, reply:\n過去 7 日你的支出總額為 $250,包括:7/8 地鐵 $14、7/10 巴士 $21、7/11 的士 $215。\n\n⸻\n\n#### Rules\n\t•\tAlways call the tool, never just return plain JSON or text.\n\t•\tUse numerical values only for money.\n\t•\tMust response in Hong Kong Chinese version\n • Group records by monthly page (e.g., “07/2025”).\n\t•\tKeep replies brief and human-readable.\n\t•\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": {
"id": "un6KB7BYeIzg3yR9",
"name": "HanamiAIfree"
}
},
"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": {
"id": "wWSdSoDCZ7FLnBb3",
"name": "Angus Account"
}
},
"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": {
"id": "wWSdSoDCZ7FLnBb3",
"name": "Angus Account"
}
},
"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, // 原始輸入句,例如:我今朝食早餐用咗$50幫我寫返佢\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": "// 將所有輸出的換行符移除\nconst outputs = items.map(item => {\n const output = item.json.output || '';\n return output.replace(/\\n/g, '');\n});\n\n// 正確回傳格式,每筆 json 一定要是 object\nreturn [\n {\n json: {\n 希希: 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🌐 PART 1: n8n Setup\n\n🧩 1. Create a Webhook Trigger in n8n\n\t•\tAdd a node: Webhook\n\t•\tSet HTTP Method: POST\n\t•\tSet Path: siri-finance\n\t•\tEnable “Respond to Webhook” = ✅\n\n🧠 2. Add AI Agent Node (e.g. OpenAI, Ollama, Gemini)\n\t•\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•\tInput: {{ $json.text }} (from webhook)\n\t•\tOutput: structured json.output\n\n🧮 3. (Optional) Add Logic to write to DB / Supabase / Google Sheets\n\t•\tAppend tool: Adds a new row\n\t•\tRead tool: Queries past data\n\n💬 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\\$:。,“”]/g, '')\n .trim();\nreturn [{ json: { reply: cleaned } }];\n\n📩 5. Return final reply to Siri\n\t•\tIn your Webhook Respond Node, set Body:\n\n{{ $json.reply }}\n\nNow your n8n flow is ready!\n\n⸻\n\n📱 PART 2: iOS Shortcut Setup\n\n⚙️ 1. Create a new Shortcut\n\t•\tName it: 記帳助理 (or Finance Bot)\n\t•\tAdd Action: Ask for Input\n\t•\tPrompt: “請說出你的記帳內容”\n\t•\tInput Type: Text\n\t•\tAdd Action: Get Contents of URL\n\t•\tMethod: POST\n\t•\tURL: https://your-n8n-domain/webhook/siri-finance\n\t•\tHeaders: Content-Type: application/json\n\t•\tRequest Body:\n\n{\n \"text\": \"Provided Input\"\n}\n\n\t•\tReplace \"Provided Input\" with Magic Variable → Input Result\n\n🔊 2. Show Result\n\t•\tAdd Action: Show Result\n\t•\tContent: Get Contents of URL\n\n🗣️ 3. Optional: Add “Speak Text”\n\t•\tIf you want Siri to speak it back, add Speak Text after Show Result.\n\n⸻\n\n✅ Example Usage\n\t•\tYou: “Hey Siri, 開支$50 早餐”\n\t•\tSiri: “已記錄支出:項目 早餐,金額 $50,已寫入”\n\nOr\n\t•\tYou: “查一下我過去7日用了幾多錢”\n\t•\tSiri: “你過去7日總支出為 $7684.64,包括:⋯⋯”\n\n⸻\n\n📦 Files to Share\n\nYou can package the following:\n\t•\t.shortcut file export\n\t•\tSample n8n workflow .json\n\t•\tOptional Supabase schema / Google Sheet template\n\n⸻\n\n💡 Tips for Newcomers\n\t•\tKeep your Webhook public but protect with token if needed.\n\t•\tEnsure you handle emoji and newline safely for iOS compatibility.\n\t•\tAdd logging nodes in n8n to help debug Siri messages.\n\n⸻\n\n🗣️ Optional Project Name\n\n“Siri 記帳助理” / “Finance VoiceBot”\n\nA simple voice-first way to manage your daily expenses.\n\n"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {
"Recieve": [
{
"json": {
"body": {
"input": "食咗早餐$40"
},
"query": {},
"params": {},
"headers": {
"host": "webhook.lingumiai.com",
"accept": "*/*",
"cf-ray": "95e4feadeedc2647-NRT",
"cdn-loop": "cloudflare; loops=1",
"priority": "u=3",
"cf-visitor": "{\"scheme\":\"https\"}",
"connection": "keep-alive",
"user-agent": "BackgroundShortcutRunner/3607.0.2 CFNetwork/3826.500.131 Darwin/24.5.0",
"cf-ipcountry": "JP",
"content-type": "application/json",
"cf-warp-tag-id": "39d521c3-e05a-4548-b17c-ad512cc8f71b",
"content-length": "27",
"accept-encoding": "gzip, br",
"accept-language": "zh-HK,zh-Hant;q=0.9",
"x-forwarded-for": "138.199.22.149",
"cf-connecting-ip": "138.199.22.149",
"x-forwarded-proto": "https"
},
"webhookUrl": "http://localhost:5678/webhook/a80191e2-2219-4157-a686-fe478130a27f",
"executionMode": "production"
}
}
]
},
"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
}
]
]
}
}
}