水费账单
中级
这是一个Miscellaneous, Multimodal AI领域的自动化工作流,包含 15 个节点。主要使用 Set, Code, Switch, Telegram, GoogleSheets 等节点。 使用 Telegram、Gemini AI 和 Google Sheets 自动化水费计算
前置要求
- •Telegram Bot Token
- •Google Sheets API 凭证
- •Google Gemini API Key
使用的节点 (15)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"id": "3dPhcViLijZ5zBah",
"meta": {
"instanceId": "f357e038067887a62c03e581da0f98dfa8010dcc02f1fa97f81df592773a1c40",
"templateCredsSetupCompleted": true
},
"name": "水费账单",
"tags": [],
"nodes": [
{
"id": "0251a048-cd44-464c-8094-89a9baff4695",
"name": "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": "重定向消息类型",
"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": "获取文件",
"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": "图片解释器",
"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": "Google Gemini 聊天模型",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
-1536,
192
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "edfc1d10-e1b8-460c-b850-7eb4d1b5f30f",
"name": "多表:您可以连接多个表以实现有组织的数据结构",
"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": "获取表中的行",
"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": "在表格中追加行",
"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": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2016,
32
],
"parameters": {
"width": 400,
"height": 624,
"content": "## 1. 创建 Google 表格"
},
"typeVersion": 1
},
{
"id": "efe8f266-d509-4372-a98d-082af2f5d2c1",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1136,
336
],
"parameters": {
"color": 4,
"width": 544,
"height": 272,
"content": "## 水费账单机器人简要说明"
},
"typeVersion": 1
},
{
"id": "ad11f386-8b9c-4e06-921b-bb8cd54fb5f4",
"name": "查找最新行",
"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": "格式化账单消息",
"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": "发送账单到 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": "准备表格数据",
"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": "计算账单",
"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": {
"Get a file": {
"main": [
[
{
"node": "Image Explainer",
"type": "main",
"index": 0
}
]
]
},
"Calculate Bill": {
"main": [
[
{
"node": "Prepare Data for Sheet",
"type": "main",
"index": 0
}
]
]
},
"Find Latest Row": {
"main": [
[
{
"node": "Calculate Bill",
"type": "main",
"index": 0
}
]
]
},
"Image Explainer": {
"main": [
[
{
"node": "Get row(s) in sheet",
"type": "main",
"index": 0
}
]
]
},
"Telegram Trigger": {
"main": [
[
{
"node": "Redirect Message Types",
"type": "main",
"index": 0
}
]
]
},
"Append row in sheet": {
"main": [
[
{
"node": "Format Bill Message",
"type": "main",
"index": 0
}
]
]
},
"Format Bill Message": {
"main": [
[
{
"node": "Send Bill to Telegram",
"type": "main",
"index": 0
}
]
]
},
"Get row(s) in sheet": {
"main": [
[
{
"node": "Find Latest Row",
"type": "main",
"index": 0
}
]
]
},
"Prepare Data for Sheet": {
"main": [
[
{
"node": "Append row in sheet",
"type": "main",
"index": 0
}
]
]
},
"Redirect Message Types": {
"main": [
[
{
"node": "Get a file",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Image Explainer",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "Image Explainer",
"type": "ai_outputParser",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
中级 - 杂项, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
LinkedIn 自动化
使用Gemini AI和审批流程将Telegram消息转换为专业LinkedIn帖子
If
Set
Code
+13
54 节点Sateesh
内容创作
Telegram论坛脉搏:使用Gemini和Groq AI模型的社区监控
Telegram论坛脉搏:使用Gemini和Groq AI模型的社区监控
If
Set
Code
+13
59 节点Nguyen Thieu Toan
杂项
使用 Gemini、Tavily 和人工审核生成 SEO 优化 WordPress 博客
使用 Gemini、Tavily 和人工审核生成 SEO 优化 WordPress 博客
If
Set
Code
+12
38 节点Aryan Shinde
内容创作
LinkedIn和X病毒内容自动引擎
使用AI生成和发布自动创建LinkedIn和X的病毒内容
If
Set
Wait
+26
156 节点Diptamoy Barman
内容创作
智能Telegram助手
使用Gemini AI、PostgreSQL记忆和动态路由构建智能Telegram助手
Set
Code
Switch
+12
36 节点John Alejandro SIlva
AI 聊天机器人
通过 Telegram 使用 Pollinations 生成图像和 Gemini 2.5 生成博客文章
通过 Telegram 使用 Pollinations 生成图像和 Gemini 2.5 生成博客文章
If
Set
Code
+9
34 节点Fahmi Oktafian
内容创作
工作流信息
难度等级
中级
节点数量15
分类2
节点类型10
作者
Miftah Rahmat
@miftahrI’m an automation enthusiast specializing in n8n workflow design and integration.
外部链接
在 n8n.io 查看 →
分享此工作流