Revolut支出自动分类
高级
这是一个Content Creation, Multimodal AI领域的自动化工作流,包含 19 个节点。主要使用 Set, Code, Merge, Crypto, Supabase 等节点。 使用GPT-4和Supabase自动分类Revolut交易
前置要求
- •Supabase URL 和 API Key
- •Google Drive API 凭证
- •OpenAI API Key
使用的节点 (19)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"id": "qfdeygimBULYjsqJ",
"meta": {
"instanceId": "c9b372d6af59e3f6d8835345664babb3bd2c029f9d3764b59df1829e2ae18ec7",
"templateCredsSetupCompleted": true
},
"name": "Revolut支出手动处理",
"tags": [
{
"id": "ea4Bb1csGvuESWWb",
"name": "Revolut",
"createdAt": "2025-08-11T13:32:47.326Z",
"updatedAt": "2025-08-11T13:32:47.326Z"
}
],
"nodes": [
{
"id": "44cf1317-7bac-45f6-a139-6979e1923496",
"name": "当点击\"执行工作流\"时",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-2352,
16
],
"parameters": {},
"typeVersion": 1
},
{
"id": "2ee0180a-e65f-4cf9-9d94-045844873105",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2960,
-352
],
"parameters": {
"width": 496,
"height": 800,
"content": "## Revolut账单分析器"
},
"typeVersion": 1
},
{
"id": "6070fcd4-1cd9-4ffe-a3d3-f7cd582ffc9d",
"name": "下载账单",
"type": "n8n-nodes-base.googleDrive",
"position": [
-1664,
16
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "list",
"value": "1JAb-5Y4Pi2A7LePJ9wvEWVrg6iqN7_5l",
"cachedResultUrl": "https://drive.google.com/file/d/1JAb-5Y4Pi2A7LePJ9wvEWVrg6iqN7_5l/view?usp=drivesdk",
"cachedResultName": "agosto.csv"
},
"options": {},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "ehEt6oTyXIIzKB1E",
"name": "Google Drive - kermitdev9"
}
},
"typeVersion": 3
},
{
"id": "01c41ea4-df02-41ec-965f-43a75cb018b4",
"name": "创建行",
"type": "n8n-nodes-base.supabase",
"onError": "continueErrorOutput",
"position": [
112,
16
],
"parameters": {
"tableId": "transactions",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "completed_date",
"fieldValue": "={{ $json.completed_date }}"
},
{
"fieldId": "started_date",
"fieldValue": "={{ $json.started_date }}"
},
{
"fieldId": "description_original",
"fieldValue": "={{ $json.description_original }}"
},
{
"fieldId": "description_clean",
"fieldValue": "={{ $json.description_clean }}"
},
{
"fieldId": "merchant_name",
"fieldValue": "={{ $json.output.merchant_name }}"
},
{
"fieldId": "category_name",
"fieldValue": "={{ $json.output.category }}"
},
{
"fieldId": "type",
"fieldValue": "={{ $json.type }}"
},
{
"fieldId": "state",
"fieldValue": "={{ $json.state }}"
},
{
"fieldId": "fee",
"fieldValue": "={{ $json.fee }}"
},
{
"fieldId": "currency",
"fieldValue": "={{ $json.currency }}"
},
{
"fieldId": "balance",
"fieldValue": "={{ $json.balance }}"
},
{
"fieldId": "is_subscription",
"fieldValue": "={{ $json.output.is_subscription }}"
},
{
"fieldId": "is_internal",
"fieldValue": "={{ $json.output.is_internal }}"
},
{
"fieldId": "amount",
"fieldValue": "={{ $json.amount }}"
},
{
"fieldId": "uniq_hash",
"fieldValue": "={{ $json.uniq_hash }}"
},
{
"fieldId": "user_id",
"fieldValue": "={{ $json.body?.userId || null }}"
}
]
}
},
"credentials": {
"supabaseApi": {
"id": "bzLzwSBr9xr18RGW",
"name": "Kermitdev9 Supabase"
}
},
"typeVersion": 1
},
{
"id": "45650b46-adeb-4b19-a28e-166ca063f42a",
"name": "标准化内容",
"type": "n8n-nodes-base.set",
"position": [
-1280,
16
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "42e6f2d4-7530-41ed-95a9-4f8b672e974a",
"name": "type",
"type": "string",
"value": "={{ $json[Object.keys($json)[0]] }}"
},
{
"id": "44447d5c-23b7-470f-982a-b6366035b1eb",
"name": "product",
"type": "string",
"value": "={{ $json[Object.keys($json)[1]].trim() }}"
},
{
"id": "44af0831-d9c6-4ec7-a729-58368b38fbb7",
"name": "started_date",
"type": "string",
"value": "={{ (($json[Object.keys($json)[2]]).replace(\" \", \"T\")) + \"Z\" }}"
},
{
"id": "63e4b1f0-a3b4-438c-b21d-347a8e0702c6",
"name": "completed_date",
"type": "string",
"value": "={{ (( $json[Object.keys($json)[3]]).replace(\" \", \"T\")) + \"Z\" }}"
},
{
"id": "842a5afe-7837-46e0-84cd-a894bbafa58c",
"name": "description_original",
"type": "string",
"value": "={{$json[Object.keys($json)[4]]}}"
},
{
"id": "0cdd36f6-cb48-4512-bc6a-3ce285b09aea",
"name": "description_clean",
"type": "string",
"value": "={{ ($json[Object.keys($json)[4]] || \"\").toLowerCase().replace(/\\s+/g, \" \").trim() }}"
},
{
"id": "9fbfbac5-2d02-4db6-8cb7-9177a66b1e37",
"name": "amount",
"type": "string",
"value": "={{ $json[Object.keys($json)[5]] }}"
},
{
"id": "6a6f1bf9-85ae-47fc-a25e-8c5433e6ac0d",
"name": "fee",
"type": "string",
"value": "={{ $json[Object.keys($json)[6]] }}"
},
{
"id": "8585ec37-33a1-4d4c-9b71-456809ab10da",
"name": "currency",
"type": "string",
"value": "={{ $json[Object.keys($json)[7]].toUpperCase() }}"
},
{
"id": "9b3a2caf-3548-4149-952e-86821f17361b",
"name": "state",
"type": "string",
"value": "={{ $json[Object.keys($json)[8]].toUpperCase() }}"
},
{
"id": "f2a8a409-9f3a-477c-8fe5-0eed9570071c",
"name": "balance",
"type": "string",
"value": "={{ $json[Object.keys($json)[9]] }}"
},
{
"id": "8737fc90-2cdf-4ce1-a793-308ee738bdbf",
"name": "raw",
"type": "string",
"value": "={{ $json }}"
},
{
"id": "c617cc25-10f6-47c0-84c8-06081bfe6672",
"name": "uniq_hash",
"type": "string",
"value": "={{ \n ( $json[Object.keys($json)[3]] || \"\") + \"|\" +\n Number($json[Object.keys($json)[5]]).toFixed(2) + \"|\" +\n ( $json[Object.keys($json)[7]] || \"\").toUpperCase() + \"|\" +\n ( $json[Object.keys($json)[0]] || \"\").toUpperCase()\n}}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "21ec8fe0-b1b6-404e-8e73-0501de474bb8",
"name": "提取商户信息",
"type": "n8n-nodes-base.code",
"position": [
-672,
32
],
"parameters": {
"jsCode": "// n8n Function Item\n// Entrada: $json.description_clean (minúsculas, sin espacios dobles)\n// Salida: merchant_candidate, merchant_candidate_normalized\n\nfunction norm(s = \"\") {\n return s\n .toLowerCase()\n .normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/[^a-z0-9\\s]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nlet desc = String($json.description_clean || \"\").trim();\nif (!desc) return [{ ...$json, merchant_candidate: \"unknown\", merchant_candidate_normalized: \"unknown\" }];\n\n// ruido común\nconst STOP_PHRASES = [\n \"payment from\",\"payment to\",\"transfer from\",\"transfer to\",\"bank transfer\",\n \"card payment\",\"pos purchase\",\"card purchase\",\"transaction at\",\"merchant\",\n \"bill\",\"charge\",\"revolut\",\"sas\",\"sarl\",\"sa\",\"ag\",\"gmbh\",\"spa\",\"srl\",\"ltd\",\n \"limited\",\"inc\",\"corp\",\"co\",\"store\",\"shop\"\n];\n\nconst NOISE_REGEX = [\n /\\b(lu|be|fr|de|nl|es|it|uk|us)\\b/g,\n /\\bcom\\b/g,\n /\\bwww\\b/g,\n /https?:\\/\\/\\S+/g,\n /[0-9]{2,}/g\n];\n\ndesc = norm(desc);\nfor (const rx of NOISE_REGEX) desc = desc.replace(rx, \" \");\nfor (const p of STOP_PHRASES) {\n const rx = new RegExp(`\\\\b${p.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}\\\\b`, \"g\");\n desc = desc.replace(rx, \" \");\n}\ndesc = desc.replace(/\\s+/g, \" \").trim();\n\n// canónicos rápidos\nconst CANONICAL = [\n { re: /\\bamzn|amazon|prime\\s+video|amazon\\s+prime\\b/, name: \"Amazon\" },\n { re: /\\bapple|itunes|apple\\.com\\b/, name: \"Apple\" },\n { re: /\\bspotify\\b/, name: \"Spotify\" },\n { re: /\\bnetflix\\b/, name: \"Netflix\" },\n { re: /\\buber\\b/, name: \"Uber\" },\n { re: /\\bbolt\\b/, name: \"Bolt\" },\n { re: /\\bcarrefour\\b/, name: \"Carrefour\" },\n { re: /\\blidl\\b/, name: \"Lidl\" },\n { re: /\\baldi\\b/, name: \"Aldi\" },\n { re: /\\bdelhaize\\b/, name: \"Delhaize\" }\n];\n\nlet canonical = null;\nfor (const { re, name } of CANONICAL) { if (re.test(desc)) { canonical = name; break; } }\n\n// candidato por primeras palabras relevantes\nconst CONNECTORS = new Set([\"the\",\"and\",\"at\",\"for\",\"from\",\"to\",\"on\",\"in\",\"of\"]);\nlet cand = desc.split(\" \").filter(w => w && !CONNECTORS.has(w)).slice(0, 3).join(\" \").trim();\n\nconst merchant_candidate = canonical || cand || (desc || \"unknown\");\nconst merchant_candidate_normalized = norm(merchant_candidate);\n\nreturn [{\n ...$json,\n merchant_candidate: merchant_candidate_normalized\n}];\n"
},
"typeVersion": 2
},
{
"id": "51b8f681-4242-4692-8873-ea326a3dc312",
"name": "遍历项目",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-896,
16
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "48f035d1-2193-4ef1-86bf-9a385ddddadb",
"name": "分类提取",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
-496,
-64
],
"parameters": {
"text": "={{ $('Normalize content').item.json.raw }}",
"batching": {},
"messages": {
"messageValues": [
{
"message": "=You are a financial transaction classifier and merchant extractor.\nYou will receive a raw financial transaction in JSON format.\nYou must return a single valid JSON object following exactly the required schema.\n\nAllowed categories:\n{{ $('Aggregate').item.json.normalized_name }}\n\nInstructions:\n1. Read the raw transaction.\n2. Extract a merchant_name: a clean, standardized version of the business or entity involved.\n - If the description clearly contains a brand or business name, return it cleaned (no codes, extra spaces, or special characters).\n - If there is no clear merchant, return \"Unknown\".\n3. Choose exactly ONE category from the allowed list based on the description, merchant, type, and amount.\n4. Set is_internal=true if the movement is between the user’s own accounts (top up, vault, transfer to self).\n5. Set is_subscription=true if the transaction appears to be a recurring service charge (streaming, memberships, etc.).\n6. Set confidence between 0.0 and 1.0 based on how certain you are about the classification.\n7. Set rule_reason as a short, clear explanation of why you chose that category and merchant.\n8. Respond only with JSON. No extra text, no explanations outside the JSON.\n\nExample output:\n{\n \"merchant_name\": \"Spotify\",\n \"category\": \"Subscriptions\",\n \"is_subscription\": true,\n \"is_internal\": false,\n \"confidence\": 0.98,\n \"rule_reason\": \"The description contains 'Spotify', which is a well-known recurring music subscription service.\"\n}\n"
}
]
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.7
},
{
"id": "dbd5bb41-b6df-4f41-a15c-356d55121ccd",
"name": "合并",
"type": "n8n-nodes-base.merge",
"position": [
-144,
16
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineAll"
},
"typeVersion": 3.2
},
{
"id": "41f70e3c-ab40-4695-af06-cc1be6672331",
"name": "输出解析器",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-304,
112
],
"parameters": {
"jsonSchemaExample": "{\n \"merchant_name\": \"Spotify\",\n \"category\": \"Subscriptions\",\n \"is_subscription\": true,\n \"is_internal\": false,\n \"confidence\": 0.98,\n \"rule_reason\": \"The description contains 'Spotify', which is a well-known recurring music subscription service.\"\n}"
},
"typeVersion": 1.3
},
{
"id": "fd6174c8-3790-447b-9223-ec575ed9d0c7",
"name": "获取多行数据",
"type": "n8n-nodes-base.supabase",
"position": [
-2144,
16
],
"parameters": {
"tableId": "categories",
"operation": "getAll",
"returnAll": true
},
"credentials": {
"supabaseApi": {
"id": "bzLzwSBr9xr18RGW",
"name": "Kermitdev9 Supabase"
}
},
"typeVersion": 1
},
{
"id": "4ab626a6-ceb7-4893-b400-5fff770536c1",
"name": "聚合",
"type": "n8n-nodes-base.aggregate",
"position": [
-1984,
16
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"fieldToAggregate": "normalized_name"
}
]
}
},
"typeVersion": 1
},
{
"id": "5e9d2e5d-39ef-4de6-bc7a-fc093ae63a9e",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2192,
-192
],
"parameters": {
"color": 2,
"width": 368,
"height": 464,
"content": "## 从Supabase获取分类"
},
"typeVersion": 1
},
{
"id": "01a5bac3-91ad-4d67-be6c-0379cd2b1ccd",
"name": "便签2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1776,
-192
],
"parameters": {
"color": 6,
"width": 832,
"height": 464,
"content": "## 下载并转换账单"
},
"typeVersion": 1
},
{
"id": "c76a64ba-e9ae-4716-b11e-de03c87ee6ee",
"name": "便签3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-720,
-192
],
"parameters": {
"color": 2,
"width": 736,
"height": 464,
"content": "## LLM分类器"
},
"typeVersion": 1
},
{
"id": "1343af82-305f-488d-9de4-b878eaf95e95",
"name": "便签4",
"type": "n8n-nodes-base.stickyNote",
"position": [
96,
-192
],
"parameters": {
"color": 2,
"width": 336,
"height": 464,
"content": "## 插入到supabase"
},
"typeVersion": 1
},
{
"id": "af13cecf-f7a9-4ac3-aa81-420de0b26a3f",
"name": "唯一哈希",
"type": "n8n-nodes-base.crypto",
"position": [
-1104,
16
],
"parameters": {
"value": "={{ $json.uniq_hash }}",
"dataPropertyName": "uniq_hash"
},
"typeVersion": 1
},
{
"id": "50638b77-608d-46be-a5fc-11983a3da235",
"name": "gpt-4.1-mini",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
-496,
112
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini",
"cachedResultName": "gpt-4.1-mini"
},
"options": {
"temperature": 0.3
}
},
"credentials": {
"openAiApi": {
"id": "3X2EvLOOJbnKaXSS",
"name": "OpenAi account"
}
},
"typeVersion": 1.2
},
{
"id": "5ecee4f9-7527-48ed-bbbb-176c19f5ef84",
"name": "从文件提取",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-1440,
16
],
"parameters": {
"options": {}
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "363d0f72-9959-4964-b2b5-e00ff29f4690",
"connections": {
"Merge": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
},
{
"node": "Create a row",
"type": "main",
"index": 0
}
]
]
},
"Aggregate": {
"main": [
[
{
"node": "Download extract",
"type": "main",
"index": 0
}
]
]
},
"Uniq Hash": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Create a row": {
"main": [
[],
[]
]
},
"gpt-4.1-mini": {
"ai_languageModel": [
[
{
"node": "Category extraction",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Get many rows": {
"main": [
[
{
"node": "Aggregate",
"type": "main",
"index": 0
}
]
]
},
"Output Parser": {
"ai_outputParser": [
[
{
"node": "Category extraction",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "Extract merchant",
"type": "main",
"index": 0
}
]
]
},
"Download extract": {
"main": [
[
{
"node": "Extract from File",
"type": "main",
"index": 0
}
]
]
},
"Extract merchant": {
"main": [
[
{
"node": "Category extraction",
"type": "main",
"index": 0
},
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Extract from File": {
"main": [
[
{
"node": "Normalize content",
"type": "main",
"index": 0
}
]
]
},
"Normalize content": {
"main": [
[
{
"node": "Uniq Hash",
"type": "main",
"index": 0
}
]
]
},
"Category extraction": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"When clicking ‘Execute workflow’": {
"main": [
[
{
"node": "Get many rows",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 内容创作, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
使用 OpenAI、QuickChart 和 Google Drive 将电子表格数据转换为智能图表
使用 OpenAI、QuickChart 和 Google Drive 将电子表格数据转换为智能图表
If
Set
Code
+18
82 节点LeeWei
内容创作
上下文混合RAG AI文案
Google Drive到Supabase上下文向量数据库同步用于RAG应用
If
Set
Code
+25
76 节点Michael Taleb
AI RAG 检索增强
内容生成器 v3
AI驱动博客自动化:使用GPT-4生成并发布SEO文章至WordPress和Twitter
If
Set
Code
+25
144 节点Jay Emp0
内容创作
WordPress博客自动化专业版(深度研究)v2.1市场
使用GPT-4o、Perplexity AI和多语言支持自动化SEO优化的博客创建
If
Set
Xml
+27
125 节点Daniel Ng
内容创作
使用 OpenAI、ElevenLabs 和 Fal.ai 自动化病毒式内容创作,适用于视频、播客和 ASMR
使用 OpenAI、ElevenLabs 和 Fal.ai 自动化病毒式内容创作,适用于视频、播客和 ASMR
Set
Code
Wait
+16
97 节点Adam Crafts
内容创作
使用Perplexity和GPT为WordPress创建SEO优化博客,包含关键词和媒体
使用Perplexity和GPT为WordPress创建SEO优化博客,包含关键词和媒体
Set
Code
Limit
+22
124 节点Paul
内容创作