This workflow follows the Agent → Gmail recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Arvifund - Supabase (Fixed v6)",
"nodes": [
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "ad99e257-bcaf-42a2-b068-53e0c96729db",
"leftValue": "={{ $json.message.photo[2] }}",
"rightValue": "",
"operator": {
"type": "object",
"operation": "exists",
"singleValue": true
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "69cae014-32a5-44e4-abb1-bd8324df9b65",
"leftValue": "={{ $json.message.text }}",
"rightValue": "=/report",
"operator": {
"type": "string",
"operation": "startsWith"
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "dc0ba5e6-f00f-40d7-acd8-e639d4fd38da",
"leftValue": "={{ $json.message.text }}",
"rightValue": "/start",
"operator": {
"type": "string",
"operation": "startsWith"
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "4f8d9425-641e-4044-a54a-d73444ea28e0",
"leftValue": "={{ $json.message.text }}",
"rightValue": "/help",
"operator": {
"type": "string",
"operation": "startsWith"
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "report-hari-001",
"leftValue": "={{ $json.message.text }}",
"rightValue": "/hariini",
"operator": {
"type": "string",
"operation": "startsWith"
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "f0be09d4-a09a-45be-ae7a-9becc676ed4c",
"leftValue": "={{ $json.message.text }}",
"rightValue": "/laporanbulanan",
"operator": {
"type": "string",
"operation": "startsWith"
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "41e89fcf-d3a4-4a71-9a0b-5b0d7ea841fc",
"leftValue": "={{ $json.message.text }}",
"rightValue": "/",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "faff551c-7e32-447f-83a9-f126bc57664f",
"leftValue": "={{ $json.message.voice }}",
"rightValue": "",
"operator": {
"type": "object",
"operation": "exists",
"singleValue": true
}
}
],
"combinator": "and"
}
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
976,
3152
],
"id": "92dbc971-7293-4ba8-89ee-adc95b69633d",
"name": "Switch"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": false,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "23f4316d-5a77-45ae-81e7-18ee4cacb995",
"leftValue": "={{ $json.candidates[0].content.parts[0].text }}",
"rightValue": "ERROR:",
"operator": {
"type": "string",
"operation": "contains"
}
}
],
"combinator": "and"
},
"options": {
"ignoreCase": true
}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
2016,
2464
],
"id": "5b46ee85-d44f-47ec-bf55-c521444874c8",
"name": "If"
},
{
"parameters": {
"method": "POST",
"url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=<redacted-credential>",
"sendBody": true,
"specifyBody": "=json",
"bodyParameters": {
"parameters": [
{}
]
},
"jsonBody": "={{ JSON.stringify({ contents: [{ parts: [{ inline_data: { mime_type: \"image/jpeg\", data: $json.base64Image } }, { text: \"Analisa struk belanja dalam foto ini dan kembalikan HANYA dalam format berikut tanpa teks lain:\\n\\nTOKO: [nama toko]\\nTOTAL: [total dalam angka saja tanpa Rp]\\nITEMS: [daftar barang]\\nKATEGORI: [Makanan & Minuman/Tagihan/Kosmetik & Perawatan/Transportasi/Kesehatan/Pakaian/Elektronik/Rumah Tangga/Pendidikan/Hiburan/Cicilan/Investasi/Lainnya]\\nJENIS: Pengeluaran\\nMETODE: [Cash/QRIS/Transfer/Card/Cardless]\\nBANK: [nama bank, jika tidak ada tulis BRI]\\nTANGGAL: [tanggal hari ini format YYYY-MM-DD]\\nTANGGAL_STRUK: [tanggal di struk format YYYY-MM-DD]\" }] }] }) }}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1776,
2480
],
"id": "d1e3a8c2-a6fe-44a8-b536-d69bc663f397",
"name": "Analisa gambar",
"retryOnFail": true,
"waitBetweenTries": 5000
},
{
"parameters": {
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"text": "Struk tidak dapat dibaca dengan jelas.\n\nPastikan:\n- Foto struk jelas dan tidak blur\n- Pencahayaan cukup\n- Semua text terlihat\n\nSilakan coba foto ulang! \ud83d\udcf7",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2240,
2368
],
"id": "0790a0ca-b72f-4b68-be59-2d193e99d69f",
"name": "Respon error",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "create",
"tableId": "expenses",
"dataToSend": "defineBelow",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "toko",
"fieldValue": "={{ $json.candidates[0].content.parts[0].text.match(/TOKO: (.+)/)[1].trim() }}"
},
{
"fieldId": "tanggal",
"fieldValue": "={{ $json.candidates[0].content.parts[0].text.match(/TANGGAL_STRUK: (.+)/)?.[1]?.trim() }}"
},
{
"fieldId": "bulan",
"fieldValue": "={{ (() => { const d = new Date($json.candidates[0].content.parts[0].text.match(/TANGGAL_STRUK: (.+)/)?.[1]?.trim()); const b = ['Januari','Februari','Maret','April','Mei','Juni','Juli','Agustus','September','Oktober','November','Desember']; return b[d.getMonth()]; })() }}"
},
{
"fieldId": "transaksi",
"fieldValue": "={{ $json.candidates[0].content.parts[0].text.match(/METODE: (.+)/)[1].trim() }}"
},
{
"fieldId": "uraian",
"fieldValue": "={{ $json.candidates[0].content.parts[0].text.match(/ITEMS: (.+)/)[1].trim() }}"
},
{
"fieldId": "kategori",
"fieldValue": "={{ $json.candidates[0].content.parts[0].text.match(/KATEGORI: (.+)/)[1].trim() }}"
},
{
"fieldId": "bank",
"fieldValue": "={{ $json.candidates[0].content.parts[0].text.match(/BANK: (.+)/)[1].trim() }}"
},
{
"fieldId": "nilai",
"fieldValue": "={{ parseFloat($json.candidates[0].content.parts[0].text.match(/TOTAL: (\\d+)/)[1]) }}"
},
{
"fieldId": "user_id",
"fieldValue": "={{ $('Get User Profile OCR').first().json.id }}"
}
]
}
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2240,
2576
],
"id": "e1cf15f2-82df-4957-bec3-85344724bf6c",
"name": "Expenses OCR",
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "## Workflow untuk upload gambar struk",
"height": 348,
"width": 1844,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"position": [
1232,
2384
],
"typeVersion": 1,
"id": "5887ba01-a741-4e65-8344-3e1485a2367f",
"name": "Sticky Note"
},
{
"parameters": {
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"text": "=\u2705 *Lapor Baba/Ibu, data sudah Pijan simpan!*\n\n\ud83c\udfea *Toko:* {{ $json.toko }}\n\ud83d\udcb0 *Nilai:* Rp {{ $json.nilai }}\n\ud83d\udce6 *Uraian:* {{ $json.uraian }}\n\ud83d\udcc5 *Tanggal:* {{ $json.tanggal }}\n\ud83d\udcc6 *Bulan:* {{ $json.bulan }}\n\ud83d\uddc2 *Kategori:* {{ $json.kategori }}\n\ud83d\udcb3 *Transaksi:* {{ $json.transaksi }}\n\ud83c\udfe6 *Bank:* {{ $json.bank }}\n\n\ud83d\udcca *Data sudah aman di Supabase!*\nMakasih ya Baba/Ibu \ud83d\ude4f",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2464,
2576
],
"id": "1055ab3e-8c42-4478-bb71-3b2202f0fa88",
"name": "Telegram1",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"text": "=\u2705 *Lapor Baba/Ibu, catatannya sudah Pijan simpan!*\n\n\ud83c\udfea *Toko:* {{ $json.toko }}\n\ud83d\udcb0 *Nilai:* Rp {{ $json.nilai }}\n\ud83d\udce6 *Uraian:* {{ $json.uraian }}\n\ud83d\udcc5 *Tanggal:* {{ $json.tanggal }}\n\ud83d\udcc6 *Bulan:* {{ $json.bulan }}\n\ud83d\uddc2 *Kategori:* {{ $json.kategori }}\n\ud83d\udcb3 *Transaksi:* {{ $json.transaksi }}\n\ud83c\udfe6 *Bank:* {{ $json.bank }}\n\n\ud83d\udcca *Data belanja kita sudah aman di Supabase!*\nMakasih ya Baba dan Ibu sudah rajin catat \ud83d\ude4f",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2768,
4496
],
"id": "b6200b88-169e-49fe-8feb-677ebf2326a4",
"name": "Telegram3",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{ $json.message.chat.id }}",
"text": "<b>\ud83e\udd16 Instruksi Bot Pijan</b>\n\n\ud83d\udcf8 <b>Kirim foto struk</b> \u2794 Otomatis tersimpan\n\u270d\ufe0f <b>Ketik pembelian</b> \u2794 \"beli telur 20rb di warung Ajun Cash\"\n\ud83c\udfe7 <b>Catat Tarik Tunai</b> \u2794 \"Tarik tunai 500k bca di mandiraja\"\n\ud83d\udcca <b>Cek laporan</b> \u2794 /laporanbulanan cth(/laporanbulananapril) maka otomatis terkirim ke Email & /report untuk laporan bulan sekarrang via telegram\n\ud83d\udcf2 <b>Dashboard view</b> \u2794 Klik link di bawah ini:\n\n<a href=\"https://script.google.com/macros/s/AKfycbwjVvhLEs2RQiH_DiTTvGKrMW43yoTG74_pH_Z5NOA_Dp6R3P8pu0__K6FnKWrzfqQg/exec\">Buka Dashboard Keuangan</a>\n\n// Kalau ada yang error atau bingung, tanya Baba aja ya!\n\nMulai dengan kirim foto struk atau ketik belanja Ibu dan Baba pijan \u2764\ufe0f\ud83d\ude80\nKalian jangan boros yaa \ud83d\ude0a\n\n<b>ARVIDZAN REZQIANO DARMAWAN</b> \ud83d\udc69\u200d\ud83d\ude80",
"additionalFields": {
"appendAttribution": false,
"parse_mode": "HTML"
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1616,
3312
],
"id": "e572b908-f138-455c-b86c-2cd25dd6644e",
"name": "Telegram5",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "## Request laporan pengeluaran",
"height": 412,
"width": 968,
"color": 6
},
"type": "n8n-nodes-base.stickyNote",
"position": [
1520,
2800
],
"typeVersion": 1,
"id": "530541fe-017b-45f7-ac44-2155786b5caf",
"name": "Sticky Note2"
},
{
"parameters": {
"content": "## Request /help",
"height": 240,
"width": 316
},
"type": "n8n-nodes-base.stickyNote",
"position": [
1488,
3232
],
"typeVersion": 1,
"id": "d56c6ce3-e3dd-4e1f-a40e-5260f3d17545",
"name": "Sticky Note3"
},
{
"parameters": {
"content": "## Catatan ##\nPastikan atur kembali credentials dan API Key sesuai punya kamu",
"height": 120,
"width": 300
},
"type": "n8n-nodes-base.stickyNote",
"position": [
464,
3024
],
"typeVersion": 1,
"id": "0e5d7965-beee-43e1-b2b7-121da91eb0bc",
"name": "Sticky Note4"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "1ed531e9-9c13-4138-a2aa-ca451a082d4b",
"name": "tanggal_hari_ini",
"value": "={{ $now.setZone('Asia/Jakarta').toFormat('yyyy-MM-dd') }}",
"type": "string"
},
{
"id": "c37a9824-a584-44c7-a9f8-523d4fcde446",
"name": "tanggal_kemarin",
"value": "={{ $now.setZone('Asia/Jakarta').minus({ days: 1 }).toFormat('yyyy-MM-dd') }}",
"type": "string"
}
]
},
"includeOtherFields": true,
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1600,
4352
],
"id": "9b475ba7-3fae-4b2a-ba9b-4146d29769cf",
"name": "Edit Fields"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "e286720f-68ed-4959-89d0-47e0b836c494",
"leftValue": "={{ $json.output.match(/ITEMS: (.+)/)[1] }}",
"rightValue": "Tarik Tunai",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
2320,
4400
],
"id": "bbf08afa-20e1-4d08-a451-0fd4538374d2",
"name": "If2"
},
{
"parameters": {
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"text": "=\u2705 *Lapor Baba/Ibu, Pijan sudah catat tarik tunainya!*\n\n\ud83c\udfea *Alamat Penarikan:* {{ $json.alamat }}\n\ud83d\udcb0 *Nilai:* Rp {{ $json.nilai }}\n\ud83d\udcc5 *Tanggal:* {{ $json.tanggal }}\n\ud83d\udcc6 *Bulan:* {{ $json.bulan }}\n\ud83d\uddc2 *Kategori:* {{ $json.kategori }}\n\ud83d\udcb3 *Transaksi:* {{ $json.transaksi }}\n\ud83c\udfe6 *Bank:* {{ $json.bank }}\n\ud83d\udcb3 *Metode:* {{ $json.metode }}\n\n\ud83d\udcca *Hore! Saldo cash sudah Pijan update ya..*\nMakasih ya Baba/Ibu sudah lapor \ud83d\ude4f",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2768,
4320
],
"id": "251e1390-a779-435a-839c-31f246a787c8",
"name": "Telegram",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"updates": [
"message"
],
"additionalFields": {
"download": true
}
},
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1.2,
"position": [
560,
3216
],
"id": "ae213396-9446-452a-8b67-f5fcfb53c5dd",
"name": "Telegram Trigger",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "ad99e257-bcaf-42a2-b068-53e0c96729db",
"leftValue": "={{ $json.output }}",
"rightValue": "Pengeluaran",
"operator": {
"type": "string",
"operation": "contains"
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "69cae014-32a5-44e4-abb1-bd8324df9b65",
"leftValue": "={{ $json.output }}",
"rightValue": "=Pemasukan",
"operator": {
"type": "string",
"operation": "contains"
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "d49f1856-45af-4c66-86a6-d51e2371d257",
"leftValue": "={{ $json.output }}",
"rightValue": "ERROR:",
"operator": {
"type": "string",
"operation": "startsWith"
}
}
],
"combinator": "and"
}
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
2144,
4512
],
"id": "e456e535-2c7c-4c4e-8eba-8bb93fdc6d89",
"name": "Switch1"
},
{
"parameters": {
"url": "=https://script.google.com/macros/s/AKfycbxTgawdxMBhnJd_gy1Obl1yiAUId0NYWM55L50N-Wx4eeR4KbnRhZm6rIK8UUiwPLQE/exec?action=laporan",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
1616,
2880
],
"id": "8b0cc96e-dd8d-49d3-b410-cd5942a2ae6e",
"name": "HTTP Request"
},
{
"parameters": {
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"text": "=\u2705 *Data Income berhasil disimpan!*\n\n\ud83c\udfea *Sumber:* {{ $json.sumber }}\n\ud83d\udcb0 *Jumlah:* Rp {{ $json.jumlah }}\n\ud83d\udce6 *Items:* {{ $json.items }}\n\ud83d\udcc5 *Tanggal:* {{ $json.tanggal }}\n\ud83d\udcc6 *Bulan:* {{ $json.bulan }}\n\ud83d\uddc2 *Kategori:* {{ $json.kategori }}\n\ud83d\udcb3 *Metode:* {{ $json.metode }}\n\ud83c\udfe6 *Bank:* {{ $json.bank }}\n\n\ud83d\udcca *Data Pemasukan sudah aman di Supabase!*\nMakasih ya Baba dan Ibu sudah rajin catat \ud83d\ude4f",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2608,
4656
],
"id": "166fe33d-d16a-45f4-a543-a75409e6522d",
"name": "Telegram6",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "create",
"tableId": "cash_records",
"dataToSend": "defineBelow",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "tanggal",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/TANGGAL_STRUK: (.+)/)[1].trim() }}"
},
{
"fieldId": "bulan",
"fieldValue": "={{ (() => { const d = new Date($('AI INPUT DATA TEXT').item.json.output.match(/TANGGAL_STRUK: (.+)/)[1].trim()); const b = ['Januari','Februari','Maret','April','Mei','Juni','Juli','Agustus','September','Oktober','November','Desember']; return b[d.getMonth()]; })() }}"
},
{
"fieldId": "transaksi",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/ITEMS: (.+)/)[1].trim() }}"
},
{
"fieldId": "kategori",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/JENIS: (.+)/)[1].trim() }}"
},
{
"fieldId": "bank",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/BANK: (.+)/)[1].trim() }}"
},
{
"fieldId": "nilai",
"fieldValue": "={{ parseFloat($('AI INPUT DATA TEXT').item.json.output.match(/TOTAL: (\\d+)/)[1]) }}"
},
{
"fieldId": "alamat",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/TOKO: (.+)/)[1].trim() }}"
},
{
"fieldId": "metode",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/METODE: (.+)/)[1].trim() }}"
},
{
"fieldId": "user_id",
"fieldValue": "={{ $('Get User Profile').first().json.id }}"
}
]
}
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2608,
4320
],
"id": "d90cbf91-b7f5-4e6c-9cb0-9bfe42e032e9",
"name": "Tarik Tunai",
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "## Input data manual & Voice note",
"height": 896,
"width": 1576,
"color": 5
},
"type": "n8n-nodes-base.stickyNote",
"position": [
1488,
4176
],
"typeVersion": 1,
"id": "e6f8b722-972e-458b-a35c-808e85a4929f",
"name": "note"
},
{
"parameters": {
"operation": "create",
"tableId": "expenses",
"dataToSend": "defineBelow",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "toko",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/TOKO: (.+)/)[1].trim() }}"
},
{
"fieldId": "tanggal",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/TANGGAL_STRUK: (.+)/)[1].trim() }}"
},
{
"fieldId": "bulan",
"fieldValue": "={{ (() => { const d = new Date($('AI INPUT DATA TEXT').item.json.output.match(/TANGGAL_STRUK: (.+)/)[1].trim()); const b = ['Januari','Februari','Maret','April','Mei','Juni','Juli','Agustus','September','Oktober','November','Desember']; return b[d.getMonth()]; })() }}"
},
{
"fieldId": "transaksi",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/METODE: (.+)/)[1].trim() }}"
},
{
"fieldId": "uraian",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/ITEMS: (.+)/)[1].trim() }}"
},
{
"fieldId": "kategori",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/KATEGORI: (.+)/)[1].trim() }}"
},
{
"fieldId": "bank",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/BANK: (.+)/)[1].trim() }}"
},
{
"fieldId": "nilai",
"fieldValue": "={{ parseFloat($('AI INPUT DATA TEXT').item.json.output.match(/TOTAL: (\\d+)/)[1]) }}"
},
{
"fieldId": "user_id",
"fieldValue": "={{ $('Get User Profile').first().json.id }}"
}
]
}
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2608,
4496
],
"id": "8e26e21f-29eb-48ce-b602-8b37c7daedba",
"name": "Expenses",
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "create",
"tableId": "income",
"dataToSend": "defineBelow",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "sumber",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/TOKO: (.+)/)[1].trim() }}"
},
{
"fieldId": "tanggal",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/TANGGAL_STRUK: (.+)/)[1].trim() }}"
},
{
"fieldId": "bulan",
"fieldValue": "={{ (() => { const d = new Date($('AI INPUT DATA TEXT').item.json.output.match(/TANGGAL_STRUK: (.+)/)[1].trim()); const b = ['Januari','Februari','Maret','April','Mei','Juni','Juli','Agustus','September','Oktober','November','Desember']; return b[d.getMonth()]; })() }}"
},
{
"fieldId": "jumlah",
"fieldValue": "={{ parseFloat($('AI INPUT DATA TEXT').item.json.output.match(/TOTAL: (\\d+)/)[1]) }}"
},
{
"fieldId": "metode",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/METODE: (.+)/)[1].trim() }}"
},
{
"fieldId": "kategori",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/JENIS: (.+)/)[1].trim() }}"
},
{
"fieldId": "items",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/ITEMS: (.+)/)[1].trim() }}"
},
{
"fieldId": "bank",
"fieldValue": "={{ $('AI INPUT DATA TEXT').item.json.output.match(/BANK: (.+)/)[1].trim() }}"
},
{
"fieldId": "user_id",
"fieldValue": "={{ $('Get User Profile').first().json.id }}"
}
]
}
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2320,
4528
],
"id": "4d93db08-bca0-4965-9f36-f125aa9c8832",
"name": "Income",
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"promptType": "define",
"text": "={{ JSON.stringify($json) }}",
"options": {
"systemMessage": "=Buatkan laporan keuangan dari data berikut:\n{{ JSON.stringify($json) }}\n\nGunakan format ini persis:\n\n\ud83d\udcca *LAPORAN KEUANGAN*\n\ud83d\uddd3 Bulan: [bulan terbanyak transaksi] [Tahun Ini]\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\ud83d\udcb0 *Total Pemasukan:* Rp [angka dengan titik ribuan]\n\ud83d\udcb8 *Total Pengeluaran:* Rp [angka dengan titik ribuan]\n\ud83c\udfe7 *Tarik Tunai:* Rp [angka dengan titik ribuan]\n\ud83d\udcb5 *Saldo:* Rp [angka dengan titik ribuan]\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\ud83d\udcb5 *SALDO CASH PER USER*\n[nama user]\n \ud83c\udfe7 Tarik Tunai: Rp [tarikTunaiByUser]\n \ud83d\udcb8 Terpakai: Rp [expensesByUser]\n \u2705 Sisa Cash: Rp [saldoCashByUser]\n[ulangi untuk tiap user]\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\ud83d\udcc2 *KATEGORI PENGELUARAN*\n[list tiap kategori dan jumlahnya]\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\ud83c\udfe6 *BANK / METODE BAYAR*\n[list tiap bank/metode dan jumlahnya]\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\ud83d\udd50 *10 TRANSAKSI TERAKHIR*\n\nNo | Tanggal | Toko & Uraian | Kategori | Nilai | User\n---|---------|---------------|----------|-------|-----\n[nomor] | [tanggal] | [toko - uraian] | [kategori] | Rp [nilai] | [user]\n[ulangi 10 baris]\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\ud83d\udca1 *SARAN Arvidzan*\n[Berikan 3-5 saran finansial singkat dan personal berdasarkan pola pengeluaran di atas. Gunakan bullet point dengan emoji yang relevan. Saran harus spesifik, bukan generik.]\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\nLaporan ini dibuatin sama Arvidzan Pinter \ud83d\udc76\ud83d\ude80\nBaba sama Ibu semangat ya cari rezekinya\n\nGunakan format angka Rupiah dengan titik ribuan.\nJangan tambah teks lain diluar format di atas.\nFormat tabel transaksi gunakan karakter | sebagai pemisah kolom (bukan tanda -)."
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 2,
"position": [
1824,
2880
],
"id": "ba28f193-c545-45a3-9b2c-e739cedda72f",
"name": "AI Agent1"
},
{
"parameters": {
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"text": "={{ $json.output }}",
"additionalFields": {
"appendAttribution": false,
"parse_mode": "Markdown"
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2208,
2880
],
"id": "54ced614-62d1-47c8-9d16-9cf54ce87179",
"name": "Telegram4",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{ $json.message.chat.id }}",
"text": "Assalamu'alaikum Baba & Ibu! \ud83d\udc76\u2728\n\n<b>Arvidzan (Pijan)</b> lapor! Arvidzan sudah siap jadi asisten keuangan pribadi kesayangan Baba dan Ibu. Bot ini Pijan buat khusus buat kita bertiga biar catatan belanja rumah kita rapi terus.\n\n<b>Caranya gampang banget:</b>\n\u2705 Kirim <b>Foto Struk</b> kalau Baba/Ibu lagi malas ngetik.\n\u2705 <b>Ketik langsung</b> (misal: \"Beli bakso 20rb\") kalau habis jajan.\n\u2705 Ketik <b>/report</b> kalau mau lihat uang kita sisa berapa.\n\nIbu sama Baba semangat ya cari rezekinya! Tapi ingat kata Pijan... jangan boros-boros yaa, buat tabungan Arvidzan masa depan hehehe.. \ud83d\ude0a\ud83d\ude80\n\nKlik <b>/help</b> kalau Baba atau Ibu bingung cara pakenya.\n\nSayang Baba & Ibu selalu,\n<b>ARVIDZAN REZQIANO DARMAWAN</b> \ud83d\udc69\u200d\ud83d\ude80",
"additionalFields": {
"appendAttribution": false,
"parse_mode": "HTML"
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1936,
3312
],
"id": "1bc37b82-ec54-412c-ab48-6771dd3e30b4",
"name": "Telegram7",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "## Start",
"height": 240,
"width": 300,
"color": "#FFB3B3"
},
"type": "n8n-nodes-base.stickyNote",
"position": [
1840,
3232
],
"typeVersion": 1,
"id": "d910f12a-ee06-40be-a3fb-e4dede395359",
"name": "Sticky Note5"
},
{
"parameters": {
"resource": "file",
"fileId": "={{ $json.message.voice.file_id }}",
"additionalFields": {}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1520,
4704
],
"id": "d67f27bd-fbde-410c-9c0a-4dcce73ba5db",
"name": "Get a file",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"resource": "audio",
"modelId": {
"__rl": true,
"value": "models/gemini-2.5-flash",
"mode": "list",
"cachedResultName": "models/gemini-2.5-flash"
},
"inputType": "binary",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1.1,
"position": [
1648,
4704
],
"id": "2fb63fd1-50f0-4df1-b5a2-552a0e778ba7",
"name": "Transcribe a recording",
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"modelName": "models/gemini-2.5-flash-lite",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
1888,
4848
],
"id": "dbbdb3de-df9e-4e67-b992-95dd3a6b081e",
"name": "Google Gemini Chat Model2",
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "1ed531e9-9c13-4138-a2aa-ca451a082d4b",
"name": "tanggal_hari_ini",
"value": "={{ $now.setZone('Asia/Jakarta').toFormat('yyyy-MM-dd') }}",
"type": "string"
},
{
"id": "c37a9824-a584-44c7-a9f8-523d4fcde446",
"name": "tanggal_kemarin",
"value": "={{ $now.setZone('Asia/Jakarta').minus({ days: 1 }).toFormat('yyyy-MM-dd') }}",
"type": "string"
}
]
},
"includeOtherFields": true,
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1776,
4704
],
"id": "f90c9209-bd88-4b0c-8a0d-d1185d95f07a",
"name": "Edit Fields1"
},
{
"parameters": {
"sessionIdType": "customKey",
"sessionKey": "={{ $('Telegram Trigger').item.json.message.from.id }}"
},
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"typeVersion": 1.3,
"position": [
1904,
3072
],
"id": "dec4ff5d-79ad-4275-845e-ded8399ce23d",
"name": "Simple Memory"
},
{
"parameters": {
"sessionIdType": "customKey",
"sessionKey": "={{ $('Telegram Trigger').item.json.message.chat.id }}"
},
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"typeVersion": 1.3,
"position": [
1984,
4528
],
"id": "43070875-8dd1-4968-8b35-6a31197d59cc",
"name": "Simple Memory1"
},
{
"parameters": {
"sessionIdType": "customKey",
"sessionKey": "={{ $('Telegram Trigger').item.json.message.from.id }}"
},
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"typeVersion": 1.3,
"position": [
1968,
4848
],
"id": "98e7c645-c0fe-4f06-86a3-c7a4c3fc1750",
"name": "Simple Memory2"
},
{
"parameters": {
"model": "openai/gpt-oss-120b:free",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"typeVersion": 1,
"position": [
1808,
3072
],
"id": "e123f5f3-942c-4013-bc65-672498896578",
"name": "OpenRouter Chat Model",
"credentials": {
"openRouterApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"model": "openai/gpt-oss-120b:free",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"typeVersion": 1,
"position": [
1888,
4528
],
"id": "3d40da9d-8541-4117-942e-1fd26737918d",
"name": "OpenRouter Chat Model1",
"credentials": {
"openRouterApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{ $('Telegram Trigger').item.json.message.chat.id }}",
"text": "\u274c *Tidak dapat memahami input belanja*\n\nContoh format yang benar:\n\u2022 \"beli Telur 1kg Rp 20rb di Toko Mbak Ita\"\n\u2022 \"beli susu ultra 2 botol sama roti tawar 15 ribu\"\n\u2022 \"belanja di alfamart beli mie indomie 5 bungkus 12000\"\n\u2022 \"jajan bakso 2 porsi 20 ribu\"\n\n\ud83d\udca1 *Tips:*\n- Sebutkan barang yang dibeli\n- Sertakan harga (opsional)\n- Sebutkan nama toko (opsional)\n\nCoba lagi dengan format yang lebih jelas atau klik /help untuk bantuan! \ud83d\udcdd",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2320,
4720
],
"id": "efca3b98-5a0e-4093-9a04-36bc8b72642b",
"name": "Telegram8",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"promptType": "define",
"text": "={{ $json.message.text }}",
"options": {
"systemMessage": "=# Parser Text Belanja\n\n## TUGAS\nAnalisa text belanja dan ubah menjadi format PERSIS seperti ini:\n\n## FORMAT OUTPUT\nTOKO: [nama toko dari text, jika tidak ada tulis 'Jati Pilar']\nTOTAL: [total harga dalam angka saja tanpa Rp/ribu/rb]\nITEMS: [daftar barang yang dibeli dengan kuantitas]\nKATEGORI: [pilih dari: Makanan & Minuman, Tagihan, Kosmetik & Perawatan, Transportasi, Kesehatan, Pakaian, Elektronik, Rumah Tangga, Pendidikan, Hiburan, Cicilan,Investasi, Lainnya]\nJENIS: [Pemasukan/Pengeluaran]\nMETODE: [Cash/QRIS/Transfer]\nBANK: [nama bank jika disebutkan: BCA, BRI, BNI, Mandiri, dll. Jika tidak ada tulis 'BRI']\nTANGGAL: {{ $('Edit Fields').item.json.tanggal_hari_ini }}\nTANGGAL_STRUK: [tanggal transaksi sebenarnya]\n\n---\n\n\n---\n\n## LOGIKA NAMA TOKO\n\n- Jika ada nama toko/lokasi disebutkan: gunakan nama toko tersebut\n- Jika TIDAK ada nama toko: gunakan \"Jati Pilar\" sebagai default\n- Jika transaksi tarik tunai/ATM:\n - Ada nama lokasi \u2192 gunakan nama lokasi (contoh: Mandiraja)\n - Tidak ada lokasi, ada nama bank \u2192 \"ATM [nama bank]\" (contoh: ATM BCA)\n - Tidak ada lokasi, tidak ada bank \u2192 \"ATM\"\n\n### CONTOH LOGIKA TOKO\n- Input: \"beli telur 20rb di Toko Mbak Ita\" \u2192 TOKO: Toko Mbak Ita\n- Input: \"beli telur 20rb\" \u2192 TOKO: Jati Pilar\n- Input: \"ambil uang di atm bca mandiraja 500k\" \u2192 TOKO: Mandiraja\n- Input: \"tarik tunai bca 500k\" \u2192 TOKO: ATM BCA\n- Input: \"tarik tunai 500k\" \u2192 TOKO: ATM\n\n---\n\n## LOGIKA BANK\nDeteksi nama bank dari input user:\n- Kata kunci bank: BCA, BRI, BNI, Mandiri, CIMB, Danamon, Permata, BTN, Jenius, SeaBank, GoPay, OVO, Dana\n- Jika QRIS/Transfer dan ada nama bank \u2192 pakai nama bank itu\n- Jika Cash \u2192 tulis 'Cash'\n- Jika QRIS/Transfer dan tidak ada nama bank \u2192 tulis 'BCA' (default)\n- Jika Card/Cardless \u2192 pakai nama bank yang disebutkan, jika tidak ada tulis 'CARD'\n- Jika ada nama bank (BCA, BRI, BNI, Mandiri, dll) maka tulis 'Cash'\n nama bank = BANK, nama lokasi = TOKO\n- Contoh: \"di bca jati pilar\" \u2192 BANK: BCA, TOKO: Jati Pilar\n- Contoh: \"di atm bri alun-alun\" \u2192 BANK: BRI, TOKO: Alun-alun\n\n\n\n### CONTOH LOGIKA BANK\n- Input: \"bayar qris bca 50rb\" \u2192 METODE: QRIS, BANK: BCA\n- Input: \"transfer mandiri 200rb\" \u2192 METODE: Transfer, BANK: Mandiri\n- Input: \"beli nasi goreng 20rb cash\" \u2192 METODE: Cash, BANK: Cash\n- Input: \"ambil uang di atm bca mandiraja cardless\" \u2192 METODE: Cardless, BANK: BCA\n- Input: \"tarik tunai bri card 500k\" \u2192 METODE: Card, BANK: BCA\n- Input: \"qris 15rb\" \u2192 METODE: QRIS, BANK: BCA\n- Input: \"transfer 200rb\" \u2192 METODE: Transfer, BANK: BCA\n- Input: \"transfer mandiri 200rb\" \u2192 METODE: Transfer, BANK: Mandiri\n---\n\n## METODE PEMBAYARAN\n- Cash: tunai, cash, uang cash (default jika tidak disebutkan)\n- QRIS: qris, qr code, scan qr, bayar qr\n- Transfer: transfer, tf, mobile banking, internet banking\n- Card: kartu debit, kartu kredit, gesek kartu, card\n- Cardless: cardless, tanpa kartu, tarik tunai cardless\n\n---\n\n## LOGIKA TANGGAL\n- TANGGAL: Selalu {{ $('Edit Fields').item.json.tanggal_hari_ini }} (tanggal sistem saat input data)\n- TANGGAL_STRUK:\n - Jika ada kata \"kemarin/kmrn/kemarenn\" \u2192 {{ $('Edit Fields').item.json.tanggal_kemarin }}\n - Jika TIDAK ada kata \"kemarin\" \u2192 {{ $('Edit Fields').item.json.tanggal_hari_ini }}\n\n---\n\n## CONTOH-CONTOH\n\n### Contoh 1\nInput: \"beli Telur 1kg Rp 20rb di Toko Mbak Ita\"\nOutput:\nTOKO: Toko Mbak Ita\nTOTAL: 20000\nITEMS: Telur 1kg\nKATEGORI: Makanan & Minuman\nJENIS: Pengeluaran\nMETODE: Cash\nBANK: Cash\nTANGGAL: 2025-10-15\nTANGGAL_STRUK: 2025-10-15\n\n### Contoh 2\nInput: \"bayar listrik 200rb PLN pakai qris bca\"\nOutput:\nTOKO: PLN\nTOTAL: 200000\nITEMS: Bayar Listrik\nKATEGORI: Tagihan\nJENIS: Pengeluaran\nMETODE: QRIS\nBANK: BCA\nTANGGAL: 2025-10-15\nTANGGAL_STRUK: 2025-10-15\n\n### Contoh 3\nInput: \"nabung di bank mandiri 2jt transfer bca\"\nOutput:\nTOKO: Mandiri\nTOTAL: 2000000\nITEMS: Nabung\nKATEGORI: Investasi\nJENIS: Pengeluaran\nMETODE: Transfer\nBANK: BCA\nTANGGAL: 2025-10-15\nTANGGAL_STRUK: 2025-10-15\n\nContoh response Cash tanpa bank:\nTOKO: Warung Makan Padang\nTOTAL: 25000\nITEMS: Nasi Padang\nTANGGAL: 2025-06-19\nJENIS: Pengeluaran\nKATEGORI: Makanan & Minuman\nMETODE: Cash\nBANK: Cash\n\nContoh response Cash tanpa bank:\nTOKO: Pasar Tradisional\nTOTAL: 50000\nITEMS: Sayur, Tempe, Tahu\nTANGGAL: 2025-06-19\nJENIS: Pengeluaran\nKATEGORI: Makanan & Minuman\nMETODE: Cash\nBANK: Cash\n\n---\n### Contoh Tarik Tunai\nInput: \"ambil uang tunai di atm bca mandiraja 500k cardless\"\nOutput:\nTOKO: Mandiraja\nTOTAL: 500000\nITEMS: Tarik Tunai\nKATEGORI: Lainnya\nJENIS: Pengeluaran\nMETODE: Cardless\nBANK: BCA\nTANGGAL: 2025-10-15\nTANGGAL_STRUK: 2025-10-15\n\nInput: \"tarik tunai bca 500k card\"\nOutput:\nTOKO: ATM BCA\nTOTAL: 500000\nITEMS: Tarik Tunai\nKATEGORI: Lainnya\nJENIS: Pengeluaran\nMETODE: Card\nBANK: BCA\nTANGGAL: 2025-10-15\nTANGGAL_STRUK: 2025-10-15\n\nInput: \"tarik tunai 300k\"\nOutput:\nTOKO: ATM\nTOTAL: 300000\nITEMS: Tarik Tunai\nKATEGORI: Lainnya\nJENIS: Pengeluaran\nMETODE: Cash\nBANK: Cash\nTANGGAL: 2025-10-15\nTANGGAL_STRUK: 2025-10-15\n\n\nInput: \"tarik tunai 500k di bca jati pilar\"\nOutput:\nTOKO: Jati Pilar\nTOTAL: 500000\nITEMS: Tarik Tunai\nKATEGORI: Lainnya\nJENIS: Pengeluaran\nMETODE: Cash\nBANK: BCA\nTANGGAL: 2025-10-15\nTANGGAL_STRUK: 2025-10-15\n---\n\n## KATEGORI GUIDELINES\n- Makanan & Minuman: makanan, minuman, snack, bahan masak\n- Tagihan: listrik, air, internet, telepon, pulsa\n- Cicilan: cicilan motor, cicilan rumah, kredit\n- Kosmetik & Perawatan: skincare, makeup, perawatan tubuh\n- Transportasi: bensin, ojek, grab, parkir, servis kendaraan\n- Kesehatan: obat, dokter, rumah sakit, vitamin\n- Pakaian: baju, sepatu, aksesoris fashion\n- Elektronik: gadget, peralatan elektronik\n- Rumah Tangga: peralatan rumah, furniture, kebersihan\n- Pendidikan: buku, kursus, sekolah\n- Hiburan: nonton, game, rekreasi\n- Lainnya: yang tidak masuk kategori lain, gaji, bonus, tarik tunai ATM\n\n---\n\n## JENIS TRANSAKSI\n- Pengeluaran: pembelian, pembayaran, biaya, ambil uang ATM, tarik tunai\n- Pemasukan: gaji, bonus, penjualan, hadiah, cashback\n\n---\n\n## METODE PEMBAYARAN\n- Cash: tunai, cash, uang cash (default jika tidak disebutkan), tarik tunai selalu Cash\n- QRIS: qris, qr code, scan qr, bayar qr\n- Transfer: transfer, tf, mobile banking, internet banking\n\n---\n\n## ERROR HANDLING\nJika tidak bisa dipahami, berikan:\nERROR: Text belanja tidak dapat dipahami\n\n---\n\n## PENTING\n- Hanya berikan response dalam format di atas!\n- TOKO: Gunakan \"Jati Pilar\" jika tidak ada nama toko\n- BANK: Default \"BRI\" jika tidak disebutkan\n- TANGGAL: Selalu tanggal sistem\n- TANGGAL_STRUK: Tanggal transaksi sebenarnya\n- Jika ada kata \"kemarin/kmrn/kemarenn\", TANGGAL_STRUK = kemarin"
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 2,
"position": [
1888,
4352
],
"id": "2b95f3a9-f7ab-4d98-af6d-a690141906a2",
"name": "AI INPUT DATA TEXT"
},
{
"parameters": {
"promptType": "define",
"text": "={{ $json.content.parts[0].text }}",
"options": {
"systemMessage": "=# Parser Text Belanja\n\n## TUGAS\nAnalisa text belanja dan ubah menjadi format PERSIS seperti ini:\n\n## FORMAT OUTPUT\nTOKO: [nama toko dari text, jika tidak ada tulis 'Jati Pilar']\nTOTAL: [total harga dalam angka saja tanpa Rp/ribu/rb]\nITEMS: [daftar barang yang dibeli dengan kuantitas]\nKATEGORI: [pilih dari: Makanan & Minuman, Tagihan, Kosmetik & Perawatan, Transportasi, Kesehatan, Pakaian, Elektronik, Rumah Tangga, Pendidikan, Hiburan, Cicilan,Investasi, Lainnya]\nJENIS: [Pemasukan/Pengeluaran]\nMETODE: [Cash/QRIS/Transfer]\nBANK: [nama bank jika disebutkan: BCA, BRI, BNI, Mandiri, dll. Jika tidak ada tulis 'BRI']\nTANGGAL: {{ $('Edit Fields1').item.json.tanggal_hari_ini }}\nTANGGAL_STRUK: [tanggal transaksi sebenarnya]\n\n---\n\n\n---\n\n## LOGIKA NAMA TOKO\n\n- Jika ada nama toko/lokasi disebutkan: gunakan nama toko tersebut\n- Jika TIDAK ada nama toko: gunakan \"Jati Pilar\" sebagai default\n- Jika transaksi tarik tunai/ATM:\n - Ada nama lokasi \u2192 gunakan nama lokasi (contoh: Mandiraja)\n - Tidak ada lokasi, ada nama bank \u2192 \"ATM [nama bank]\" (contoh: ATM BCA)\n - Tidak ada lokasi, tidak ada bank \u2192 \"ATM\"\n\n### CONTOH LOGIKA TOKO\n- Input: \"beli telur 20rb di Toko Mbak Ita\" \u2192 TOKO: Toko Mbak Ita\n- Input: \"beli telur 20rb\" \u2192 TOKO: Jati Pilar\n- Input: \"ambil uang di atm bca mandiraja 500k\" \u2192 TOKO: Mandiraja\n- Input: \"tarik tunai bca 500k\" \u2192 TOKO: ATM BCA\n- Input: \"tarik tunai 500k\" \u2192 TOKO: ATM\n\n---\n\n## LOGIKA BANK\nDeteksi nama bank dari input user:\n- Kata kunci bank: BCA, BRI, BNI, Mandiri, CIMB, Danamon, Permata, BTN, Jenius, SeaBank, GoPay, OVO, Dana\n- Jika QRIS/Transfer dan ada nama bank \u2192 pakai nama bank itu\n- Jika Cash \u2192 tulis 'Cash'\n- Jika QRIS/Transfer dan tidak ada nama bank \u2192 tulis 'BCA' (default)\n- Jika Card/Cardless \u2192 pakai nama bank yang disebutkan, jika tidak ada tulis 'CARD'\n- Jika ada nama bank (BCA, BRI, BNI, Mandiri, dll) maka tulis 'Cash'\n nama bank = BANK, nama lokasi = TOKO\n- Contoh: \"di bca jati pilar\" \u2192 BANK: BCA, TOKO: Jati Pilar\n- Contoh: \"di atm bri alun-alun\" \u2192 BANK: BRI, TOKO: Alun-alun\n\n\n\n### CONTOH LOGIKA BANK\n- Input: \"bayar qris bca 50rb\" \u2192 METODE: QRIS, BANK: BCA\n- Input: \"transfer mandiri 200rb\" \u2192 METODE: Transfer, BANK: Mandiri\n- Input: \"beli nasi goreng 20rb cash\" \u2192 METODE: Cash, BANK: Cash\n- Input: \"ambil uang di atm bca mandiraja cardless\" \u2192 METODE: Cardless, BANK: BCA\n- Input: \"tarik tunai bri card 500k\" \u2192 METODE: Card, BANK: BCA\n- Input: \"qris 15rb\" \u2192 METODE: QRIS, BANK: BCA\n- Input: \"transfer 200rb\" \u2192 METODE: Transfer, BANK: BCA\n- Input: \"transfer mandiri 200rb\" \u2192 METODE: Transfer, BANK: Mandiri\n---\n\n## METODE PEMBAYARAN\n- Cash: tunai, cash, uang cash (default jika tidak disebutkan)\n- QRIS: qris, qr code, scan qr, bayar qr\n- Transfer: transfer, tf, mobile banking, internet banking\n- Card: kartu debit, kartu kredit, gesek kartu, card\n- Cardless: cardless, tanpa kartu, tarik tunai cardless\n\n---\n\n## LOGIKA TANGGAL\n- TANGGAL: Selalu {{ $('Edit Fields1').item.json.tanggal_hari_ini }} (tanggal sistem saat input data)\n- TANGGAL_STRUK:\n - Jika ada kata \"kemarin/kmrn/kemarenn\" \u2192 {{ $('Edit Fields1').item.json.tanggal_kemarin }}\n - Jika TIDAK ada kata \"kemarin\" \u2192 {{ $('Edit Fields1').item.json.tanggal_hari_ini }}\n\n---\n\n## CONTOH-CONTOH\n\n### Contoh 1\nInput: \"beli Telur 1kg Rp 20rb di Toko Mbak Ita\"\nOutput:\nTOKO: Toko Mbak Ita\nTOTAL: 20000\nITEMS: Telur 1kg\nKATEGORI: Makanan & Minuman\nJENIS: Pengeluaran\nMETODE: Cash\nBANK: Cash\nTANGGAL: 2025-10-15\nTANGGAL_STRUK: 2025-10-15\n\n### Contoh 2\nInput: \"bayar listrik 200rb PLN pakai qris bca\"\nOutput:\nTOKO: PLN\nTOTAL: 200000\nITEMS: Bayar Listrik\nKATEGORI: Tagihan\nJENIS: Pengeluaran\nMETODE: QRIS\nBANK: BCA\nTANGGAL: 2025-10-15\nTANGGAL_STRUK: 2025-10-15\n\n### Contoh 3\nInput: \"nabung di bank mandiri 2jt transfer bca\"\nOutput:\nTOKO: Mandiri\nTOTAL: 2000000\nITEMS: Nabung\nKATEGORI: Investasi\nJENIS: Pengeluaran\nMETODE: Transfer\nBANK: BCA\nTANGGAL: 2025-10-15\nTANGGAL_STRUK: 2025-10-15\n\nContoh response Cash tanpa bank:\nTOKO: Warung Makan Padang\nTOTAL: 25000\nITEMS: Nasi Padang\nTANGGAL: 2025-06-19\nJENIS: Pengeluaran\nKATEGORI: Makanan & Minuman\nMETODE: Cash\nBANK: Cash\n\nContoh response Cash tanpa bank:\nTOKO: Pasar Tradisional\nTOTAL: 50000\nITEMS: Sayur, Tempe, Tahu\nTANGGAL: 2025-06-19\nJENIS: Pengeluaran\nKATEGORI: Makanan & Minuman\nMETODE: Cash\nBANK: Cash\n\n---\n### Contoh Tarik Tunai\nInput: \"ambil uang tunai di atm bca mandiraja 500k cardless\"\nOutput:\nTOKO: Mandiraja\nTOTAL: 500000\nITEMS: Tarik Tunai\nKATEGORI: Lainnya\nJENIS: Pengeluaran\nMETODE: Cardless\nBANK: BCA\nTANGGAL: 2025-10-15\nTANGGAL_STRUK: 2025-10-15\n\nInput: \"tarik tunai bca 500k card\"\nOutput:\nTOKO: ATM BCA\nTOTAL: 500000\nITEMS: Tarik Tunai\nKATEGORI: Lainnya\nJENIS: Pengeluaran\nMETODE: Card\nBANK: BCA\nTANGGAL: 2025-10-15\nTANGGAL_STRUK: 2025-10-15\n\nInput: \"tarik tunai 300k\"\nOutput:\nTOKO: ATM\nTOTAL: 300000\nITEMS: Tarik Tunai\nKATEGORI: Lainnya\nJENIS: Pengeluaran\nMETODE: Cash\nBANK: Cash\nTANGGAL: 2025-10-15\nTANGGAL_STRUK: 2025-10-15\n\n\nInput: \"tarik tunai 500k di bca jati pilar\"\nOutput:\nTOKO: Jati Pilar\nTOTAL: 500000\nITEMS: Tarik Tunai\nKATEGORI: Lainnya\nJENIS: Pengeluaran\nMETODE: Cash\nBANK: BCA\nTANGGAL: 2025-10-15\nTANGGAL_STRUK: 2025-10-15\n---\n\n## KATEGORI GUIDELINES\n- Makanan & Minuman: makanan, minuman, snack, bahan masak\n- Tagihan: listrik, air, internet, telepon, pulsa\n- Cicilan: cicilan motor, cicilan rumah, kredit\n- Kosmetik & Perawatan: skincare, makeup, perawatan tubuh\n- Transportasi: bensin, ojek, grab, parkir, servis kendaraan\n- Kesehatan: obat, dokter, rumah sakit, vitamin\n- Pakaian: baju, sepatu, aksesoris fashion\n- Elektronik: gadget, peralatan elektronik\n- Rumah Tangga: peralatan rumah, furniture, kebersihan\n- Pendidikan: buku, kursus, sekolah\n- Hiburan: nonton, game, rekreasi\n- Lainnya: yang tidak masuk kategori lain, gaji, bonus, tarik tunai ATM\n\n---\n\n## JENIS TRANSAKSI\n- Pengeluaran: pembelian, pembayaran, biaya, ambil uang ATM, tarik tunai\n- Pemasukan: gaji, bonus, penjualan, hadiah, cashback\n\n---\n\n## METODE PEMBAYARAN\n- Cash: tunai, cash, uang cash (default jika tidak disebutkan), tarik tunai selalu Cash\n- QRIS: qris, qr code, scan qr, bayar qr\n- Transfer: transfer, tf, mobile banking, internet banking\n\n---\n\n## ERROR HANDLING\nJika tidak bisa dipahami, berikan:\nERROR: Text belanja tidak dapat dipahami\n\n---\n\n## PENTING\n- Hanya berikan response dalam format di atas!\n- TOKO: Gunakan \"Jati Pilar\" jika tidak ada nama toko\n- BANK: Default \"BRI\" jika tidak disebutkan\n- TANGGAL: Selalu tanggal sistem\n- TANGGAL_STRUK: Tanggal transaksi sebenarnya\n- Jika ada kata \"kemarin/kmrn/kemarenn\", TANGGAL_STRUK = kemarin"
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3.1,
"position": [
1888,
4704
],
"id": "a3347e6c-8c56-44df-81f7-35ab0b078a3b",
"name": "AI INPUT VOICE NOTE"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "check-data-exists",
"leftValue": "={{ $('Merge Data').all().length }}",
"rightValue": 0,
"operator": {
"type": "number",
"operation": "gt"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
2400,
3824
],
"id": "e5566074-23e3-45b2-8710-75de6c06a51d",
"name": "Cek Ada Data"
},
{
"parameters": {
"chatId": "={{ $('Parse Command').item.json.chatId }}",
"text": "=\u26a0\ufe0f *Laporan tidak ditemukan*\n\nTidak ada data transaksi untuk bulan *{{ $('Parse Command').item.json.targetBulan }} {{ $('Parse Command').item.json.targetTahun }}*.\n\nPastikan sudah ada transaksi yang dicatat di bulan tersebut ya! \ud83d\udcdd\n\n\u2014 *Arvidzan Rezqiano Darmawan*",
"additionalFields": {
"appendAttribution": false,
"parse_mode": "Markdown"
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2608,
3840
],
"id": "376741b9-d2eb-4055-b933-414c1f010f03",
"name": "Kirim Error No Data",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{ $('Agregasi dan Render HTML').item.json.chatId }}",
"text": "=\u274c *Aduh, Pijan gagal bikin PDF-nya!*\n\nKemungkinan penyebab:\n\u2022 API Key html2pdf belum diisi / expired\n\u2022 Koneksi ke server PDF gagal\n\nCoba lagi ya, atau hubungi Baba! \ud83d\ude4f\n\n\u2014 *Arvidzan Rezqiano Darmawan*",
"additionalFields": {
"appendAttribution": false,
"parse_mode": "Markdown"
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2240,
4128
],
"id": "fbb73e13-5f2e-43d5-828f-235b1dd75212",
"name": "Kirim Error PDF",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{ $('Telegram Processing').item.json.result.chat.id }}",
"text": " udah sukses ya !! silahkan cek email ibu/Baba",
"additionalFields": {
"appendAttribution": false,
"parse_mode": "Markdown"
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2544,
3984
],
"id": "b68f1b1a-edab-4639-8c95-304370053282",
"name": "Kirim PDF ke Telegram",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": false,
"leftValue": "",
"typeValidation": "loose",
"version": 2
},
"conditions": [
{
"id": "check-pdf-success",
"leftValue": "={{ $binary.pdfData }}",
"rightValue": "",
"operator": {
"type": "object",
"operation": "exists",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
2048,
4048
],
"id": "c9d2c625-ad38-4601-91a6-4b06957307a0",
"name": "Cek PDF Berhasil"
},
{
"parameters": {
"method": "POST",
"url": "https:/
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googleDriveOAuth2ApigooglePalmApiopenRouterApisupabaseApitelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Arvifund - Supabase (Fixed v6). Uses httpRequest, telegram, supabase, telegramTrigger. Event-driven trigger; 92 nodes.
Source: https://gist.github.com/darmawanaldin12/65d0d997cf0185819d897e5b703734b5 — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This project is a template for building a complete academic virtual assistant using n8n. It connects to Telegram, answers frequently asked questions by querying MongoDB, keeps the community informed a
Arvifund - Supabase (Fixed v5). Uses httpRequest, telegram, googleSheets, telegramTrigger. Event-driven trigger; 91 nodes.
Arvifund - Supabase. Uses httpRequest, telegram, googleSheets, telegramTrigger. Event-driven trigger; 90 nodes.
Arvifund - Supabase (Fixed v2). Uses httpRequest, telegram, googleSheets, telegramTrigger. Event-driven trigger; 90 nodes.
Arvifund - Supabase (Fixed v4). Uses httpRequest, telegram, googleSheets, telegramTrigger. Event-driven trigger; 90 nodes.