{
  "name": "Multi-modal expense tracking with Telegram, Gemini AI & Google Sheets",
  "nodes": [
    {
      "id": "7be734f2-0de6-4763-81e5-346cb715bd66",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1664,
        624
      ],
      "parameters": {
        "width": 896,
        "height": 928,
        "content": "# 🚀 Quick Start\n\n## 📋 Workflow Overview\n- **Ingest** Telegram messages as the source (text, voice, image).\n- **Route** by type and **validate** supported formats (text/voice/photo only).\n- **Transform"
      }
    },
    {
      "id": "dba88ead-1ca9-488d-9cb2-c1fdc4156dce",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -688,
        560
      ],
      "parameters": {
        "width": 672,
        "height": 992,
        "content": "## 1) Message Intake & Routing\n**Purpose:** Receive user messages and route by input type.  \n**Covers nodes:** `Start: On Telegram Message` → `Route: Text, Voice or Image?` → (`Telegram: Send error me"
      }
    },
    {
      "id": "67cb65eb-65c3-4e83-a5db-8fc0a227513a",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        560
      ],
      "parameters": {
        "width": 688,
        "height": 992,
        "content": "## 2) Input Capture & Normalization\n**Purpose:** Turn everything into plain text for parsing.  \n**Covers nodes:**  \n`Set: Text Input` \n`Telegram: Get Voice File` → `Gemini: Transcribe Voice` → `Set: V"
      }
    },
    {
      "id": "bbcaf572-fe02-49d9-bb73-9e0229c4e931",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        560
      ],
      "parameters": {
        "width": 432,
        "height": 992,
        "content": "## 3) Expense Parsing & Validation\n**Purpose:** Convert free-form text into structured expenses.  \n**Covers nodes:** `AI: Extract Expenses`\n**What it does:**\n- Parses `raw_text` into a strict JSON arr"
      }
    },
    {
      "id": "40c74ab6-4079-475d-89d1-c861ca778c94",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1168,
        560
      ],
      "parameters": {
        "width": 1056,
        "height": 992,
        "content": "## 4) Row Generation, Sheet Write & Confirmation\n**Purpose:** Turn parsed entries into rows, save them, and notify the user.  \n**Covers nodes:** `Split: Entries to Rows` → `If null?` → `Set: Extract O"
      }
    },
    {
      "id": "5ca4b51a-2d7e-46f9-82a5-081b0cb970fd",
      "name": "GSheet: Log Expense",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1824,
        1056
      ]
    },
    {
      "id": "297ff453-2268-40ba-95c3-fa7a3e736467",
      "name": "LLM: Gemini Flash",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        768,
        1408
      ]
    },
    {
      "id": "9519104e-7bb0-4b48-aa2c-cd416266a9de",
      "name": "Gemini: Transcribe Voice",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        272,
        1072
      ]
    },
    {
      "id": "8bd5377e-39ef-4af7-846d-1d3a279151c2",
      "name": "Telegram: Send Confirmation",
      "type": "n8n-nodes-base.telegram",
      "position": [
        2016,
        1056
      ]
    },
    {
      "id": "ec454606-5cc7-45ff-a8fe-a8ecd39b7b13",
      "name": "Telegram: Get Voice File",
      "type": "n8n-nodes-base.telegram",
      "position": [
        64,
        1072
      ]
    },
    {
      "id": "ab30a0a4-0f88-437a-b75f-488eb11eb38b",
      "name": "Set: Text Input",
      "type": "n8n-nodes-base.set",
      "position": [
        384,
        912
      ]
    },
    {
      "id": "9850615f-f28d-4b68-8fe2-fbf704172667",
      "name": "Set: Voice Input (Text)",
      "type": "n8n-nodes-base.set",
      "position": [
        496,
        1072
      ]
    },
    {
      "id": "8cbe3328-cdd1-4773-90ad-4822859ddba1",
      "name": "AI: Extract Expenses",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        832,
        1040
      ]
    },
    {
      "id": "cd20d803-47a3-496b-8160-0052c6b50ef4",
      "name": "Split: Entries to Rows",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        1216,
        1040
      ]
    },
    {
      "id": "a1e5d645-da07-479c-84c7-5e6ad67d2f7c",
      "name": "Telegram: Send error message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -144,
        1392
      ]
    },
    {
      "id": "076077d4-a0c9-4800-aa1e-1f455255a8db",
      "name": "Gemini: Analyze an image",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        272,
        1264
      ]
    },
    {
      "id": "fe77a802-f56e-4fae-ae7c-0c6dabf43d2c",
      "name": "Set: image Input (Text)",
      "type": "n8n-nodes-base.set",
      "position": [
        496,
        1264
      ]
    },
    {
      "id": "3c907845-b556-4a13-a93b-1319e953e001",
      "name": "Route: Text, Voice or Image?",
      "type": "n8n-nodes-base.switch",
      "position": [
        -384,
        1136
      ]
    },
    {
      "id": "45416109-6e88-4b09-8327-bea0d9878b7e",
      "name": "Auto-Fix JSON",
      "type": "@n8n/n8n-nodes-langchain.outputParserAutofixing",
      "position": [
        880,
        1248
      ]
    },
    {
      "id": "6c8d0ca0-9e88-41d7-9692-32b3751c70b0",
      "name": "AI Helper: Define Schema",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        992,
        1392
      ]
    },
    {
      "id": "95435178-b029-4319-a886-7a0aef028363",
      "name": "Telegram: Get Image File",
      "type": "n8n-nodes-base.telegram",
      "position": [
        64,
        1264
      ]
    },
    {
      "id": "a0d74a66-0e2f-460a-ada8-c52c1a38535b",
      "name": "Start: On Telegram Message",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -608,
        1168
      ]
    },
    {
      "id": "44724e36-7f53-4e42-b588-c7a808f57f70",
      "name": "Set: Extract Output",
      "type": "n8n-nodes-base.set",
      "position": [
        1632,
        1056
      ]
    },
    {
      "id": "b2122f43-7eaf-4d09-ba73-b756fa8d2863",
      "name": "If null?",
      "type": "n8n-nodes-base.if",
      "position": [
        1424,
        1152
      ]
    },
    {
      "id": "b4d6dc9a-d623-455d-8fd5-a2f757229a07",
      "name": "Telegram: Send Null",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1616,
        1280
      ]
    }
  ],
  "connections": {
    "If null?": {
      "main": [
        [
          {
            "node": "Set: Extract Output",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Telegram: Send Null",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Auto-Fix JSON": {
      "ai_outputParser": [
        [
          {
            "node": "AI: Extract Expenses",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Set: Text Input": {
      "main": [
        [
          {
            "node": "AI: Extract Expenses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "LLM: Gemini Flash": {
      "ai_languageModel": [
        [
          {
            "node": "Auto-Fix JSON",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "AI: Extract Expenses",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "GSheet: Log Expense": {
      "main": [
        [
          {
            "node": "Telegram: Send Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set: Extract Output": {
      "main": [
        [
          {
            "node": "GSheet: Log Expense",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI: Extract Expenses": {
      "main": [
        [
          {
            "node": "Split: Entries to Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split: Entries to Rows": {
      "main": [
        [
          {
            "node": "If null?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set: Voice Input (Text)": {
      "main": [
        [
          {
            "node": "AI: Extract Expenses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set: image Input (Text)": {
      "main": [
        [
          {
            "node": "AI: Extract Expenses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Helper: Define Schema": {
      "ai_outputParser": [
        [
          {
            "node": "Auto-Fix JSON",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Gemini: Analyze an image": {
      "main": [
        [
          {
            "node": "Set: image Input (Text)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini: Transcribe Voice": {
      "main": [
        [
          {
            "node": "Set: Voice Input (Text)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram: Get Image File": {
      "main": [
        [
          {
            "node": "Gemini: Analyze an image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram: Get Voice File": {
      "main": [
        [
          {
            "node": "Gemini: Transcribe Voice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start: On Telegram Message": {
      "main": [
        [
          {
            "node": "Route: Text, Voice or Image?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route: Text, Voice or Image?": {
      "main": [
        [
          {
            "node": "Set: Text Input",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Telegram: Get Voice File",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Telegram: Get Image File",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Telegram: Send error message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}