{
  "id": "CvIOr50bDG2t7vHO",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Automated Financial Reporting Using Google Vision OCR, Telegram & Google Sheets",
  "tags": [],
  "nodes": [
    {
      "id": "1e4b5f2c-827a-40da-b0b5-cf6405d3d41c",
      "name": "Telegram Trigger",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -4080,
        -320
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "4a22cbd2-7888-4098-a9d0-8fc4726ac537",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        -3860,
        -320
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a4be3cda-799d-4413-9946-a837832e5e3d",
              "operator": {
                "type": "boolean",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.message.photo }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "d895590f-7790-47f1-af15-a18fc8b51492",
      "name": "Get Path",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -3280,
        -440
      ],
      "parameters": {
        "url": "=https://api.telegram.org/bot{{ $json.telegramToken }}/getFile?file_id={{ $('Telegram Trigger').item.json.message.photo.slice(-1)[0].file_id }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "aa36a70e-f6a5-495c-8ae4-83fe3dc5ea60",
      "name": "Get URL",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -3100,
        -440
      ],
      "parameters": {
        "url": "=https://api.telegram.org/file/bot{{ $('Set Telegram Token').item.json.telegramToken }}/{{ $json.result.file_path }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "ee19459b-b8f0-4e9f-940f-3c165898f744",
      "name": "Set Vision API",
      "type": "n8n-nodes-base.set",
      "position": [
        -2720,
        -440
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "586cf442-13be-4996-9824-366e20ab864e",
              "name": "visionAPI",
              "type": "string",
              "value": "YOUR_GOOGLE_VISION_API_KEY"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "cf01bb03-cb8d-467b-b6e9-c8f8c3127ac1",
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2500,
        -440
      ],
      "parameters": {
        "url": "=https://vision.googleapis.com/v1/images:annotate?key={{ $json.visionAPI }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"requests\": [\n    {\n      \"image\": {\n        \"content\": \"{{ $('Code').item.json.base64 }}\"\n      },\n      \"features\": [\n        {\n          \"type\": \"TEXT_DETECTION\"\n        }\n      ]\n    }\n  ]\n}\n",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2
    },
    {
      "id": "a8137a20-d135-4bb4-a010-dd77bb390d41",
      "name": "Code",
      "type": "n8n-nodes-base.code",
      "position": [
        -2920,
        -440
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Ini untuk Function Item node\nconst base64 = item.binary.data.data; // 'data' adalah nama binary\nreturn {\n  json: {\n    base64\n  }\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "b8cc498e-3716-4cd2-8775-11fdbfb2d7f0",
      "name": "Basic LLM Chain",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        -2280,
        -440
      ],
      "parameters": {
        "text": "={{ $json.responses[0].fullTextAnnotation }}",
        "batching": {},
        "messages": {
          "messageValues": [
            {
              "message": "=You are a professional accountant experienced in preparing financial reports and classifying expenses into appropriate categories.\nYou will receive input data extracted via OCR that needs to be parsed and structured.\n\nInstructions:\nAlways generate the output using the same language as the input.\nAnalyze the input and extract relevant fields such as:\nDate\nCategory\nStore Name\nStore Address\nInvoice Number\nProduct Name\nQuantity\nUnit Price\nTotal Amount\nIf any data is missing or not detected, return: 'not found' for text fields and 0 for numerical values\nIf the date is not present, use current date."
            }
          ]
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.7
    },
    {
      "id": "1ab8b159-83c8-41c1-a714-c459b2967d05",
      "name": "OpenRouter Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        -2280,
        -240
      ],
      "parameters": {
        "model": "google/gemini-2.0-flash-exp:free",
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "542b2f21-8a8f-4110-b0d1-c02642fe5809",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -2120,
        -240
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"Date\": \"2025-07-07\",\n  \"Id\": \"4821-INV-001234\",\n  \"Category\": \"Auto-generated category\",\n  \"Vendor\": \"Vendor Name\",\n  \"Vendor Address\": \"Vendor Address\",\n  \"Invoice Number\": \"INV-001234\",\n  \"Items\": [\n    {\n      \"Product\": \"Product 1\",\n      \"Quantity\": 2,\n      \"Unit Price\": 10000,\n      \"Total\": 20000\n    },\n    {\n      \"Product\": \"Product 2\",\n      \"Quantity\": 1,\n      \"Unit Price\": 20000,\n      \"Total\": 20000\n    },\n    {\n      \"Product\": \"Product 3\",\n      \"Quantity\": 3,\n      \"Unit Price\": 12000,\n      \"Total\": 36000\n    }\n  ]\n}\n"
      },
      "typeVersion": 1.3
    },
    {
      "id": "6dd87457-4afd-41ef-b0ee-0ddfff83f94a",
      "name": "Append or update row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1480,
        -440
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $('Code1').item.json.output.Date }}",
            "Total": "={{ $json.Total }}",
            "Vendor": "={{ $('Code1').item.json.output.Vendor }}",
            "Product": "={{ $json.Product }}",
            "Category": "={{ $('Code1').item.json.output.Category }}",
            "Quantity": "={{ $json.Quantity }}",
            "Unit Price": "={{ $json['Unit Price'] }}",
            "Invoice Number": "={{ $('Code1').item.json.output['Invoice Number'] }}",
            "Vendor Address": "={{ $('Code1').item.json.output['Vendor Address'] }}"
          },
          "schema": [
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Invoice Number",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Invoice Number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Category",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Category",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Vendor",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Vendor",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Vendor Address",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Vendor Address",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Product",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Product",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Quantity",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Quantity",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Unit Price",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Unit Price",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Total",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Invoice Number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "11oT95lKoGNFlZtV129ampaBNOxnnKAJnUn1fAlqYZvY"
        }
      },
      "executeOnce": false,
      "typeVersion": 4.6
    },
    {
      "id": "50783998-dd2e-4597-98e0-6f5e9892d69a",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -1680,
        -440
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "output.Items"
      },
      "typeVersion": 1
    },
    {
      "id": "a15f4030-bf82-439e-84b3-39752d2e9017",
      "name": "Basic LLM Chain1",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        -1920,
        20
      ],
      "parameters": {
        "text": "={{ $json.output }}",
        "batching": {},
        "messages": {
          "messageValues": [
            {
              "message": "=Please write the following transaction details neatly so that they are easy for users to understand. Display all items and the total purchase amount. Write in plain text without additional punctuation. Use emojis for greater interaction."
            }
          ]
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "e18b01e4-d88f-4b89-aa24-8e1eeaccf70d",
      "name": "OpenRouter Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        -1920,
        220
      ],
      "parameters": {
        "model": "google/gemini-2.0-flash-exp:free",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "e8754a00-1761-42b6-a768-489e21895044",
      "name": "Send a text message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -1560,
        20
      ],
      "parameters": {
        "text": "={{ $json.text }}",
        "chatId": "={{ $('Telegram Trigger').item.json.message.from.id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "6d0388c7-5995-463f-95e8-ea2f0ae3f22e",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -3520,
        100
      ],
      "parameters": {
        "text": "={{ $json.message.text }}",
        "options": {
          "systemMessage": "=You are a professional accountant skilled in financial reporting. You are currently having a conversation with {{ $json.message.from.first_name }}. Always use data to answer questions. Write in plain text without punctuation, and use emojis for greater interaction."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2
    },
    {
      "id": "64819421-164f-4b66-8f38-f12f30d67877",
      "name": "Get row(s) in sheet in Google Sheets",
      "type": "n8n-nodes-base.googleSheetsTool",
      "position": [
        -3280,
        320
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "11oT95lKoGNFlZtV129ampaBNOxnnKAJnUn1fAlqYZvY"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "a4dcf0e8-bfb1-49d1-b198-eb578334accc",
      "name": "OpenRouter Chat Model2",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        -3520,
        320
      ],
      "parameters": {
        "model": "google/gemini-2.0-flash-exp:free",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "fb81aa66-2d80-42c6-b391-584097b42c02",
      "name": "Send a text message1",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -3180,
        100
      ],
      "parameters": {
        "text": "={{ $json.output }}",
        "chatId": "={{ $('Telegram Trigger').item.json.message.from.id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "d3d431c6-5492-4aa7-a814-eac634407391",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        -3440,
        320
      ],
      "parameters": {
        "sessionKey": "={{ $('Telegram Trigger').item.json.message.from.id }}",
        "sessionIdType": "customKey",
        "contextWindowLength": 10
      },
      "typeVersion": 1.3
    },
    {
      "id": "6e737840-75f2-4ef7-a108-f8a232d60a72",
      "name": "Code1",
      "type": "n8n-nodes-base.code",
      "position": [
        -1920,
        -440
      ],
      "parameters": {
        "jsCode": "function cleanNumber(n) {\n  return parseInt(n.toString().replace(/[.,]/g, '')) || 0;\n}\n\nconst items = $json.output.Items.map(item => ({\n  ...item,\n  Quantity: cleanNumber(item.Quantity),\n  \"Unit Price\": cleanNumber(item[\"Unit Price\"]),\n  Total: cleanNumber(item.Total),\n}));\n\nreturn {\n  json: {\n    output: {\n      ...$json.output,\n      Items: items\n    }\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "0a96b324-9e24-45e4-99cf-8b2822f91242",
      "name": "Send a text message2",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -2500,
        -620
      ],
      "parameters": {
        "text": "Data is being processed . . .",
        "chatId": "={{ $('Telegram Trigger').item.json.message.from.id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "46f7fdaa-5fe3-49f1-8e1e-9e8cd0ac559a",
      "name": "Set Telegram Token",
      "type": "n8n-nodes-base.set",
      "position": [
        -3520,
        -440
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "586cf442-13be-4996-9824-366e20ab864e",
              "name": "telegramToken",
              "type": "string",
              "value": "YOUR_TELEGRAM_BOT_TOKEN"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "119c9b9d-26cb-4578-bc5f-6ef756fd08c7",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4720,
        -760
      ],
      "parameters": {
        "color": 6,
        "width": 580,
        "height": 1020,
        "content": "## Automated Financial Reporting Using Google Vision OCR, Telegram & Google Sheets\n\n\nThis workflow automates the process of recording financial transactions from photos of receipts or shopping receipts. Users simply send an image of the receipt via Telegram. The image is processed using the Google Vision API to detect text, then extracted and structured by LLM via OpenRouter. The final result is saved to Google Sheets and also displayed to the user via a Telegram bot.\n\n**\ud83e\uddfe Google Sheets Template**\nCreate a Google Sheet using this template: [Financial Reporting](https://docs.google.com/spreadsheets/d/11oT95lKoGNFlZtV129ampaBNOxnnKAJnUn1fAlqYZvY/edit?usp=sharing)\n\n## \ud83d\udee0\ufe0f Key Features\n- The workflow starts when a user sends a photo of a receipt to the Telegram bot.\n- The image is converted to text using the Google Vision API's OCR.\n- Data processing with LLM (OpenRouter) helps identify and structure transaction elements such as: date, vendor name & address, receipt/invoice number, item list (product name, quantity, unit price, total), and transaction category.\n- Cleaned and structured data is automatically recorded to Google Sheets per item.\n- The system also sends a summary of the recording results in an easy to read text format.\n- Users can also send text messages to the bot to query stored transaction data, which will be answered by a Google Sheets-based AI Agent.\n\n## \ud83d\udd27 Requirements\n- Active Telegram Bot + API Token\n- Google Vision API Key\n- OpenRouter Account + API Key\n- Google Sheets connected to n8n\n\n## \ud83e\udde9 Setup Instructions\n1. Replace all API keys and tokens with your own in the relevant nodes.\n   - Google Vision API Key: Set in 'Set Vision API' node.\n   - Telegram Bot Token: Set in 'Set Telegram Token' node and all Telegram nodes.\n   - OpenRouter API Key: Set in all OpenRouter nodes.\n   - Google Sheets: Connect your own Google Sheets credential.\n2. Use the provided Google Sheets template or your own.\n3. Activate the workflow after configuration.\n4. (Optional) Review sticky notes for step-by-step explanations.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "500572a3-af19-4d22-87c2-99a16803ada1",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3580,
        -620
      ],
      "parameters": {
        "width": 220,
        "height": 340,
        "content": "Store the Telegram bot API token as a variable (telegram Token) so that it can be used by subsequent nodes without repeated hardcoding."
      },
      "typeVersion": 1
    },
    {
      "id": "ea7c2f1c-1667-43c5-a32a-018ee7fa693b",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3300,
        -660
      ],
      "parameters": {
        "color": 4,
        "width": 500,
        "height": 380,
        "content": "- Retrieves the file path (image) from Telegram by accessing the getFile endpoint. This path is needed so we can download the image file from the Telegram server.\n- After obtaining the file_path, this node accesses the direct URL to download the image file from the Telegram server.\n- Next, it retrieves the binary image data from the previous node and converts it to a base64 string, which is required by the Google Vision API for the OCR process."
      },
      "typeVersion": 1
    },
    {
      "id": "41fb4adb-7a5a-418d-a4f6-ee37ccf67ec0",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2760,
        -880
      ],
      "parameters": {
        "color": 6,
        "width": 400,
        "height": 600,
        "content": "- Save the Google Vision API key into a variable named visionAPI. This variable will later be used to dynamically call the OCR endpoint, without having to specify the API key directly in the URL.\n- Send a POST request to the Google Vision API endpoint. The sent data contains the image in base64 format from the previous node (Code) and uses TEXT_DETECTION as the OCR feature.\n- Send a message to the Telegram user as a notification that the data is being processed. This provides immediate feedback so the user knows the workflow is running."
      },
      "typeVersion": 1
    },
    {
      "id": "c6508f4d-0ad4-4d93-939d-170a322d1f61",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2320,
        -560
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 480,
        "content": "Using LLM (Language Model) to process OCR text from Google Vision API (fullTextAnnotation) and convert it into structured data."
      },
      "typeVersion": 1
    },
    {
      "id": "45b230e7-a528-4568-a834-c14f6c15b492",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1940,
        -640
      ],
      "parameters": {
        "color": 4,
        "width": 640,
        "height": 380,
        "content": "- Cleans numeric data from characters such as periods or commas (common in receipt pricing formats), then converts them to whole numbers (integers).\n- Splits the Items[] array (containing products per row) into separate items so they can be recorded individually in rows in Google Sheets.\n- Adds product data one by one to Google Sheets based on a predefined structure. If there are any duplicate Invoice Numbers, the data will be updated."
      },
      "typeVersion": 1
    },
    {
      "id": "29c7a276-4ed9-4b44-88eb-5e4bf67f704d",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1940,
        -100
      ],
      "parameters": {
        "width": 640,
        "height": 480,
        "content": "- Converts parsed transaction data into a human readable text summary.\n- Sends the summary results from LLM to Telegram users."
      },
      "typeVersion": 1
    },
    {
      "id": "87ac24f9-94ef-4a50-935e-a67d2d79a950",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3540,
        0
      ],
      "parameters": {
        "color": 2,
        "width": 500,
        "height": 480,
        "content": "Providing text based interaction features with users on Telegram, this agent is designed as a financial assistant that answers user questions based on transaction data previously recorded in Google Sheets."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "c939f754-70a0-4f7e-9f8f-7811cf218ce8",
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Set Telegram Token",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code": {
      "main": [
        [
          {
            "node": "Set Vision API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code1": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get URL": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Send a text message1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Path": {
      "main": [
        [
          {
            "node": "Get URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "Append or update row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Set Vision API": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          },
          {
            "node": "Send a text message2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Basic LLM Chain": {
      "main": [
        [
          {
            "node": "Basic LLM Chain1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Code1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Basic LLM Chain1": {
      "main": [
        [
          {
            "node": "Send a text message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Telegram Token": {
      "main": [
        [
          {
            "node": "Get Path",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Basic LLM Chain1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model2": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s) in sheet in Google Sheets": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  }
}