{
  "name": "optimize-added-expenses",
  "nodes": [
    {
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1.1,
      "position": [
        -4592,
        112
      ],
      "id": "bcb6389d-2f59-4aaa-9483-c09705224700",
      "name": "Telegram Trigger",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "Zarejestrowany wydatek: \"{{ $json.text }}\" lub \"{{ $json.content }}\" lub {{ $binary }}",
        "options": {
          "systemMessage": "=Instrukcje Systemowe dla Agenta\n\nJeste\u015b asystentem do zarz\u0105dzania wydatkami. Twoim zadaniem jest przeanalizowanie wiadomo\u015bci i ewentualnych za\u0142\u0105cznik\u00f3w (paragon\u00f3w, faktur) oraz dodanie wydatku do arkusza Google Sheets. Je\u015bli to mo\u017cliwe, prze\u015blij te\u017c za\u0142\u0105cznik do Google Drive. Dzia\u0142asz w jednej iteracji.\n\n\u2e3b\n\nWyodr\u0119bnij nast\u0119puj\u0105ce dane:\n\t1.\tData \u2013 w formacie RRRR-MM-DD, strefa Europe/Warsaw.\n\t\u2022\tWzgl\u0119dne daty (np. \u201cwczoraj\u201d) przelicz wzgl\u0119dem {{ $now.setZone('Europe/Warsaw') }}.\n\t\u2022\tJe\u015bli brak \u2192 null.\n\t2.\tMiejsce/Przedmiot \u2013 gdzie/na co wydano.\n\t\u2022\tJe\u015bli brak \u2192 null.\n\t3.\tKwota \u2013 liczba dziesi\u0119tna z kropk\u0105 jako separatorem, bez symbolu waluty.\n\t\u2022\tPrzyk\u0142ad: \u201c49,99 z\u0142\u201d \u2192 49.99.\n\t\u2022\tJe\u015bli brak \u2192 null.\n\t4.\tKategoria \u2013 Prywatne, MT HUB, FHU Gabriela.\nZasady klasyfikacji:\n\t\u2022\tJe\u015bli dokument zawiera NIP 8393229228 \u2192 MT HUB\n\t\u2022\tJe\u015bli dokument zawiera NIP 8393251475 \u2192 FHU\n\t\u2022\tW pozosta\u0142ych przypadkach, je\u015bli nie ma pewno\u015bci lub brak danych \u2192 prywatny\n\t\t5.\tSubKategoria:\n\u2022 Je\u015bli kategoria to Prywatne, przypisz szczeg\u00f3\u0142ow\u0105 subkategori\u0119 wydatku, np. \u017bywno\u015b\u0107, Odzie\u017c, Transport, Rozrywka, Zdrowie, Hobby, RTV/AGD, inne.\n\u2022 Je\u015bli kategoria to MT HUB \u2192 subkategoria: MT_HUB\n\u2022 Je\u015bli kategoria to FHU Gabriela \u2192 subkategoria: FHU\n\u2e3b\n\ud83d\udd20 UWAGA: Zwracaj szczeg\u00f3ln\u0105 uwag\u0119 na wielko\u015b\u0107 liter. Kategoria i subkategoria musz\u0105 dok\u0142adnie odpowiada\u0107 wzorcowi (case-sensitive). Nie przekszta\u0142caj ani nie normalizuj wielko\u015bci liter.\nPrzyk\u0142adowo:\n\t\u2022\tPrywatne, Firmowe - prawid\u0142owe\n    \u2022\tMT_HUB, FHU \u2013 prawid\u0142owe\n\t\u2022\tMt Hub, mt hub, MTHub, prywatne, firmowe \u2013 nieprawid\u0142owe\n\nTo samo dotyczy kategorii Prywatne i FHU.\n\nNarz\u0119dzia dodaj_wydatek_do_bazy (u\u017cyj tylko, je\u015bli wszystkie dane s\u0105 dost\u0119pne)\nwydatek_folder_id:\n\t\u2022\tJe\u015bli Prywatne \u2192 {{ $('Get a row').item.json.prywatne_id }}\n\t\u2022\tJe\u015bli MT HUB \u2192 {{ $('Get a row').item.json.mt_hub_id }}\n\t\u2022\tJe\u015bli FHU \u2192 {{ $('Get a row').item.json.fhu_id }}\n\u2e3b\n\nFormat odpowiedzi\n\nSukces\n\n\u2705 Wydatek dodany:\n\u2022 \ud83d\udcc5 Data:\n\u2022 \ud83c\udff7\ufe0f Miejsce/Przedmiot:\n\u2022 \ud83d\udcb8 Kwota: (z\u0142, przecinek jako separator)\n\u2022 \ud83d\udd16 Kategoria:\n\n\nTylko za\u0142\u0105cznik\n\n\ud83d\udcf8 Za\u0142\u0105cznik przes\u0142any do Google Drive. Brak danych do dodania wydatku.\n\nProblem\n\n\ud83d\udd34 Problem z dodaniem wydatku. Brakuje danych o:",
          "passthroughBinaryImages": true
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.7,
      "position": [
        -1088,
        80
      ],
      "id": "7a0a7ad8-ccdb-4ef9-9e70-32fe18db4ea6",
      "name": "AI Agent",
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.message.text }}",
                    "rightValue": "",
                    "operator": {
                      "type": "string",
                      "operation": "exists",
                      "singleValue": true
                    },
                    "id": "7c91a664-3634-41e0-a1c8-2e195b9b509e"
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Text"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "b6f5f508-c214-4f1a-925b-16dca2a94a74",
                    "leftValue": "={{ $('Telegram Trigger').item.json.message.voice.file_id }}",
                    "rightValue": "",
                    "operator": {
                      "type": "string",
                      "operation": "exists",
                      "singleValue": true
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "=Voice"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "22c624df-56e4-4bc2-bf8a-6d41614556d9",
                    "leftValue": "={{ $('Telegram Trigger').item.json.message.photo.last().file_id }}",
                    "rightValue": "",
                    "operator": {
                      "type": "string",
                      "operation": "exists",
                      "singleValue": true
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Image"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        -2320,
        112
      ],
      "id": "de35a0f4-fe98-40b3-bb42-661c114a61cd",
      "name": "Switch"
    },
    {
      "parameters": {
        "resource": "file",
        "fileId": "={{ $('Telegram Trigger').item.json.message.photo.last().file_id }}",
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        -2112,
        272
      ],
      "id": "4bb7bb22-5a7b-4408-8b5b-71d036627642",
      "name": "Get a file",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.2,
      "position": [
        -1104,
        304
      ],
      "id": "9292110e-1a01-4f15-b32b-508c242450c5",
      "name": "OpenAI Chat Model",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const inputItems = $input.all(); // Pobierz wszystkie elementy z poprzedniego w\u0119z\u0142a\n\nconst monthTranslations = {\n  \"January\": \"Stycze\u0144\",\n  \"February\": \"Luty\",\n  \"March\": \"Marzec\",\n  \"April\": \"Kwiecie\u0144\",\n  \"May\": \"Maj\",\n  \"June\": \"Czerwiec\",\n  \"July\": \"Lipiec\",\n  \"August\": \"Sierpie\u0144\",\n  \"September\": \"Wrzesie\u0144\",\n  \"October\": \"Pa\u017adziernik\",\n  \"November\": \"Listopad\",\n  \"December\": \"Grudzie\u0144\"\n};\n\nconst monthNumbers = {\n    \"January\": \"01\",\n    \"February\": \"02\",\n    \"March\": \"03\",\n    \"April\": \"04\",\n    \"May\": \"05\",\n    \"June\": \"06\",\n    \"July\": \"07\",\n    \"August\": \"08\",\n    \"September\": \"09\",\n    \"October\": \"10\",\n    \"November\": \"11\",\n    \"December\": \"12\"\n};\n\nconst WARSAW_TIMEZONE = 'Europe/Warsaw';\n\nconst outputData = inputItems.map(item => {\n    // Odczytaj znacznik czasu z pola 'currentTimestamp' z poprzedniego w\u0119z\u0142a\n    // Je\u015bli z jakiego\u015b powodu go nie ma, u\u017cyj aktualnej daty\n    const currentMoment = item.json.currentTimestamp ? new Date(item.json.currentTimestamp) : new Date();\n\n    // Utw\u00f3rz obiekt Intl.DateTimeFormat dla strefy czasowej Warszawy\n    const formatter = new Intl.DateTimeFormat('en-US', {\n        year: 'numeric',\n        month: 'long',\n        day: '2-digit',\n        hour: '2-digit',\n        minute: '2-digit',\n        second: '2-digit',\n        hour12: false, // U\u017cyj formatu 24-godzinnego dla \u0142atwiejszej ekstrakcji\n        timeZone: WARSAW_TIMEZONE\n    });\n\n    // Sformatuj dat\u0119 i czas w strefie czasowej Warszawy\n    const parts = formatter.formatToParts(currentMoment);\n    const getPart = (type) => parts.find(part => part.type === type)?.value;\n\n    const year = getPart('year');\n    const englishMonth = getPart('month'); // Nazwa miesi\u0105ca w j\u0119zyku angielskim\n    const dayOfMonth = getPart('day');\n    const hour = getPart('hour');\n    const minute = getPart('minute');\n    const second = getPart('second');\n\n    // T\u0142umaczenie miesi\u0105ca na polski\n    const polishMonth = monthTranslations[englishMonth] || englishMonth;\n    const monthNumber = monthNumbers[englishMonth] || \"\";\n\n    // Aby uzyska\u0107 \"Day of week\" w strefie czasowej Warszawy:\n    const dayOfWeekFormatter = new Intl.DateTimeFormat('en-US', { weekday: 'long', timeZone: WARSAW_TIMEZONE });\n    const dayOfWeek = dayOfWeekFormatter.format(currentMoment);\n\n    // Aby uzyska\u0107 \"Readable date\" i \"Readable time\" z uwzgl\u0119dnieniem AM/PM (je\u015bli chcesz)\n    // w strefie czasowej Warszawy:\n    const readableDateFormatter = new Intl.DateTimeFormat('en-US', {\n        month: 'long', day: 'numeric', year: 'numeric',\n        hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: true,\n        timeZone: WARSAW_TIMEZONE\n    });\n    const readableTimeFormatter = new Intl.DateTimeFormat('en-US', {\n        hour: 'numeric', minute: 'numeric', second: 'numeric', hour12: true,\n        timeZone: WARSAW_TIMEZONE\n    });\n\n    // NOWA FUNKCJONALNO\u015a\u0106: Formatowanie daty w formacie 2025-07-23 10:43:00+00\n    // Uwzgl\u0119dniaj\u0105c stref\u0119 czasow\u0105 Polski (CEST/CET)\n    const formatPolishDateTime = () => {\n        const date = new Date(currentMoment);\n        \n        // Formatowanie w strefie czasowej Polski\n        const polishFormatter = new Intl.DateTimeFormat('en-CA', {\n            year: 'numeric',\n            month: '2-digit',\n            day: '2-digit',\n            hour: '2-digit',\n            minute: '2-digit',\n            second: '2-digit',\n            hour12: false,\n            timeZone: WARSAW_TIMEZONE\n        });\n        \n        const polishParts = polishFormatter.formatToParts(date);\n        const getPolishPart = (type) => polishParts.find(part => part.type === type)?.value;\n        \n        const polishYear = getPolishPart('year');\n        const polishMonth = getPolishPart('month');\n        const polishDay = getPolishPart('day');\n        const polishHour = getPolishPart('hour');\n        const polishMinute = getPolishPart('minute');\n        const polishSecond = getPolishPart('second');\n        \n        // Okre\u015bl offset dla Polski (CEST +02:00 latem, CET +01:00 zim\u0105)\n        const isDST = (date) => {\n            const jan = new Date(date.getFullYear(), 0, 1);\n            const jul = new Date(date.getFullYear(), 6, 1);\n            return date.getTimezoneOffset() < Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());\n        };\n        \n        // Sprawd\u017a czy to czas letni czy zimowy w Polsce\n        const tempDate = new Date();\n        tempDate.setFullYear(parseInt(polishYear), parseInt(polishMonth) - 1, parseInt(polishDay));\n        tempDate.setHours(parseInt(polishHour), parseInt(polishMinute), parseInt(polishSecond));\n        \n        // Polska u\u017cywa CEST (+02) latem i CET (+01) zim\u0105\n        const offset = isDST(tempDate) ? '+02' : '+01';\n        \n        return `${polishYear}-${polishMonth}-${polishDay} ${polishHour}:${polishMinute}:${polishSecond}${offset}`;\n    };\n\n    return {\n        json: {\n            // timestamp w ISO zawsze b\u0119dzie w UTC, ale reprezentuje czas w Warszawie\n            \"timestamp\": currentMoment.toISOString(),\n            \"Readable date\": readableDateFormatter.format(currentMoment),\n            \"Readable time\": readableTimeFormatter.format(currentMoment),\n            \"Day of week\": dayOfWeek,\n            \"Year\": year,\n            \"Month\": polishMonth,\n            \"Day of month\": dayOfMonth,\n            \"Hour\": hour,\n            \"Minute\": minute,\n            \"Second\": second,\n            \"Timezone\": WARSAW_TIMEZONE + \" (UTC+02:00)\", // Jawnie ustawiamy stref\u0119 czasow\u0105\n            \"Month Number\": monthNumber,\n            \"aktualna data i godzina\": formatPolishDateTime() // NOWE POLE\n        }\n    };\n});\n\nreturn outputData;\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -4128,
        128
      ],
      "id": "047a41aa-2012-4901-8d4c-cf53e70fc6da",
      "name": "Ekstrakcja aktualnej daty"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.categoryType }}",
                    "rightValue": "prywatny",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "155c39c2-bd94-4403-987b-16d9c8f02682"
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "prywatny"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "836da5c1-7eb3-4d6e-bf49-61255c642190",
                    "leftValue": "={{ $json.categoryType }}",
                    "rightValue": "MT HUB",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "MT HUB"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "a1920598-dd5b-435f-9472-7af7ec89fbb3",
                    "leftValue": "={{ $json.categoryType }}",
                    "rightValue": "FHU",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "FHU"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        -512,
        80
      ],
      "id": "3cc217eb-8f93-4a33-8fbc-2e6816a9eaaf",
      "name": "Switch1"
    },
    {
      "parameters": {
        "jsCode": "const inputText = $input.item.json.output; // TYLKO JEDNA DEKLARACJA\n\nlet category = 'nieznana';\n\n// Szukamy konkretnie: MT HUB, FHU lub prywatny\nconst regex = /Kategoria: (MT HUB|FHU|prywatn(?:y|e)?)/i;\nconst match = inputText.match(regex);\n\nif (match && match[1]) {\n    const kat = match[1].toLowerCase();\n    if (kat.includes('mt hub')) {\n        category = 'MT HUB';\n    } else if (kat.includes('fhu')) {\n        category = 'FHU';\n    } else if (kat.startsWith('prywatn')) {\n        category = 'prywatny';\n    }\n}\n\n$input.item.json.categoryType = category;\n\nreturn $input.item;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -704,
        80
      ],
      "id": "04fba468-f46f-48ea-8cd7-8d5006a1a8c8",
      "name": "Code1"
    },
    {
      "parameters": {
        "name": "={{ $('Get a file').item.json.result.file_path }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "folderId": {
          "__rl": true,
          "value": "={{ $('Get a row').item.json.month_id }}",
          "mode": "id"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        -1648,
        272
      ],
      "id": "ada3c670-cb3a-47f1-af73-db02b6056a5e",
      "name": "Upload file",
      "alwaysOutputData": true,
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "operation": "download",
        "fileId": {
          "__rl": true,
          "value": "={{ $json.id }}",
          "mode": "id"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        -1376,
        272
      ],
      "id": "4f302a50-b7d4-4cc0-ab3d-160aae8937c8",
      "name": "Download file",
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "operation": "move",
        "fileId": {
          "__rl": true,
          "value": "={{ $('Upload file').item.json.id }}",
          "mode": "id"
        },
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "folderId": {
          "__rl": true,
          "value": "={{ $('Get a row').item.json.prywatne_id }}",
          "mode": "id"
        }
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        -192,
        -112
      ],
      "id": "326e2032-6246-445e-aedf-2630a7746f1e",
      "name": "Move prywatny",
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "text": "={{ $('AI Agent').item.json.output }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        144,
        48
      ],
      "id": "b5f13e79-e3a2-4c57-ad7b-854d10dfa39a",
      "name": "Send a text message1",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "text": "Zdj\u0119cie zosta\u0142o przes\u0142ane. Trwa analiza. ",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        -4400,
        112
      ],
      "id": "a2b3edd1-23be-4da8-81c1-c6f77f97897b",
      "name": "Send a text message",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "text": "\u274c Wyst\u0105pi\u0142 b\u0142\u0105d autoryzacji Agent AI. Wykonaj autoryzacj\u0119 w n8n. \u274c ",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        -624,
        464
      ],
      "id": "ba8fc34f-c302-4143-8fde-36bb480d8318",
      "name": "Error autoryzacja agenta Ai",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "text": "\u274c Wyst\u0105pi\u0142 problem z przes\u0142aniem pliku na google drive. Sprawd\u017a automatyzacj\u0119 w n8n. \u274c ",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        -1552,
        512
      ],
      "id": "d30431f4-a8ea-4937-836f-9981eacbdf4f",
      "name": "Error upload file",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "move",
        "fileId": {
          "__rl": true,
          "value": "={{ $('Download file').item.json.id }}",
          "mode": "id"
        },
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "folderId": {
          "__rl": true,
          "value": "={{ $('Get a row').item.json.mt_hub_id }}",
          "mode": "id"
        }
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        -192,
        80
      ],
      "id": "ad682668-a9ce-48f8-8fa9-fe8c7376aee6",
      "name": "Move MTHUB",
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "operation": "move",
        "fileId": {
          "__rl": true,
          "value": "={{ $('Download file').item.json.id }}",
          "mode": "id"
        },
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "folderId": {
          "__rl": true,
          "value": "={{ $('Get a row').item.json.fhu_id}}",
          "mode": "id"
        }
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        -192,
        288
      ],
      "id": "b705bc4d-0395-4989-a510-f9a572994464",
      "name": "Move FHU",
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "operation": "get",
        "tableId": "folder_registry",
        "filters": {
          "conditions": [
            {
              "keyName": "month",
              "keyValue": "={{ $json.invoiceMonth}}"
            },
            {
              "keyName": "year",
              "keyValue": "={{ $json.invoiceYear }}"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -2560,
        128
      ],
      "id": "2d055399-558c-46a3-bb91-86d7d1281e35",
      "name": "Get a row",
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "text": "Wykryto tekst. Wrzu\u0107 zdj\u0119cie.",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        -2016,
        -64
      ],
      "id": "0a2de4e0-58dc-4a78-8e9e-358520393305",
      "name": "Send a text message2",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "text": "Wykryto d\u017awi\u0119k. Wrzu\u0107 zdj\u0119cie.",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        -2016,
        112
      ],
      "id": "58021996-04b5-4dc3-90b0-a622ff993ab1",
      "name": "Send a text message3",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "tableId": "detailed_expenses",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "description",
              "fieldValue": "={{ $fromAI('Miejsce-Przedmiot', ``, 'string') }}"
            },
            {
              "fieldId": "expense_date",
              "fieldValue": "={{ $fromAI('Data', ``, 'string') }}"
            },
            {
              "fieldId": "amount",
              "fieldValue": "={{ $fromAI('Kwota', ``, 'string') }}"
            },
            {
              "fieldId": "category",
              "fieldValue": "={{ $fromAI('Kategoria', ``, 'string') }}"
            },
            {
              "fieldId": "folder_id",
              "fieldValue": "={{ $fromAI('wydatek_folder_id', ``, 'string') }}"
            },
            {
              "fieldId": "subcategory",
              "fieldValue": "={{ $fromAI('SubKategoria', ``, 'string') }}"
            },
            {
              "fieldId": "created_at",
              "fieldValue": "={{ $('Ekstrakcja aktualnej daty').item.json['aktualna data i godzina'] }}"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.supabaseTool",
      "typeVersion": 1,
      "position": [
        -928,
        512
      ],
      "id": "70920b94-8ba7-4eea-83b5-06ea5ad0040e",
      "name": "Dodaj wydatek do bazy",
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "file",
        "fileId": "={{ $('Telegram Trigger').item.json.message.photo.last().file_id }}",
        "additionalFields": {}
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        -3872,
        128
      ],
      "id": "48d4d2cd-c2db-43d7-b324-fb0bc043612f",
      "name": "Get a file1",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "image",
        "operation": "analyze",
        "modelId": {
          "__rl": true,
          "value": "gpt-4o",
          "mode": "list",
          "cachedResultName": "GPT-4O"
        },
        "text": "=Twoje zadanie:\n\n1. Przeanalizuj za\u0142\u0105czone zdj\u0119cie lub skan faktury, rachunku lub paragonu.\n2. Znajd\u017a **rzeczywist\u0105 dat\u0119 wystawienia dokumentu** \u2013 tylko t\u0119, kt\u00f3ra jest widoczna w tre\u015bci dokumentu.\n3. Nie zgaduj \u2013 nie u\u017cywaj dzisiejszej daty ani roku domy\u015blnego. Je\u015bli nie masz pewno\u015bci, zwr\u00f3\u0107 `null`.\n\n\ud83d\udd01 Zwr\u00f3\u0107 wynik jako **czysta tablica JSON**, dok\u0142adnie w tym formacie:\n[\n  {\n    \"invoiceDay\": \"DD\",\n    \"invoiceMonth\": \"MM\",\n    \"invoiceYear\": \"YYYY\"\n  }\n]\n\n\ud83d\udccc Je\u015bli dokument nie zawiera jednoznacznej daty, zwr\u00f3\u0107:\n[\n  {\n    \"invoiceDay\": null,\n    \"invoiceMonth\": null,\n    \"invoiceYear\": null\n  }\n]\n\n\ud83e\udde0 Aktualny data i godzina to {{ $('Ekstrakcja aktualnej daty').item.json['aktualna data i godzina'] }} \u2013 nie zak\u0142adaj automatycznie 2023 ani 2024. Upewnij si\u0119, \u017ce data pochodzi z dokumentu, a nie z domys\u0142u.\n\n\u2757Odpowied\u017a ma zawiera\u0107 **tylko czysty JSON**, bez znacznik\u00f3w kodu (np. ```json), komentarzy ani dodatkowego opisu.",
        "inputType": "base64",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.8,
      "position": [
        -3456,
        128
      ],
      "id": "ea86b0c9-a298-4b29-9f8c-427ce5e047a4",
      "name": "Analyze image",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "for (const item of items) {\n  // Sprawdzamy, czy element ma dane binarne i czy te dane istniej\u0105\n  if (item.binary && item.binary.data) {\n    const binaryData = item.binary.data; // Odwo\u0142anie do obiektu z danymi binarnymi\n\n    const ext = binaryData.fileExtension?.toLowerCase(); // Pobieramy rozszerzenie pliku\n    let newMimeType = binaryData.mimeType; // Domy\u015blnie zachowujemy istniej\u0105cy mimeType\n\n    // Logika zmiany mimeType na podstawie rozszerzenia\n    if (ext === 'jpg' || ext === 'jpeg') {\n      newMimeType = 'image/jpeg';\n    } else if (ext === 'png') {\n      newMimeType = 'image/png';\n    } else if (ext === 'webp') {\n      newMimeType = 'image/webp';\n    }\n\n    // WA\u017bNA ZMIANA: Zapisujemy now\u0105 warto\u015b\u0107 z powrotem do obiektu\n    binaryData.mimeType = newMimeType;\n  }\n}\nreturn items;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -3648,
        128
      ],
      "id": "57428f89-fbb5-4423-9c41-faa7c0858de1",
      "name": "change mimetype",
      "alwaysOutputData": true,
      "retryOnFail": true
    },
    {
      "parameters": {
        "jsCode": "for (const item of items) {\n  // Sprawdzamy, czy element ma dane binarne i czy te dane istniej\u0105\n  if (item.binary && item.binary.data) {\n    const binaryData = item.binary.data; // Odwo\u0142anie do obiektu z danymi binarnymi\n\n    const ext = binaryData.fileExtension?.toLowerCase(); // Pobieramy rozszerzenie pliku\n    let newMimeType = binaryData.mimeType; // Domy\u015blnie zachowujemy istniej\u0105cy mimeType\n\n    // Logika zmiany mimeType na podstawie rozszerzenia\n    if (ext === 'jpg' || ext === 'jpeg') {\n      newMimeType = 'image/jpeg';\n    } else if (ext === 'png') {\n      newMimeType = 'image/png';\n    } else if (ext === 'webp') {\n      newMimeType = 'image/webp';\n    }\n\n    // WA\u017bNA ZMIANA: Zapisujemy now\u0105 warto\u015b\u0107 z powrotem do obiektu\n    binaryData.mimeType = newMimeType;\n  }\n}\nreturn items;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1872,
        272
      ],
      "id": "4597f2cb-005a-4a77-9161-d31fc51f61e1",
      "name": "change mimetype1",
      "alwaysOutputData": true,
      "retryOnFail": true
    },
    {
      "parameters": {
        "jsCode": "const raw = $json[\"content\"];\n\ntry {\n  // Parsujemy string JSON do tablicy obiekt\u00f3w\n  const parsedArray = JSON.parse(raw);\n\n  const data = parsedArray[0];\n\n  return [\n    {\n      json: {\n        invoiceDay: parseInt(data.invoiceDay, 10),\n        invoiceMonth: parseInt(data.invoiceMonth, 10),\n        invoiceYear: parseInt(data.invoiceYear, 10)\n      }\n    }\n  ];\n} catch (error) {\n  return [\n    {\n      json: {\n        invoiceDay: null,\n        invoiceMonth: null,\n        invoiceYear: null,\n        error: \"Nieprawid\u0142owy format JSON w polu content\"\n      }\n    }\n  ];\n}"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -3248,
        128
      ],
      "id": "00dac3f1-bd4a-4aa4-8cd4-441f1b88f06d",
      "name": "Code"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "cebfda1b-23fc-4d9d-96ca-64fe9b992e3d",
              "leftValue": "={{ $json.invoiceDay }}",
              "rightValue": "null",
              "operator": {
                "type": "string",
                "operation": "contains"
              }
            },
            {
              "id": "eb260322-ccc3-4bab-a8c6-821273468bae",
              "leftValue": "={{ $json.invoiceMonth }}",
              "rightValue": "null",
              "operator": {
                "type": "string",
                "operation": "contains"
              }
            },
            {
              "id": "3f8e72be-95cb-4cc8-b0e0-37ad266ea19e",
              "leftValue": "={{ $json.invoiceYear }}",
              "rightValue": "null",
              "operator": {
                "type": "string",
                "operation": "contains"
              }
            }
          ],
          "combinator": "or"
        },
        "looseTypeValidation": true,
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -3040,
        128
      ],
      "id": "b93fff91-65f0-401b-a269-de1e67456659",
      "name": "If"
    },
    {
      "parameters": {
        "chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
        "text": "\u274c Wyst\u0105pi\u0142 problem z odczytaniem daty rachunku. \u274c",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        -2784,
        48
      ],
      "id": "97f2a155-6e5a-4149-b24b-a3a0a7f3fd77",
      "name": "error date",
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "Send a text message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Code1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Error autoryzacja agenta Ai",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Send a text message2",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send a text message3",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get a file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get a file": {
      "main": [
        [
          {
            "node": "change mimetype1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Ekstrakcja aktualnej daty": {
      "main": [
        [
          {
            "node": "Get a file1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch1": {
      "main": [
        [
          {
            "node": "Move prywatny",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Move MTHUB",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Move FHU",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code1": {
      "main": [
        [
          {
            "node": "Switch1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload file": {
      "main": [
        [
          {
            "node": "Download file",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Error upload file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download file": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Move prywatny": {
      "main": [
        [
          {
            "node": "Send a text message1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send a text message": {
      "main": [
        [
          {
            "node": "Ekstrakcja aktualnej daty",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Move MTHUB": {
      "main": [
        [
          {
            "node": "Send a text message1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Move FHU": {
      "main": [
        [
          {
            "node": "Send a text message1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get a row": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Dodaj wydatek do bazy": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get a file1": {
      "main": [
        [
          {
            "node": "change mimetype",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "change mimetype": {
      "main": [
        [
          {
            "node": "Analyze image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "change mimetype1": {
      "main": [
        [
          {
            "node": "Upload file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze image": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If": {
      "main": [
        [
          {
            "node": "error date",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get a row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "cd854273-c672-48a9-a987-0f1e39e470fe",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "W0tNDxvVikyoDVxM",
  "tags": []
}