8
n8n 한국어amn8n.com

MS 지출 추적기

중급

이것은Personal Productivity, AI Summarization분야의자동화 워크플로우로, 10개의 노드를 포함합니다.주로 Code, GoogleSheets, Agent, HttpRequestTool, TelegramTrigger 등의 노드를 사용하며. Telegram, AI, Google Sheets를 활용한 자동 지출 추적

사전 요구사항
  • Google Sheets API 인증 정보
  • 대상 API의 인증 정보가 필요할 수 있음
  • Telegram Bot Token
  • OpenAI API Key
  • Anthropic API Key
  • Google Gemini API Key
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
  "id": "B1P6d8Jusl69JubP",
  "meta": {
    "instanceId": "c92a0c76586da37fb3ac600956b62e842bfa4bd5f52acc7feb4e8a6e75ca1381",
    "templateCredsSetupCompleted": true
  },
  "name": "MS_SPEND_TRACKER",
  "tags": [],
  "nodes": [
    {
      "id": "76519239-54b1-40e3-b7df-5c86c006a893",
      "name": "Telegram 트리거",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -100,
        0
      ],
      "webhookId": "9f664da7-cf40-44c6-a341-d69d6136366d",
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {
          "chatIds": "={{ $env.chat_id }}",
          "download": true
        }
      },
      "credentials": {
        "telegramApi": {
          "id": "OymlVCuTPYhVa2B9",
          "name": "Telegram account"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "60fedb80-ee63-4a46-916c-9d133b9fa874",
      "name": "AI 에이전트",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        220,
        0
      ],
      "parameters": {
        "text": "===Parse this expense message and extract structured spending.\n\nMESSAGE: \"{{ $json.message?.text || $json.chatInput }}\"\nFROM USER: {{ $json.message?.from.id || 1 }}\nTIMESTAMP: {{ $now }}\n\n**INSTRUCTIONS:**\n1. **Parse the message** to extract the amount, description, currency, and payment method.\n2. **Currency & Exchange Rate Logic:**\n   * Identify the currency from the message (EGP, USD, SAR, AED). If no currency is mentioned, default to \"EGP\".\n   * **CRITICAL:** Only use the `Get Rates` tool if the identified currency is USD, SAR, or AED.\n   * If the currency is \"EGP\", set the `exchange_rate` to `1` and the `amount_converted` to be the same as the `amount`. Do NOT use the `Get Rates` tool for EGP transactions.\n3. **Categorization:** Assign a category based on the `CATEGORY MAPPING HINTS`. If no clear category fits, use \"Other\".\n4. **Final Output:** Respond with ONLY a valid JSON object. No explanations, no markdown formatting.\n\n---\n**CATEGORY MAPPING HINTS:**\n- \"coffee\", \"café\", \"starbucks\" → Coffee\n- \"uber\", \"taxi\", \"metro\", \"bus\" → Transport\n- \"supermarket\", \"carrefour\", \"spinneys\" → Groceries\n- \"restaurant\", \"food\", \"lunch\", \"dinner\" → Food & Dining\n- \"clothes\", \"shoes\", \"mall\" → Shopping\n- \"medicine\", \"doctor\", \"pharmacy\" → Health\n- \"netflix\", \"spotify\", \"gym\" → Subscriptions\n\n**PAYMENT METHOD HINTS:**\n- \"cash\", \"نقدي\" → Cash (default)\n- \"card\", \"visa\", \"mastercard\" → Credit Card\n- \"vodafone cash\", \"wallet\" → Wallet\n- \"transfer\", \"bank\" → Bank Transfer\n\n---\n\n**REQUIRED OUTPUT FORMAT:**\n{\n  \"amount\": <number>,\n  \"category\": \"<string>\",\n  \"description\": \"<string>\",\n  \"date\": \"<ISO date-time string>\",\n  \"user_id\": \"<string>\",\n  \"payment_method\": \"<string>\",\n  \"currency\": \"<string>\",\n  \"exchange_rate\": <number>,\n  \"amount_converted\": <number>\n}",
        "options": {
          "systemMessage": "You are a financial data extraction specialist. You receive natural language text about expenses and convert them to structured JSON.\n\nCRITICAL RULES:\n1. Always return valid JSON only - no explanations, no markdown\n2. All required fields must be present\n3. Numbers must be actual numbers, not strings\n4. Dates must be in ISO format\n5. If information is missing, use sensible defaults\n\nYou must follow the exact JSON schema provided in the user prompt."
        },
        "promptType": "define",
        "needsFallback": true,
        "hasOutputParser": true
      },
      "typeVersion": 2
    },
    {
      "id": "f7bb1c22-e64a-4a15-b483-823bb8c56ceb",
      "name": "o3",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        260,
        280
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "o3",
          "cachedResultName": "o3"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "8lxlMBHY8Mt8KqSc",
          "name": "OpenAi account"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "3867cd64-89a1-49c5-a81b-046970cea171",
      "name": "H3.5",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        40,
        280
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-3-5-haiku-20241022",
          "cachedResultName": "Claude Haiku 3.5"
        },
        "options": {}
      },
      "credentials": {
        "anthropicApi": {
          "id": "4ScK4atfzHy1FIZU",
          "name": "Anthropic account"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "6ffd9ec9-2e7a-4a96-8ed7-4dd6dd60dd76",
      "name": "Get Rates",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        500,
        280
      ],
      "parameters": {
        "url": "https://open.er-api.com/v6/latest/EGP",
        "options": {},
        "toolDescription": "Get exchange rates for EGP"
      },
      "typeVersion": 4.2
    },
    {
      "id": "5e9fd301-a6c2-4e5f-8eda-46d4f20475e9",
      "name": "Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        620,
        280
      ],
      "parameters": {
        "autoFix": true,
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"amount\": {\n      \"type\": \"number\",\n      \"description\": \"The expense amount in the original currency\"\n    },\n    \"category\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"Groceries\",\n        \"Transport\", \n        \"Food & Dining\",\n        \"Shopping\",\n        \"Personal Care\",\n        \"Health\",\n        \"Utilities\",\n        \"Entertainment\",\n        \"Education\",\n        \"Bills\",\n        \"Subscriptions\",\n        \"Donations\",\n        \"Family\",\n        \"Other\"\n      ],\n      \"description\": \"The expense category from predefined list\"\n    },\n    \"description\": {\n      \"type\": \"string\",\n      \"description\": \"Description or note about the expense\"\n    },\n    \"date\": {\n      \"type\": \"string\",\n      \"format\": \"date-time\",\n      \"description\": \"ISO 8601 date-time string of when the expense occurred\"\n    },\n    \"user_id\": {\n      \"type\": \"string\",\n      \"description\": \"Telegram user ID who made the expense\"\n    },\n    \"payment_method\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"Cash\",\n        \"Credit Card\", \n        \"Wallet\"\n      ],\n      \"description\": \"Method used to make the payment\"\n    },\n    \"currency\": {\n      \"type\": \"string\",\n      \"enum\": [\"EGP\", \"USD\", \"SAR\", \"AED\"],\n      \"description\": \"Original currency of the transaction\"\n    },\n    \"exchange_rate\": {\n      \"type\": \"number\",\n      \"description\": \"Exchange rate from original currency to EGP (1.0 if already EGP)\"\n    },\n    \"amount_converted\": {\n      \"type\": \"number\", \n      \"description\": \"Amount converted to EGP using the exchange rate\"\n    }\n  },\n  \"required\": [\n    \"amount\",\n    \"category\", \n    \"description\",\n    \"date\",\n    \"user_id\",\n    \"payment_method\",\n    \"currency\",\n    \"exchange_rate\",\n    \"amount_converted\"\n  ],\n  \"additionalProperties\": false\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "8b0131e6-7cb1-4445-8785-6c938499a132",
      "name": "Append row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        860,
        0
      ],
      "parameters": {
        "columns": {
          "value": {
            "date": "={{ $json.date }}",
            "amount": "={{ $json.amount }}",
            "user_id": "={{ $json.user_id }}",
            "category": "={{ $json.category }}",
            "currency": "={{ $json.currency }}",
            "description": "={{ $json.description }}",
            "exchange_rate": "={{ $json.exchange_rate }}",
            "payment_method": "={{ $json.payment_method }}",
            "amount_converted": "={{ $json.amount_converted }}"
          },
          "schema": [
            {
              "id": "amount",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "amount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "category",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "category",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "description",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "user_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "user_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "payment_method",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "payment_method",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "currency",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "currency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "exchange_rate",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "exchange_rate",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "amount_converted",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "amount_converted",
              "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/1v5ffTb0q-kS4yE6ItklO-L1CX3qKVgIT1VlGK2pEU6s/edit#gid=0",
          "cachedResultName": "txn"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1v5ffTb0q-kS4yE6ItklO-L1CX3qKVgIT1VlGK2pEU6s",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1v5ffTb0q-kS4yE6ItklO-L1CX3qKVgIT1VlGK2pEU6s/edit?usp=drivesdk",
          "cachedResultName": "n8n-spending-tracker"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "aGXCer6XeWMYlGFP",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "62b68b7f-1bf0-44e2-8596-87fd6af48fdb",
      "name": "2.5F",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -60,
        280
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "id": "5zYMtBaFTxmme3MM",
          "name": "Gemini api key"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "688170f6-31f9-495b-a617-fc84c142569b",
      "name": "2.5F1",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        620,
        440
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "id": "5zYMtBaFTxmme3MM",
          "name": "Gemini api key"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c9250987-9160-49b6-9d8a-00865065487e",
      "name": "코드",
      "type": "n8n-nodes-base.code",
      "position": [
        640,
        0
      ],
      "parameters": {
        "jsCode": "// Process AI Agent output and fix date format for Google Sheets\nconst aiOutput = $input.first().json.output;\n\n// Convert ISO date to Google Sheets compatible format\nfunction formatDateForSheets(isoString) {\n  const date = new Date(isoString);\n  // Format as YYYY-MM-DD HH:MM:SS (Google Sheets preferred format)\n  return date.toISOString().slice(0, 19).replace('T', ' ');\n}\n\n// Process the data with proper date formatting\nconst processedData = {\n  amount: Number(aiOutput.amount) || 0,\n  category: String(aiOutput.category || 'Other'),\n  description: String(aiOutput.description || ''),\n  date: formatDateForSheets(aiOutput.date || new Date().toISOString()),\n  user_id: String(aiOutput.user_id || ''),\n  payment_method: String(aiOutput.payment_method || 'Other'),\n  currency: String(aiOutput.currency || 'EGP'),\n  exchange_rate: Number(aiOutput.exchange_rate) || 1,\n  amount_converted: Number(aiOutput.amount_converted) || Number(aiOutput.amount) || 0\n};\n\nreturn [{ json: processedData }];"
      },
      "typeVersion": 2
    }
  ],
  "active": true,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "49657870-ce61-456e-ad93-d2be3e50012b",
  "connections": {
    "f7bb1c22-e64a-4a15-b483-823bb8c56ceb": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 1
          }
        ]
      ]
    },
    "62b68b7f-1bf0-44e2-8596-87fd6af48fdb": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Code": {
      "main": [
        [
          {
            "node": "8b0131e6-7cb1-4445-8785-6c938499a132",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3867cd64-89a1-49c5-a81b-046970cea171": {
      "ai_languageModel": [
        []
      ]
    },
    "688170f6-31f9-495b-a617-fc84c142569b": {
      "ai_languageModel": [
        [
          {
            "node": "5e9fd301-a6c2-4e5f-8eda-46d4f20475e9",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "5e9fd301-a6c2-4e5f-8eda-46d4f20475e9": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6ffd9ec9-2e7a-4a96-8ed7-4dd6dd60dd76": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
자주 묻는 질문

이 워크플로우를 어떻게 사용하나요?

위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.

이 워크플로우는 어떤 시나리오에 적합한가요?

중급 - 개인 생산성, AI 요약

유료인가요?

이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.

워크플로우 정보
난이도
중급
노드 수10
카테고리2
노드 유형9
난이도 설명

일정 경험을 가진 사용자를 위한 6-15개 노드의 중간 복잡도 워크플로우

외부 링크
n8n.io에서 보기

이 워크플로우 공유

카테고리

카테고리: 34