{
  "name": "Catat Keuangan Keluarga",
  "nodes": [
    {
      "parameters": {
        "content": "### Note\nSend response immediately to prevent request timeout",
        "height": 96,
        "width": 224
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1040,
        -608
      ],
      "typeVersion": 1,
      "id": "a16909ca-c280-4739-8f45-c8c4e14c7f00",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "content": "## Telegram Environment Variable\n\n- `TELEGRAM_WHITELIST_CHAT_IDS`\n`array` of `number` telegram chat_id only whitelisted chat_id will be process\n",
        "height": 192,
        "width": 320
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -784,
        -848
      ],
      "typeVersion": 1,
      "id": "6377267c-c306-4cfc-a2e9-51ea66590775",
      "name": "Sticky Note1"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "168dfea0-cd85-411d-a5ff-0ed308aef03e",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1008,
        -1024
      ],
      "id": "8428dc2d-9e4d-4286-bf96-4d0dd87145e9",
      "name": "telegram webhook",
      "alwaysOutputData": false,
      "retryOnFail": false
    },
    {
      "parameters": {
        "respondWith": "noData",
        "options": {
          "responseCode": 204,
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "no-content"
              }
            ]
          }
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [
        -1024,
        -768
      ],
      "id": "4cf40289-1e84-447c-afc8-1d9cf72f81d2",
      "name": "response telegram webhook"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "34411d36-21cf-4bb0-8bec-bc40f451707f",
              "name": "TELEGRAM_WHITELIST_CHAT_IDS",
              "value": "={{ [12345] }}",
              "type": "array"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -784,
        -1024
      ],
      "id": "e5d108b9-2e5c-4268-827b-4f50c74c8105",
      "name": "telegram environment",
      "alwaysOutputData": false
    },
    {
      "parameters": {
        "content": "## Environment Variable\n\n- `ENV`\n`string` production or development\nif'production' - mean only production trigger will be process\n- `REPORT_URL`\n`string` url report if user ask to laporan\n- `TIMEZONE`\n`string` timezone",
        "height": 240,
        "width": 320
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        176,
        0
      ],
      "typeVersion": 1,
      "id": "c72ccc2c-389b-4297-a97f-b09cbe9910f5",
      "name": "Sticky Note2"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "89f07450-b558-43e4-a32e-c5f697f2ce3f",
              "name": "ENV",
              "value": "development",
              "type": "string"
            },
            {
              "id": "57917086-0e8d-4959-a7ea-5e18ad27454c",
              "name": "REPORT_URL",
              "value": "",
              "type": "string"
            },
            {
              "id": "ed460189-4235-42bf-bef5-27b69d9f78a1",
              "name": "TIMEZONE",
              "value": "Asia/Jakarta",
              "type": "string"
            },
            {
              "id": "9304c86b-9417-4c79-bff0-b5da34306faa",
              "name": "meta",
              "value": "={{ { start: $now } }}",
              "type": "object"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        288,
        -160
      ],
      "id": "3be22afe-07c3-4281-a11c-d2b64cbb3385",
      "name": "environment"
    },
    {
      "parameters": {
        "content": "# TELEGRAM WEBHOOK",
        "height": 80,
        "width": 752
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -992,
        -1120
      ],
      "typeVersion": 1,
      "id": "afd9b61f-516a-4a54-9a92-48a5483e9b28",
      "name": "Sticky Note3"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "304ae319-9597-4e75-8c6c-6cf567d1f901",
              "leftValue": "={{ 'message' in $json.body }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            },
            {
              "id": "db70592e-3019-4f68-8d04-70cce01ac829",
              "leftValue": "={{ $json.TELEGRAM_WHITELIST_CHAT_IDS }}",
              "rightValue": "={{ $json.body.message.chat.id }}",
              "operator": {
                "type": "array",
                "operation": "contains",
                "rightType": "any"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2.2,
      "position": [
        -560,
        -1024
      ],
      "id": "0856f9c3-07bd-423d-8435-b20472d1f821",
      "name": "telegram middleware"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "b81d37a7-ed28-44f6-aa19-167e38461715",
              "name": "data",
              "value": "={{ {\n  from: \"telegram\",\n  message_id: $json.body.message.message_id,\n  chat_id: $json.body.message.chat.id,\n  session_id: \"telegram-\"+$json.body.message.chat.id.toString(),\n  text: $json.body.message.text\n} }}",
              "type": "object"
            },
            {
              "id": "e7dbd7ad-1b71-46e7-a041-c0f20e4eaf49",
              "name": "env",
              "value": "={{ $json.executionMode }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -336,
        -1024
      ],
      "id": "246a992b-1d72-414d-bb4c-430c6a761c62",
      "name": "telegram parser"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "9eb240b0-c0d2-40a0-b498-dd9e98b862fb",
              "leftValue": "={{ $json.ENV == 'production' ? $json.env == \"production\" : true }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2.2,
      "position": [
        496,
        -160
      ],
      "id": "8ad32953-7f5d-4e4c-8faa-54ab8b4b249d",
      "name": "middleware"
    },
    {
      "parameters": {
        "content": "# CHAT",
        "height": 80,
        "width": 150
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -992,
        -256
      ],
      "typeVersion": 1,
      "id": "bf42e8d0-b02a-4c48-a3e3-3ddf24a62597",
      "name": "Sticky Note4"
    },
    {
      "parameters": {
        "options": {
          "responseMode": "responseNodes"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "typeVersion": 1.3,
      "position": [
        -1008,
        -160
      ],
      "id": "1b4d0aae-d64b-41f7-9574-6314d6470fd3",
      "name": "chat trigger"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "b81d37a7-ed28-44f6-aa19-167e38461715",
              "name": "data",
              "value": "={{ {\n  from: \"chat\",\n  session_id: \"chat\"+$json.sessionId,\n  text: $json.chatInput,\n  env: \"development\"\n} }}",
              "type": "object"
            },
            {
              "id": "e7dbd7ad-1b71-46e7-a041-c0f20e4eaf49",
              "name": "env",
              "value": "={{ $json.executionMode }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -784,
        -160
      ],
      "id": "f3e1ced5-589b-4046-9958-d9c39dbf7dbc",
      "name": "chat parser"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=# DATA\nnow = {{ $now.toUTC().toISO() }}\n\n# INPUT USER\n{{ $json.data.text }}",
        "options": {
          "systemMessage": "Kamu adalah \"FinClassify\", AI yang menentukan maksud teks pengguna keluarga muda Indonesia (usia 25\u201330 th).\n\nKembalikan **satu kata saja (huruf besar semua):**\nPENCATATAN / LAPORAN / CUSTOM\n\nAturan:\n- PENCATATAN \u2192 hanya jika teks berisi nominal (contoh: 10rb, Rp50.000) atau konteks transaksi (beli, bayar, gajian, bonus, top up, dll).\n- LAPORAN \u2192 jika teks minta data, total, ringkasan, saldo, statistik, laporan, perbandingan, dsb.\n- CUSTOM \u2192 untuk semua selain itu.  \n  Jika tidak ada nominal **dan** tidak ada konteks keuangan, pilih CUSTOM.\n\nContoh:\n\"Aku beli bensin 50 ribu\" \u2192 PENCATATAN  \n\"Total bulan lalu berapa?\" \u2192 LAPORAN  \n\"Aku capek banget kerja\" \u2192 CUSTOM"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3,
      "position": [
        720,
        -160
      ],
      "id": "377be39e-0624-409d-bcf1-b5aaff362b5d",
      "name": "Clasification Agent",
      "alwaysOutputData": false
    },
    {
      "parameters": {
        "modelName": "models/gemini-2.5-flash-preview-09-2025",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        912,
        448
      ],
      "id": "3edccfb7-f586-4dcd-9e67-ac9047b0dab4",
      "name": "Google Gemini Chat Model",
      "credentials": {}
    },
    {
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"title\": \"FinExtractOutput\",\n  \"description\": \"Schema for structured financial transaction data extracted by FinExtract.\",\n  \"type\": \"array\",\n  \"minItems\": 1,\n  \"items\": {\n    \"type\": \"object\",\n    \"required\": [\"type\", \"name\", \"date\", \"amount\", \"qty\", \"total\", \"labels\"],\n    \"properties\": {\n      \"type\": {\n        \"type\": \"string\",\n        \"enum\": [\"in\", \"out\", \"saving\", \"withdraw\"],\n        \"description\": \"Transaction direction: 'in' for income, 'out' for expense, 'saving' for saving money.\"\n      },\n      \"name\": {\n        \"type\": \"string\",\n        \"minLength\": 1,\n        \"description\": \"Readable transaction title, e.g. 'Pembayaran listrik'.\"\n      },\n      \"date\": {\n        \"type\": \"string\",\n        \"pattern\": \"^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}(\\\\.\\\\d+)?\\\\+07:00$\",\n        \"description\": \"Transaction date in ISO8601 format with Asia/Jakarta timezone (+07:00).\"\n      },\n      \"amount\": {\n        \"type\": \"number\",\n        \"description\": \"Unit price or income amount can minus.\"\n      },\n      \"qty\": {\n        \"type\": \"integer\",\n        \"minimum\": 1,\n        \"default\": 1,\n        \"description\": \"Quantity of items or units.\"\n      },\n      \"total\": {\n        \"type\": \"number\",\n        \"description\": \"Total amount = amount \u00d7 qty can minus.\"\n      },\n      \"labels\": {\n        \"type\": \"array\",\n        \"minItems\": 1,\n        \"items\": {\n          \"type\": \"string\",\n          \"minLength\": 1\n        },\n        \"description\": \"List of category tags such as ['makanan', 'tagihan', 'transportasi'].\"\n      }\n    },\n    \"additionalProperties\": false\n  }\n}\n"
      },
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "typeVersion": 1.3,
      "position": [
        1488,
        320
      ],
      "id": "6807524c-fd7c-495d-bfc2-01b187f10465",
      "name": "Parse Output"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.output }}",
                    "rightValue": "LAPORAN",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "41443236-5a09-49fc-861f-cbb9bdd739f2"
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "2cdcfe1b-f3ba-4f49-a22f-26aa668a8440",
                    "leftValue": "={{ $json.output }}",
                    "rightValue": "CUSTOM",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "602c2285-de3c-48ba-a0da-30b634cf0152",
                    "leftValue": "={{ $json.output }}",
                    "rightValue": "PENCATATAN",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            }
          ]
        },
        "options": {
          "allMatchingOutputs": false
        }
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.3,
      "position": [
        1072,
        -176
      ],
      "id": "bbe679b9-ff1c-4fcc-a5c2-fc8e4af23082",
      "name": "Switch"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "bc1ca612-b629-4b91-b020-7868cb4d953b",
              "name": "action",
              "value": "record",
              "type": "string"
            },
            {
              "id": "45bedb6b-d974-4a80-9788-080c64d1a59e",
              "name": "items",
              "value": "={{ $json.output }}",
              "type": "array"
            },
            {
              "id": "d4c3d14a-4ac4-4ab3-8212-cca603d6184b",
              "name": "i",
              "value": 0,
              "type": "number"
            },
            {
              "id": "5b5a88b8-029b-471a-96e0-98eea281f369",
              "name": "results",
              "value": "={{ {storage: \"\", data: [], total: 0, saving: 0} }}",
              "type": "object"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1696,
        80
      ],
      "id": "5aa06da6-f409-4192-9fac-14f850fd8adc",
      "name": "record parser"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "f6bad1a0-852e-430c-9cb6-354ff10b9299",
              "name": "reply",
              "value": "={{ $json.output }}",
              "type": "string"
            },
            {
              "id": "c23d2e36-9957-437e-9d03-785407572311",
              "name": "action",
              "value": "custom",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1696,
        -160
      ],
      "id": "009d5beb-cd45-42f2-9f09-5dc16534f88f",
      "name": "custom parser"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "180f2a6a-a7cc-4724-9bf9-fc58c578f9da",
              "name": "reply",
              "value": "={{ ((url) => {\n\nif (!url || !url.length) {\n  return \"Sorry bos, laporan e gurung samean setting\";\n}\n\nreturn `Iki bos, di delok dewe laporan e ${url}`;\n\n})($('environment').item.json.REPORT_URL) }}",
              "type": "string"
            },
            {
              "id": "05e98519-cc89-43f5-87a4-209513dbb770",
              "name": "action",
              "value": "laporan",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1696,
        -400
      ],
      "id": "fb428698-36bf-438a-8abf-6b9cd82cdd2c",
      "name": "report generator"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.from }}",
                    "rightValue": "telegram",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "b19a9ce9-b46d-45c4-9286-b6bfa1a967bb"
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "e12ef3e2-3deb-49e9-bb5b-248410ed2daf",
                    "leftValue": "={{ $json.from }}",
                    "rightValue": "chat",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            }
          ]
        },
        "options": {
          "allMatchingOutputs": true
        }
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.3,
      "position": [
        2384,
        -160
      ],
      "id": "d373035b-29b7-4b25-9e3e-ef6b6d1aca91",
      "name": "reply manager"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "1ee6025c-6fa9-4b0c-857d-ce653995e978",
              "name": "reply",
              "value": "={{ ((datas) => {\n  const f = new Intl.NumberFormat(\"id-ID\",  { style: \"currency\", currency: \"IDR\" });\n\n  const replys = [\n    \"Aman bos, wes tak catet\",\n    datas.map((data) => [\n      \"\\n\\n-----------------------\",\n      `Type: ${data.action}`,\n      `Nama: ${data.name}`,\n      `Tanggal: ${new Date(data.date).toLocaleString(\"id-ID\", { timeZone: \"Asia/Jakarta\" })}`,\n      `Nominal: ${f.format(data.amount)}`,\n      `Qty: ${data.qty}`,\n      `Total: ${f.format(data.total)}`,\n      `Labels: ${data.labels.join(\", \")}`,\n    ].join(\"\\n\")).join(\"\\n\"),\n    \"\\n\\n-----------------------\",\n  ];\n\n  if ($('save balance').isExecuted) {\n    const balance = $('save balance').item.json.balance;\n    replys.push(`Saldo: ${f.format(balance)}`)\n  }\n\n  if ($('save saving').isExecuted) {\n    const saving = $('save saving').item.json.saving;\n    replys.push(`Tabungan: ${f.format(saving)}`)\n  }\n\n  return replys.join(\"\\n\")\n\n})($('loop check').item.json.results.data) }}",
              "type": "string"
            },
            {
              "id": "7c64accf-53ca-4653-a978-17f04d97b552",
              "name": "action",
              "value": "record",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3472,
        736
      ],
      "id": "57fe77db-4ac1-43a7-bc55-d2784a58c719",
      "name": "generate reply"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "43f2399e-9764-456d-a3dc-a29b98efc52e",
              "name": "from",
              "value": "={{ $('environment').item.json.data.from }}",
              "type": "string"
            },
            {
              "id": "cb719531-8e44-45b9-9720-cd6f6f4a29b5",
              "name": "session_id",
              "value": "={{ $('environment').item.json.data.session_id }}",
              "type": "string"
            },
            {
              "id": "53928e9e-bb80-4290-a75c-41c575d9a511",
              "name": "message_id",
              "value": "={{ $('environment').item.json.data.message_id }}",
              "type": "string"
            },
            {
              "id": "44c4f1ea-a300-48ea-b37a-1d200822464e",
              "name": "chat_id",
              "value": "={{ $('environment').item.json.data.chat_id }}",
              "type": "string"
            },
            {
              "id": "4d26c872-e120-4cb3-b19a-7376cd6c9877",
              "name": "reply",
              "value": "={{ ((reply) => {\n\n  const start = new Date($('environment').item.json.meta.start);\n  const end = new Date();\n  const ms = end - start;\n  if (isNaN(ms) || ms < 0) {\n    return reply;\n  }\n\n  const seconds = Math.floor(ms / 1000);\n  const minutes = Math.floor(seconds / 60);\n  const hours = Math.floor(minutes / 60);\n\n  const displayMs = ms % 1000;\n  const displayS = seconds % 60;\n  const displayM = minutes % 60;\n  const displayH = hours;\n\n  return (\n    reply +\n    \"\\n\\n-----------------\\n\" +\n    `eksekusi = ${displayM}m ${displayS}d ${displayMs}md`\n  );\n})($json.reply) }}",
              "type": "string"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1936,
        -160
      ],
      "id": "7c621e7a-fa6c-4b02-b52e-1ea8f0c03b69",
      "name": "reply"
    },
    {
      "parameters": {
        "sessionIdType": "customKey",
        "sessionKey": "={{ $('environment').item.json.data.session_id }}"
      },
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.3,
      "position": [
        1296,
        320
      ],
      "id": "1f11dc11-a2d3-451f-93df-dd0872782bd3",
      "name": "Simple Memory"
    },
    {
      "parameters": {
        "content": "## input requirement\n\n- `data` field must be `object` contains\n\n  ```ts\n  {\n    // indicate where data comming from\n    // e.g `telegram` | `chat`\n    from: string,\n    // global unique string for session_id\n    // e.g `telegram-1000032`\n    session_id: string, \n    // user input\n    text: string,\n    // some additional datas\n    ...\n  }\n  ```",
        "height": 384,
        "width": 624
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        208,
        -576
      ],
      "typeVersion": 1,
      "id": "fc050b5d-4a8f-4240-950a-192cb297c9b8",
      "name": "Sticky Note5"
    },
    {
      "parameters": {
        "chatId": "={{ $json.chat_id }}",
        "text": "={{ $json.reply }}",
        "additionalFields": {
          "appendAttribution": false,
          "reply_to_message_id": "={{ $json.action == \"record\" ? $json.message_id : null }}"
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        2800,
        -320
      ],
      "id": "fa39ec07-c6a2-4e86-a9a6-256433be53a4",
      "name": "reply telegram",
      "credentials": {}
    },
    {
      "parameters": {
        "message": "={{ $json.reply }}",
        "waitUserReply": false,
        "options": {
          "memoryConnection": false
        }
      },
      "type": "@n8n/n8n-nodes-langchain.chat",
      "typeVersion": 1,
      "position": [
        2800,
        -144
      ],
      "id": "bdf6d82a-7ff8-45ce-b72a-10cb5127dea8",
      "name": "reply chat"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Ubah teks menjadi array JSON valid (minified, tanpa spasi atau teks tambahan) berisi satu atau lebih objek transaksi:\n{\n  \"type\": \"in\" | \"out\" | \"saving\" | \"withdraw\",\n  \"name\": string,\n  \"date\": string, // ISO8601 denga timezone {{ $('environment').item.json.TIMEZONE }}\n  \"amount\": number,\n  \"qty\": number,\n  \"total\": number,\n  \"labels\": string[]\n}\n\nAturan:\n- type: \"in\" untuk pemasukan (gajian, dapat, jual, transfer masuk)\n- type: \"out\" untuk pengeluaran (beli, bayar, langganan, top up, traktir, dll)\n- type: \"saving\" untuk tambah tabungan pribadi (nabung, ditabung, menabung)\n- type: \"withdraw\" untuk ambil tabungan pribadi (ambil tabungan, dari tabungan) nominal dan total selalu bernilai minus\n- name: ubah jadi kalimat natural (contoh: \u201cbayar listrik\u201d \u2192 \u201cPembayaran listrik\u201d)\n- amount: harga satuan; ubah nominal lokal ke angka (mis. \u201c50 ribu\u201d \u2192 50000)\n- qty: jumlah item, default 1 jika tidak disebut, selalu 1 untuk tipe \"saving\"\n- total: amount \u00d7 qty (atau total langsung jika disebut)\n- labels: kategori salah satu dari (Tempat Tinggal, Utilitas, Pangan, Transportasi, Kesehatan, Pendidikan, Utang, Asuransi, Kebutuhan Pribadi dan Rekreasi, Tabungan dan Dana Darurat)\n- date: selalu gunakan format ISO8601 lengkap dengan timezone {{ $('environment').item.json.TIMEZONE }}\n- hasil akhir harus berupa **JSON array minified valid**, tanpa teks atau format tambahan, **LANGSUNG JSON ARRAY**\n\nContoh:\nInput: \"Bayar listrik 200 ribu dan beli kopi 25 ribu dua kali, dan nabung juga 300000, bayar bpjs 100 ribu ambil tabungan\"\n\nOutput:\n[{\"type\":\"out\",\"name\":\"Pembayaran listrik\",\"date\":\"2025-11-07T10:18:48.265+07:00\",\"amount\":200000,\"qty\":1,\"total\":200000,\"labels\":[\"tagihan\"]},{\"type\":\"out\",\"name\":\"Beli kopi\",\"date\":\"2025-11-07T10:18:48.265+07:00\",\"amount\":25000,\"qty\":2,\"total\":50000,\"labels\":[\"makanan\"]},{\"type\":\"saving\",\"name\":\"Nabung pribadi\",\"date\":\"2025-11-07T10:18:48.265+07:00\",\"amount\":300000,\"qty\":1,\"total\":300000,\"labels\":[\"Tabungan dan Dana Darurat\"]},{\"type\":\"withdraw\",\"name\":\"Ambil tabungan\",\"date\":\"2025-11-07T10:18:48.265+07:00\",\"amount\":-100000,\"qty\":1,\"total\":-100000,\"labels\":[\"Tabungan dan Dana Darurat\"]},{\"type\":\"in\",\"name\":\"Dari tabungan\",\"date\":\"2025-11-07T10:18:48.265+07:00\",\"amount\":100000,\"qty\":1,\"total\":100000,\"labels\":[\"Tabungan dan Dana Darurat\"]},{\"type\":\"out\",\"name\":\"Bayar BPJS\",\"date\":\"2025-11-07T10:18:48.265+07:00\",\"amount\":100000,\"qty\":1,\"total\":100000,\"labels\":[\"Kesehatan\"]}]\n\n# DATA\nnow = {{ $now.toUTC().toISO() }}\n\n# INPUT USER\n{{ $('environment').item.json.data.text }}",
        "hasOutputParser": true,
        "options": {
          "systemMessage": "=Kamu adalah AI yang mengekstrak transaksi keuangan dari teks pengguna (keluarga muda Indonesia, usia 25\u201330 tahun)."
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3,
      "position": [
        1344,
        96
      ],
      "id": "cd99f028-9841-4000-9494-8e8e7a7806f5",
      "name": "Record Agent",
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=# DATA\nnow = {{ $now.toUTC().toISO() }}\nlink laporan = {{ $('environment').item.json.REPORT_URL }}\n\n# INPUT USER\n{{ $('environment').item.json.data.text }}",
        "hasOutputParser": true,
        "options": {
          "systemMessage": "Kamu adalah \"Yuk Lia\", AI untuk pencatatan keuangan keluarga di indonesia, Jawa khususnya\n\n**Balas menggunakan Bahasa Jawa Timuran**"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3,
      "position": [
        1344,
        -160
      ],
      "id": "ae003377-1e2c-401b-bc71-cdabfd3eb5fa",
      "name": "Talk Agent"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "75465abd-f36c-4846-b0d4-e57039d37337",
              "name": "action",
              "value": "={{ $json.items[$json.i].type }}",
              "type": "string"
            },
            {
              "id": "c2977517-eee7-4ffa-9248-b66d643dfaf4",
              "name": "name",
              "value": "={{ $json.items[$json.i].name }}",
              "type": "string"
            },
            {
              "id": "107e19cc-efad-429b-80ac-976a67f800ae",
              "name": "date",
              "value": "={{ $json.items[$json.i].date }}",
              "type": "string"
            },
            {
              "id": "2d006833-989d-48c4-826a-ce3fec8b593b",
              "name": "amount",
              "value": "={{ $json.items[$json.i].amount }}",
              "type": "number"
            },
            {
              "id": "45ec52fe-576f-4129-b753-0cd65bab2ee8",
              "name": "qty",
              "value": "={{ $json.items[$json.i].qty }}",
              "type": "number"
            },
            {
              "id": "fd17fa2e-f409-413a-a756-3ec5f0c5f885",
              "name": "total",
              "value": "={{ $json.items[$json.i].total }}",
              "type": "number"
            },
            {
              "id": "181a948c-912a-4053-af9a-48c9547f9591",
              "name": "labels",
              "value": "={{ $json.items[$json.i].labels }}",
              "type": "array"
            },
            {
              "id": "a48e80ee-0520-49f3-b887-24803420c439",
              "name": "created_at",
              "value": "={{ new Date() }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        2592,
        64
      ],
      "id": "8995ee1a-999a-4b04-b2e3-9a5b7d9674c8",
      "name": "map record"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "9f56e81c-f701-4375-9e5a-93304e1b0301",
              "leftValue": "={{ $json.i }}",
              "rightValue": "={{ $json.items.length }}",
              "operator": {
                "type": "number",
                "operation": "lt"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2176,
        80
      ],
      "id": "14a957f0-fcee-4f16-962e-1b539cd46077",
      "name": "loop check"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "fbad8433-e890-49db-ad79-33e03f25b8a6",
              "name": "date",
              "value": "={{ new DateTime($json.date).toUTC().toMillis() }}",
              "type": "number"
            },
            {
              "id": "103ca7d5-b181-494e-a6bf-98cdb74ff4cf",
              "name": "created_at",
              "value": "={{ new DateTime($json.created_at).toUTC().toMillis() }}",
              "type": "number"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        2816,
        64
      ],
      "id": "71c75c1b-dd82-400b-ac00-6abb523faf5b",
      "name": "map firebase payload"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "0fe46638-54fe-4fe8-92e8-367188b8e083",
              "name": "action",
              "value": "={{ $('loop check').item.json.action }}",
              "type": "string"
            },
            {
              "id": "f00eebdf-6a80-43e2-a40e-2f282754327f",
              "name": "items",
              "value": "={{ $('loop check').item.json.items }}",
              "type": "array"
            },
            {
              "id": "981cc997-3e9f-4959-b1d2-727446152ba8",
              "name": "i",
              "value": "={{ $('loop check').item.json.i + 1 }}",
              "type": "number"
            },
            {
              "id": "34428624-c5d4-44b1-92d6-54997552d254",
              "name": "results",
              "value": "={{ $json.results }}",
              "type": "object"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3488,
        64
      ],
      "id": "5cff0bc1-d29a-42fd-816e-10a98092c2ae",
      "name": "loop"
    },
    {
      "parameters": {
        "projectId": "fairuz-kingdom-default-rtdb",
        "operation": "get",
        "path": "/balance"
      },
      "type": "n8n-nodes-base.googleFirebaseRealtimeDatabase",
      "typeVersion": 1,
      "position": [
        2384,
        480
      ],
      "id": "af1b20dd-277a-48c0-a65b-9dc852bc1b14",
      "name": "get balance",
      "retryOnFail": true,
      "waitBetweenTries": 300,
      "credentials": {},
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "106905e4-b308-4993-a0fb-548852c96f39",
              "name": "balance",
              "value": "={{ ($json['/balance'] ?? 0) + $('loop check').item.json.results.total }}",
              "type": "number"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        2592,
        464
      ],
      "id": "c3f12e7b-83c9-445b-a0f0-01f0cc8af246",
      "name": "update balance"
    },
    {
      "parameters": {
        "projectId": "fairuz-kingdom-default-rtdb",
        "operation": "update",
        "path": "/",
        "attributes": "=balance"
      },
      "type": "n8n-nodes-base.googleFirebaseRealtimeDatabase",
      "typeVersion": 1,
      "position": [
        2816,
        464
      ],
      "id": "20de06b6-97e0-4be2-9945-e1d973afc08d",
      "name": "save balance",
      "retryOnFail": true,
      "waitBetweenTries": 500,
      "credentials": {},
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "projectId": "fairuz-kingdom-default-rtdb",
        "operation": "delete",
        "path": "={{ $json.datas[$json.remove_i].id }}"
      },
      "type": "n8n-nodes-base.googleFirebaseRealtimeDatabase",
      "typeVersion": 1,
      "position": [
        3024,
        912
      ],
      "id": "4989ad6a-2323-4cb7-a60b-6af691a68933",
      "name": "delete records",
      "retryOnFail": true,
      "credentials": {}
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "65ca1a34-80bd-4a9e-9eaf-a0fcc95a6f8d",
              "name": "remove_i",
              "value": 0,
              "type": "number"
            },
            {
              "id": "3af9db91-50d9-4b83-af4b-56e4116419eb",
              "name": "datas",
              "value": "={{ $('append response').item.json.results.data }}",
              "type": "array"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        2384,
        928
      ],
      "id": "3595a284-14b7-4351-930b-b3b6f95e8684",
      "name": "loop remove"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "e2caf674-d7e9-4045-a030-c48347b0e9a8",
              "leftValue": "={{ $json.remove_i }}",
              "rightValue": "={{ $json.datas.length }}",
              "operator": {
                "type": "number",
                "operation": "lt"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2592,
        928
      ],
      "id": "1655797e-ebbd-4081-9249-121ac374fce9",
      "name": "check loop remove"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "95c3b528-0398-44c0-af71-462c94d955d2",
              "name": "reply",
              "value": "=Firebase Error: {{ $('loop remove').item.json.error }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3472,
        944
      ],
      "id": "c00c8e89-62fd-40e9-954c-1b38f29c9377",
      "name": "error message"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "9acdfe1a-2387-4a77-a382-1e3405a452c5",
              "name": "i",
              "value": "={{ $('check loop remove').item.json.remove_i + 1 }}",
              "type": "number"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3248,
        912
      ],
      "id": "53f0c2b0-8be0-48b3-8ade-7447eb5a40e8",
      "name": "loop remove continue"
    },
    {
      "parameters": {
        "projectId": "fairuz-kingdom-default-rtdb",
        "operation": "push",
        "path": "={{ ((action) => {\n\n  return {\n    in: \"\\incomes\",\n    out: \"\\outcomes\",\n    saving: \"\\savings\",\n    withdraw: \"\\savings\",\n  }[action] ?? \"\";\n\n})($json.action) }}",
        "attributes": "name,date,amount,qty,labels,created_at"
      },
      "type": "n8n-nodes-base.googleFirebaseRealtimeDatabase",
      "typeVersion": 1,
      "position": [
        3040,
        64
      ],
      "id": "640ffac8-67e3-49dd-a529-8b79e6d7c4e2",
      "name": "append record",
      "alwaysOutputData": false,
      "credentials": {}
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "7afd9e7f-7d52-4f05-aefe-5ede8478cbbc",
              "name": "storage",
              "value": "firebase",
              "type": "string"
            },
            {
              "id": "31930359-2521-4d6a-a287-9f5772c5b677",
              "name": "results",
              "value": "={{ ((res) => {\n  const item = $('map record').item.json;\n  const data = {\n    ...item,\n    id: `/${item.action}/${$json.name}`\n  }\n\n  let total = res.total;\n  let saving = res.saving;\n  if (item.action == 'in') {\n    total += item.total;\n  } else if (item.action == 'out') {\n    total -= item.total;\n  } else if (item.action == 'saving') {\n    saving += item.total;\n  } else if (item.action == 'withdraw') {\n    saving += item.total;\n  }\n\n  return {\n    ...res,\n    data: [...res.data, data],\n    total,\n    saving,\n  };\n\n})($('loop check').item.json.results) }}",
              "type": "object"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3264,
        64
      ],
      "id": "321f4341-c452-40f7-a612-84136f6667c7",
      "name": "append response"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "2c0fd444-8951-4bd2-8ebd-8828f27283f9",
              "name": "reply",
              "value": "=AI Error: {{ $json.error }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1696,
        272
      ],
      "id": "ab1a2fd9-a29c-4eb6-93fe-beb5f73250ff",
      "name": "error ai"
    },
    {
      "parameters": {
        "projectId": "fairuz-kingdom-default-rtdb",
        "operation": "get",
        "path": "/saving"
      },
      "type": "n8n-nodes-base.googleFirebaseRealtimeDatabase",
      "typeVersion": 1,
      "position": [
        2384,
        704
      ],
      "id": "c4778254-192a-48fe-b986-1314cc636da3",
      "name": "get saving",
      "retryOnFail": true,
      "waitBetweenTries": 300,
      "credentials": {},
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "106905e4-b308-4993-a0fb-548852c96f39",
              "name": "saving",
              "value": "={{ ($json['/saving'] ?? 0) + $('loop check').item.json.results.saving }}",
              "type": "number"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        2592,
        688
      ],
      "id": "92e62127-9f91-4861-a52e-63fc99e74eab",
      "name": "update saving"
    },
    {
      "parameters": {
        "projectId": "fairuz-kingdom-default-rtdb",
        "operation": "update",
        "path": "/",
        "attributes": "=saving"
      },
      "type": "n8n-nodes-base.googleFirebaseRealtimeDatabase",
      "typeVersion": 1,
      "position": [
        2816,
        688
      ],
      "id": "b248494c-727d-4fef-9395-9351e9c31727",
      "name": "save saving",
      "retryOnFail": true,
      "waitBetweenTries": 500,
      "credentials": {},
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "6feba555-355d-462f-9ea8-ede8b5647d5f",
              "leftValue": "={{ $('loop check').item.json.results.total }}",
              "rightValue": 0,
              "operator": {
                "type": "number",
                "operation": "notEquals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2176,
        496
      ],
      "id": "fbe657ec-0e69-4efe-b694-c9ae698e6062",
      "name": "if balance update"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "6feba555-355d-462f-9ea8-ede8b5647d5f",
              "leftValue": "={{ $('loop check').item.json.results.saving }}",
              "rightValue": 0,
              "operator": {
                "type": "number",
                "operation": "notEquals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2176,
        720
      ],
      "id": "3221048b-bac2-490f-8263-2d5853670d18",
      "name": "if saving update"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "036edc51-c1fa-4b89-b892-0c5b07ab7aae",
              "name": "total",
              "value": "={{ $json.saving }}",
              "type": "number"
            },
            {
              "id": "a3300677-ce9a-4871-bf4e-d41a8728dea7",
              "name": "date",
              "value": "={{ $now.toUTC().toMillis() }}",
              "type": "number"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3024,
        624
      ],
      "id": "e8624d5c-cbe4-4c9c-9699-93dc67c65738",
      "name": "gen saving history"
    },
    {
      "parameters": {
        "projectId": "fairuz-kingdom-default-rtdb",
        "operation": "push",
        "path": "/saving_history",
        "attributes": "date, total"
      },
      "type": "n8n-nodes-base.googleFirebaseRealtimeDatabase",
      "typeVersion": 1,
      "position": [
        3232,
        624
      ],
      "id": "af5dae6d-2aed-4d52-9916-3166f8d0debb",
      "name": "add saving history",
      "retryOnFail": true,
      "waitBetweenTries": 1000,
      "credentials": {},
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "036edc51-c1fa-4b89-b892-0c5b07ab7aae",
              "name": "total",
              "value": "={{ $json.balance }}",
              "type": "number"
            },
            {
              "id": "a3300677-ce9a-4871-bf4e-d41a8728dea7",
              "name": "date",
              "value": "={{ $now.toUTC().toMillis() }}",
              "type": "number"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3024,
        400
      ],
      "id": "83a74a29-23df-4df1-9b6d-9a164108a09a",
      "name": "gen saving balance"
    },
    {
      "parameters": {
        "projectId": "fairuz-kingdom-default-rtdb",
        "operation": "push",
        "path": "/balance_history",
        "attributes": "date, total"
      },
      "type": "n8n-nodes-base.googleFirebaseRealtimeDatabase",
      "typeVersion": 1,
      "position": [
        3232,
        400
      ],
      "id": "ec1ae70e-dcc4-4a15-820c-055c58813a0b",
      "name": "add saving balance",
      "retryOnFail": true,
      "waitBetweenTries": 1000,
      "credentials": {},
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "content": "## Get Started\n1. Setup Firebase Realtime Database Integration see https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlecloudrealtimedatabase\n2. Setup Telegram Bot and integrate with n8n\n3. Set Telegram webhook to call workflow webhook link\n4. You can restricted which chat_id allowed to process on `telegram environment` node\n5. Setup AI Model integrate with this workflow on every agent\n\n",
        "height": 208,
        "width": 624
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        208,
        -832
      ],
      "typeVersion": 1,
      "id": "fe86619a-99b8-46de-a060-41131fd7d549",
      "name": "Sticky Note6"
    }
  ],
  "connections": {
    "telegram webhook": {
      "main": [
        [
          {
            "node": "response telegram webhook",
            "type": "main",
            "index": 0
          },
          {
            "node": "telegram environment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "telegram environment": {
      "main": [
        [
          {
            "node": "telegram middleware",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "environment": {
      "main": [
        [
          {
            "node": "middleware",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "telegram middleware": {
      "main": [
        [
          {
            "node": "telegram parser",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "telegram parser": {
      "main": [
        [
          {
            "node": "environment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "middleware": {
      "main": [
        [
          {
            "node": "Clasification Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "chat trigger": {
      "main": [
        [
          {
            "node": "chat parser",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "chat parser": {
      "main": [
        [
          {
            "node": "environment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clasification Agent": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Clasification Agent",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Record Agent",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Talk Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Parse Output": {
      "ai_outputParser": [
        [
          {
            "node": "Record Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "report generator",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Talk Agent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Record Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "record parser": {
      "main": [
        [
          {
            "node": "loop check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "custom parser": {
      "main": [
        [
          {
            "node": "reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "report generator": {
      "main": [
        [
          {
            "node": "reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "reply manager": {
      "main": [
        [
          {
            "node": "reply telegram",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "reply chat",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "generate reply": {
      "main": [
        [
          {
            "node": "reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "reply": {
      "main": [
        [
          {
            "node": "reply manager",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "Talk Agent",
            "type": "ai_memory",
            "index": 0
          },
          {
            "node": "Record Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "reply telegram": {
      "main": [
        []
      ]
    },
    "reply chat": {
      "main": [
        []
      ]
    },
    "Record Agent": {
      "main": [
        [
          {
            "node": "record parser",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error ai",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Talk Agent": {
      "main": [
        [
          {
            "node": "custom parser",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "map record": {
      "main": [
        [
          {
            "node": "map firebase payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "loop check": {
      "main": [
        [
          {
            "node": "map record",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "if balance update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "map firebase payload": {
      "main": [
        [
          {
            "node": "append record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "loop": {
      "main": [
        [
          {
            "node": "loop check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get balance": {
      "main": [
        [
          {
            "node": "update balance",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "loop remove",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "update balance": {
      "main": [
        [
          {
            "node": "save balance",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "save balance": {
      "main": [
        [
          {
            "node": "gen saving balance",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "loop remove",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "loop remove": {
      "main": [
        [
          {
            "node": "check loop remove",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "check loop remove": {
      "main": [
        [
          {
            "node": "delete records",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "error message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "error message": {
      "main": [
        [
          {
            "node": "reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "delete records": {
      "main": [
        [
          {
            "node": "loop remove continue",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "loop remove continue": {
      "main": [
        [
          {
            "node": "check loop remove",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "append record": {
      "main": [
        [
          {
            "node": "append response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "append response": {
      "main": [
        [
          {
            "node": "loop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "error ai": {
      "main": [
        [
          {
            "node": "reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get saving": {
      "main": [
        [
          {
            "node": "update saving",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "loop remove",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "update saving": {
      "main": [
        [
          {
            "node": "save saving",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "save saving": {
      "main": [
        [
          {
            "node": "gen saving history",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "loop remove",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "if balance update": {
      "main": [
        [
          {
            "node": "get balance",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "if saving update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "if saving update": {
      "main": [
        [
          {
            "node": "get saving",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "generate reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "gen saving history": {
      "main": [
        [
          {
            "node": "add saving history",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "add saving history": {
      "main": [
        [
          {
            "node": "generate reply",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "gen saving balance": {
      "main": [
        [
          {
            "node": "add saving balance",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "add saving balance": {
      "main": [
        [
          {
            "node": "if saving update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "timezone": "Asia/Jakarta",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false,
    "errorWorkflow": "nbXLSiLZH4QozW6V",
    "saveManualExecutions": false,
    "timeSavedPerExecution": 1
  },
  "versionId": "ede39e32-3c40-4885-aa06-f6cf576248b4",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "HIEmdTflyDS8KQhN",
  "tags": []
}