Factura de agua

Intermedio

Este es unMiscellaneous, Multimodal AIflujo de automatización del dominio deautomatización que contiene 15 nodos.Utiliza principalmente nodos como Set, Code, Switch, Telegram, GoogleSheets. Automatizar el cálculo de tarifas de agua con Telegram, Gemini AI y Google Sheets

Requisitos previos
  • Bot Token de Telegram
  • Credenciales de API de Google Sheets
  • Clave de API de Google Gemini
Vista previa del flujo de trabajo
Visualización de las conexiones entre nodos, con soporte para zoom y panorámica
Exportar flujo de trabajo
Copie la siguiente configuración JSON en n8n para importar y usar este flujo de trabajo
{
  "id": "3dPhcViLijZ5zBah",
  "meta": {
    "instanceId": "f357e038067887a62c03e581da0f98dfa8010dcc02f1fa97f81df592773a1c40",
    "templateCredsSetupCompleted": true
  },
  "name": "TagihanAir",
  "tags": [],
  "nodes": [
    {
      "id": "0251a048-cd44-464c-8094-89a9baff4695",
      "name": "Disparador de Telegram",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -2688,
        -240
      ],
      "webhookId": "665df113-870a-4b73-832c-075ca8e3caa2",
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "9da0ef32-0aae-47d4-ad66-ddeb8ff60e07",
      "name": "Redirect Message Types",
      "type": "n8n-nodes-base.switch",
      "position": [
        -2384,
        -256
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Image Message",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "05b30af4-967b-4824-abdc-84a8292ac0e5",
                    "operator": {
                      "type": "object",
                      "operation": "exists",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.message.photo[0] }}",
                    "rightValue": ""
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra",
          "renameFallbackOutput": "Text Message"
        }
      },
      "typeVersion": 3.2
    },
    {
      "id": "22e0a88e-aa48-46f2-896a-99473313fe34",
      "name": "Get a file",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -1936,
        -240
      ],
      "webhookId": "4b59179c-2b2a-47fa-9a06-cfe9a8be8db7",
      "parameters": {
        "fileId": "={{ $json.message.photo[3].file_id }}",
        "resource": "file",
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "40406678-0fce-4f9a-9335-69e3600c84e8",
      "name": "Image Explainer",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        -1488,
        -64
      ],
      "parameters": {
        "text": "=Ambil angka didalam kotak m³\nCaption : {{ $('Telegram Trigger').item.json.message.caption }}",
        "messages": {
          "messageValues": [
            {
              "type": "HumanMessagePromptTemplate",
              "messageType": "imageBinary"
            }
          ]
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.4
    },
    {
      "id": "0d24bce4-067b-40af-bb51-b6ca5c0a9ae3",
      "name": "Modelo de chat Google Gemini",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -1536,
        192
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "edfc1d10-e1b8-460c-b850-7eb4d1b5f30f",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -1344,
        144
      ],
      "parameters": {
        "jsonSchemaExample": "{\n\t\"m3\": \"00000\",\n    \"caption\": \"Nama\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "8faed6ed-cabf-4ed2-a6bd-164ee72e1483",
      "name": "Get row(s) in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1136,
        -64
      ],
      "parameters": {
        "options": {
          "dataLocationOnSheet": {
            "values": {
              "rangeDefinition": "detectAutomatically"
            }
          }
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kbzli64xlywauDLgVVfc2FC4CHqnjzc3f9EU0kkvfIQ/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1kbzli64xlywauDLgVVfc2FC4CHqnjzc3f9EU0kkvfIQ",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kbzli64xlywauDLgVVfc2FC4CHqnjzc3f9EU0kkvfIQ/edit?usp=drivesdk",
          "cachedResultName": "Tagihan Air"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "da0f78a6-3146-4e15-911f-61f3f6a073e2",
      "name": "Append row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -256,
        -64
      ],
      "parameters": {
        "columns": {
          "value": {
            "Nama": "={{ $json.Nama }}",
            "Beban": "={{ $json.Beban }}",
            "Harga/m³": "={{ $json['Harga/m³'] }}",
            "Total Bayar": "={{ $json['Total Bayar'] }}",
            "Jumlah Bayar": "={{ $json['Jumlah Bayar'] }}",
            "Tanggal Input": "={{ $json.tanggalF }}",
            "Volume Saat Ini": "={{ $json['Volume Saat ini'] }}",
            "Volume Sebelumnya": "={{ $json['Volume Sebelumnya'] }}"
          },
          "schema": [
            {
              "id": "Nama",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Nama",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Volume Sebelumnya",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Volume Sebelumnya",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Volume Saat Ini",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Volume Saat Ini",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Harga/m³",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Harga/m³",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Jumlah Bayar",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Jumlah Bayar",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Beban",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Beban",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total Bayar",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Total Bayar",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tanggal Input",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Tanggal Input",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "useAppend": true
        },
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kbzli64xlywauDLgVVfc2FC4CHqnjzc3f9EU0kkvfIQ/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1kbzli64xlywauDLgVVfc2FC4CHqnjzc3f9EU0kkvfIQ",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kbzli64xlywauDLgVVfc2FC4CHqnjzc3f9EU0kkvfIQ/edit?usp=drivesdk",
          "cachedResultName": "Tagihan Air"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "c58a7b4d-b780-4167-be6e-5f91cee2eb72",
      "name": "Nota adhesiva",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2016,
        32
      ],
      "parameters": {
        "width": 400,
        "height": 624,
        "content": "## 1. Create Google Sheet\nRows :\n- Nama\t\n- Volume Sebelumnya\t\n- Volume Saat Ini\t\n- Harga/m³\t\n- Jumlah Bayar\t\n- Beban\t\n- Total Bayar\t\n- Tanggal Input\n\n## 2. Create Telegram Bot\n- Open Telegram and search for @BotFather.\n- Use the command /newbot and follow the instructions (choose a name and username).\n- BotFather will give you a token.\n- Copy the token and paste it into your n8n (or automation platform) credentials.\n\n## 3. Create Your Gemini API Integration\n- Go to Google AI Studio.\n- Generate an API key for Gemini.\n- Paste the Gemini API key into your credentials."
      },
      "typeVersion": 1
    },
    {
      "id": "efe8f266-d509-4372-a98d-082af2f5d2c1",
      "name": "Nota adhesiva1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1136,
        336
      ],
      "parameters": {
        "color": 4,
        "width": 544,
        "height": 272,
        "content": "## Short Explanation of the Water Bill BOT\nEach resident sends a picture of the water meter along with a caption that includes their name to the chatbot.\nThe BOT automatically calculates the difference in volume between the previous and current payment.\nExample calculation:\nPrevious Volume: 535\nCurrent Volume: 545\nDifference: 10 m³\nIf the price per 1 m³ is Rp3,000, then 10 × 3,000 = Rp30,000\nAdditional mandatory fee (fixed charge): Rp3,000\nTotal = Rp33,000\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ad11f386-8b9c-4e06-921b-bb8cd54fb5f4",
      "name": "Find Latest Row",
      "type": "n8n-nodes-base.code",
      "position": [
        -928,
        -64
      ],
      "parameters": {
        "jsCode": "const data = items.map(item => item.json);\n\nconst maxRowItem = data.reduce((max, current) => {\n  return current.row_number > max.row_number ? current : max;\n}, data[0]);\n\nreturn [\n  {\n    json: maxRowItem\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "ac746257-cbf5-40be-85de-7262071f643b",
      "name": "Format Bill Message",
      "type": "n8n-nodes-base.code",
      "position": [
        -64,
        -64
      ],
      "parameters": {
        "jsCode": "const current = $json;\nconst previous = $('Calculate Bill').item.json;\nconst previousInfo = $('Find Latest Row').item.json;\nconst user = $('Prepare Data for Sheet').item.json.user;\nconst nama = $('Prepare Data for Sheet').item.json.Nama;\n\nfunction formatRupiah(angka) {\n  return angka.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, '.');\n}\n\nfunction removeLeadingZeros(str) {\n  return str.toString().replace(/^0+/, '');\n}\n\nconst volPrevlong = Number(previous['Volume Sebelumnya']);\nconst volPrev = Number(current['Volume Sebelumnya']);\nconst volumeSelisihlalu = Math.abs(volPrevlong - volPrev);\nconst volNowRaw = current['Volume Saat Ini'];\nconst volNow = Number(volNowRaw);\nconst volumeSelisih = Math.abs(volNow - volPrev);\n\nconst volNowDisplay = removeLeadingZeros(volNowRaw);\n\nconst totalBayarNow = formatRupiah(current['Total Bayar']);\nconst totalBayarPrev = formatRupiah(previousInfo['Total Bayar']);\n\nreturn [\n  {\n    json: {\n      user,\n      nama,\n      tanggal_sebelumnya: previousInfo['Tanggal Input'],\n      tanggal_sekarang: current['Tanggal Input'],\n      vol_sebelumnyalagi: volPrevlong,\n      vol_sebelumnya: volPrev,\n      vol_saat_ini: volNowDisplay,\n      volume_selisihlalu: volumeSelisihlalu,\n      volume_selisih: volumeSelisih,\n      total_bayar_sekarang: `Rp${totalBayarNow}`,\n      total_bayar_sebelumnya: `Rp${totalBayarPrev}`\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "f68c7969-bdf0-4d70-a7e3-96894db6c2d8",
      "name": "Send Bill to Telegram",
      "type": "n8n-nodes-base.telegram",
      "position": [
        144,
        -64
      ],
      "webhookId": "d1f3b592-bfaa-4095-b613-46e52ecc754a",
      "parameters": {
        "text": "=Hallo Kak {{ $('Prepare Data for Sheet').item.json.user }}, \nberikut tagihan untuk Bapak/Ibu {{ $('Prepare Data for Sheet').item.json.Nama }}\n-----------------------------\n\n<b>Tagihan Sebelumnya</b>\n\n<b>{{ $json.tanggal_sebelumnya }}</b>\nVolume : {{ $('Calculate Bill').item.json['Volume Sebelumnya'] }} ➤ {{ $('Calculate Bill').item.json['Volume Saat Ini'] }} = {{ $json.volume_selisihlalu }}m³\nTotal Bayar : {{ $json.total_bayar_sebelumnya }}\nStatus : Lunas\n\n-----------------------------\n\n<b>Tagihan Saat Ini</b>\n\n<b>{{ $json.tanggal_sekarang }}</b>\nVolume : {{ $json.vol_sebelumnya }} ➤ {{ $json.vol_saat_ini }} = {{ $json.volume_selisih }}m³\nTotal Bayar : {{ $json.total_bayar_sekarang }}\nStatus : Pending\n\n<b>Silakan lakukan pembayaran melalui QRIS <a href=\"https://miftahrahmat.com\">disini</a> ( Bendahara RT )</b>\n",
        "chatId": "={{ $('Prepare Data for Sheet').item.json.chat_id }}",
        "additionalFields": {
          "parse_mode": "HTML",
          "appendAttribution": false,
          "reply_to_message_id": "={{ $('Prepare Data for Sheet').item.json.mess_id }}"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "e29bafb4-47de-4220-bf11-bb2c882be340",
      "name": "Prepare Data for Sheet",
      "type": "n8n-nodes-base.set",
      "position": [
        -512,
        -64
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d66900d4-cb6a-4bca-bca2-99c94f70d7e7",
              "name": "Volume Sebelumnya",
              "type": "number",
              "value": "={{ $json['Volume Saat Ini'] }}"
            },
            {
              "id": "4a2b3dda-e6ac-43b1-a8d4-3e8e6e49f443",
              "name": "Volume Saat ini",
              "type": "string",
              "value": "={{ $json.VolumeSaatini }}"
            },
            {
              "id": "888a80f9-effe-479b-9fcf-dea623bd5cb1",
              "name": "Nama",
              "type": "string",
              "value": "={{ $json.caption }}"
            },
            {
              "id": "73834b6e-1daf-494d-adc2-074178c77e0d",
              "name": "tanggalF",
              "type": "string",
              "value": "={{ $json.tanggalF }}"
            },
            {
              "id": "32823266-a5d3-42a2-9279-fbf989c2f763",
              "name": "Tanggal bayar sebelumnya",
              "type": "string",
              "value": "={{ $json['Tanggal Input'] }}"
            },
            {
              "id": "432c4403-74f5-46d4-9527-46d0b4fee725",
              "name": "Volume",
              "type": "number",
              "value": "={{ $json.Volume }}"
            },
            {
              "id": "40551b2e-d541-4cac-a7b9-0a7175f04467",
              "name": "Jumlah Bayar",
              "type": "number",
              "value": "={{ $json['Jumlah Bayar'] }}"
            },
            {
              "id": "20b5be6f-0e70-49db-95fb-db04f5bf6b69",
              "name": "Beban",
              "type": "number",
              "value": "={{ $json.Beban }}"
            },
            {
              "id": "a62d41b0-6f00-4ac3-b3a0-b5d558d8cee1",
              "name": "Total Bayar",
              "type": "number",
              "value": "={{ $json['Total Bayar'] }}"
            },
            {
              "id": "04aaabba-14fd-4232-97cc-c406bf127a53",
              "name": "Harga/m³",
              "type": "number",
              "value": "={{ $json['Harga/m³'] }}"
            },
            {
              "id": "f6738814-fd06-4e20-a727-6de499dac851",
              "name": "user",
              "type": "string",
              "value": "={{ $json.user }}"
            },
            {
              "id": "b3643859-3815-4a7b-82e0-87a7504ec190",
              "name": "chat_id",
              "type": "number",
              "value": "={{ $json.chat_id }}"
            },
            {
              "id": "bcd99fe0-0322-4a25-9453-017bc620a4ef",
              "name": "mess_id",
              "type": "number",
              "value": "={{ $json.mess_id }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e24e6599-1475-478b-a83e-a026e6a8aca6",
      "name": "Calculate Bill",
      "type": "n8n-nodes-base.code",
      "position": [
        -720,
        -64
      ],
      "parameters": {
        "jsCode": "const item = $json;\n\nconst volumeSebelumnya = Number(item[\"Volume Saat Ini\"] || 0);\nconst volumeSekarang = String($('Image Explainer').first().json.output.m3).padStart(5, \"0\");\nconst hargaPerM3 = Number(item[\"Harga/m³\"] || 0);\nconst beban = Number(item[\"Beban\"] || 0);\nconst nama = item[\"Nama\"] || \"\";\n\nconst volume = volumeSekarang - volumeSebelumnya;\nconst jumlahBayar = volume * hargaPerM3;\nconst totalBayar = jumlahBayar + beban;\n\nconst inputDate = $now;\n\nconst dateObj = new Date(inputDate);\n\nconst hari = ['Minggu', 'Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu'];\nconst bulan = ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'];\n\nconst namaHari = hari[dateObj.getDay()];\nconst tanggal = dateObj.getDate();\nconst namaBulan = bulan[dateObj.getMonth()];\nconst tahun = dateObj.getFullYear();\n\nconst formatted = `${namaHari}, ${tanggal} ${namaBulan} ${tahun}`;\n\nreturn [{\n  json: {\n    ...item,\n    VolumeSaatini: volumeSekarang,\n    Volume: volume,\n    \"Jumlah Bayar\": jumlahBayar,\n    \"Total Bayar\": totalBayar,\n    caption: nama,\n    tanggalF: formatted,\n    mess_id: $('Telegram Trigger').first().json.message.message_id,\n    chat_id: $('Telegram Trigger').first().json.message.chat.id,\n    user: $('Telegram Trigger').first().json.message.from.first_name\n  }\n}];"
      },
      "typeVersion": 2
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "8fb90ae0-c3bb-4b63-976b-4faef238f2ba",
  "connections": {
    "22e0a88e-aa48-46f2-896a-99473313fe34": {
      "main": [
        [
          {
            "node": "40406678-0fce-4f9a-9335-69e3600c84e8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e24e6599-1475-478b-a83e-a026e6a8aca6": {
      "main": [
        [
          {
            "node": "e29bafb4-47de-4220-bf11-bb2c882be340",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ad11f386-8b9c-4e06-921b-bb8cd54fb5f4": {
      "main": [
        [
          {
            "node": "e24e6599-1475-478b-a83e-a026e6a8aca6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "40406678-0fce-4f9a-9335-69e3600c84e8": {
      "main": [
        [
          {
            "node": "8faed6ed-cabf-4ed2-a6bd-164ee72e1483",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "9da0ef32-0aae-47d4-ad66-ddeb8ff60e07",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "da0f78a6-3146-4e15-911f-61f3f6a073e2": {
      "main": [
        [
          {
            "node": "ac746257-cbf5-40be-85de-7262071f643b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ac746257-cbf5-40be-85de-7262071f643b": {
      "main": [
        [
          {
            "node": "f68c7969-bdf0-4d70-a7e3-96894db6c2d8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8faed6ed-cabf-4ed2-a6bd-164ee72e1483": {
      "main": [
        [
          {
            "node": "ad11f386-8b9c-4e06-921b-bb8cd54fb5f4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e29bafb4-47de-4220-bf11-bb2c882be340": {
      "main": [
        [
          {
            "node": "da0f78a6-3146-4e15-911f-61f3f6a073e2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9da0ef32-0aae-47d4-ad66-ddeb8ff60e07": {
      "main": [
        [
          {
            "node": "22e0a88e-aa48-46f2-896a-99473313fe34",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "40406678-0fce-4f9a-9335-69e3600c84e8",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "edfc1d10-e1b8-460c-b850-7eb4d1b5f30f": {
      "ai_outputParser": [
        [
          {
            "node": "40406678-0fce-4f9a-9335-69e3600c84e8",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    }
  }
}
Preguntas frecuentes

¿Cómo usar este flujo de trabajo?

Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.

¿En qué escenarios es adecuado este flujo de trabajo?

Intermedio - Varios, IA Multimodal

¿Es de pago?

Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.

Información del flujo de trabajo
Nivel de dificultad
Intermedio
Número de nodos15
Categoría2
Tipos de nodos10
Descripción de la dificultad

Adecuado para usuarios con experiencia intermedia, flujos de trabajo de complejidad media con 6-15 nodos

Autor
Miftah Rahmat

Miftah Rahmat

@miftahr

I’m an automation enthusiast specializing in n8n workflow design and integration.

Enlaces externos
Ver en n8n.io

Compartir este flujo de trabajo

Categorías

Categorías: 34