[
  {
    "path": "Kode.gs",
    "content": "//CONFIG\nvar BOT_TOKEN = \"6642440655:AADRAWN3nXcuJf5xJkSQLhyJgQXGag08cLc\" //BOT TOKEN ANDA\nvar SS_URL = \"https://docs.google.com/spreadsheets/d/1LArhvsBXZ8lJ3tzvx8DyYrFWwtRxlQsWQEFzdsyignw/edit#gid=0\" //URL SPREADSHEET\nvar CREDIT_SHEET_NAME = \"Pemasukan\" //NAMA SHEET PEMASUKAN\nvar DEBIT_SHEET_NAME = \"Pengeluaran\" //NAMA SHEET PENGELUARAN\n\n\n//BEGIN\nconst ss = SpreadsheetApp.openByUrl(SS_URL);\nconst creditSheet = ss.getSheetByName(CREDIT_SHEET_NAME);\nconst debitSheet = ss.getSheetByName(DEBIT_SHEET_NAME);\nconst Credit = new Collection.Collect(creditSheet)\nconst Debit = new Collection.Collect(debitSheet)\n\nfunction doGet(e) {\n  return HtmlService.createHtmlOutput('<h1>OK</h1>')\n}\n\nfunction doPost(e) {\n  const queryParameters = e.parameter;\n  const usersQuery = queryParameters.users\n  const validUsers = usersQuery.split(',')\n  try {\n    if (e.postData.type == \"application/json\") {\n      let update = JSON.parse(e.postData.contents);\n      if (update) {\n        commands(update, validUsers)\n        return true\n      }\n    }\n  } catch (e) {\n    Logger.log(e)\n  }\n}\n\nfunction commands(update, validUsers) {\n\n  const chatId = update.message.chat.id;\n  const first_name = update.message.chat.first_name;\n  const text = update.message.text || '';\n  const tanggal = new Date().toLocaleString();\n  const _date = new Date().toJSON()\n\n  if (validUsers.includes(String(chatId))) {\n\n    if (text.startsWith(\"/start\")) {\n      sendMessage({\n        chat_id: chatId,\n        text: \"Mulai laporan keuangan.\\nPemasukan:\\n/masuk [nominal] [#kategori] [item1, item2 dst]\\nPengeluaran:\\n/keluar [nominal] [#kategori] [item1, item2 dst]\\n\\nRekapitulasi: /rekap [tanggal/bulan] [tanggal/bulan (opsional)]\\nTanggal dan bulan berformat YYYY-MM-DD dan YYYY-MM\\nContoh: \\n/rekap 2024-01-01\\n/rekap 2024-01-01 2024-01-10\\n/rekap 2024-01\\n/rekap 2024-01 2024-06\"\n      })\n    } else if (text.startsWith(\"/masuk\")) {\n      const stext = text.split(' ')\n\n      const nominal = Number(stext[1]);\n      const kategori = stext[2].startsWith('#') ? stext[2].replace('#', '') : '';\n\n      stext.splice(0, 3);\n      const item = stext.join(' ')\n\n      if (nominal && kategori && item) {\n\n        Credit.insert(\n          {\n            _date,\n            Tanggal: tanggal,\n            Kategori: kategori,\n            Nominal: nominal,\n            Item: item,\n            ReporterID: chatId,\n            ReporterName: first_name\n          }\n        )\n\n        sendMessage({\n          chat_id: chatId,\n          text: 'Laporan pemasukan sukses.'\n        })\n\n      } else {\n        sendMessage({\n          chat_id: chatId,\n          text: 'Gagal. Pastikan sesuai format. \\n/masuk [harga] [#kategori] [item1, item2 dst]'\n        })\n      }\n    } else if (text.startsWith(\"/keluar\")) {\n      const stext = text.split(' ')\n\n      const nominal = Number(stext[1]);\n      const kategori = stext[2].startsWith('#') ? stext[2].replace('#', '') : '';\n\n      stext.splice(0, 3);\n      const item = stext.join(' ')\n\n      if (nominal && kategori && item) {\n\n        Debit.insert(\n          {\n            _date,\n            Tanggal: tanggal,\n            Kategori: kategori,\n            Nominal: nominal,\n            Item: item,\n            ReporterID: chatId,\n            ReporterName: first_name\n          }\n        )\n\n        sendMessage({\n          chat_id: chatId,\n          text: 'Laporan pengeluaran sukses.'\n        })\n\n      } else {\n        sendMessage({\n          chat_id: chatId,\n          text: 'Gagal. Pastikan sesuai format. \\n/keluar [harga] [#kategori] [item1, item2 dst]'\n        })\n      }\n    } else if (text.startsWith(\"/rekap\")) {\n      const stext = text.split(' ')\n      stext.splice(0, 1);\n\n      const oDateRange = Collection.generateDateRange(stext.join(' '))\n      const dataRange = oDateRange.dateRange\n      const sumType = oDateRange.sumType\n      const monthNames = ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember']\n\n      if (dataRange.length > 0) {\n        let textToSend = \"Rekapitulasi: \\n\"\n\n        for (let _date of dataRange) {\n          const pengeluaran = Debit.find(\n            {\n              _date: d => new Date(d) >= _date.from && new Date(d) < _date.to\n            }\n          )\n\n          const pemasukan = Credit.find(\n            {\n              _date: d => new Date(d) >= _date.from && new Date(d) < _date.to\n            }\n          )\n\n          let rekapMasuk = pemasukan.reduce((acc, item) => {\n            if (!acc[item.Kategori]) {\n              acc[item.Kategori] = 0;\n            }\n            acc[item.Kategori] += item.Nominal;\n            return acc;\n          }, {});\n\n          let rekapKeluar = pengeluaran.reduce((acc, item) => {\n            if (!acc[item.Kategori]) {\n              acc[item.Kategori] = 0;\n            }\n            acc[item.Kategori] += item.Nominal;\n            return acc;\n          }, {});\n\n          if (sumType == 'daily') {\n            let dateTo = new Date(_date.to)\n            dateTo.setDate(dateTo.getDate() - 1)\n            textToSend += \"Pemasukan \" + _date.from.toLocaleDateString() + ' s.d ' + dateTo.toLocaleDateString() + \"\\n\"\n            textToSend += Object.keys(rekapMasuk).map((i) => `${i}: ${Number(rekapMasuk[i]).toLocaleString('id-ID')}`).join('\\n') || '---'\n            textToSend += '\\nTotal: ' + Object.values(rekapMasuk).reduce((acc, value) => acc + value, 0).toLocaleString('id-ID');\n            textToSend += \"\\n\"\n            textToSend += \"\\n\"\n            textToSend += \"Pengeluaran \" + _date.from.toLocaleDateString() + ' s.d ' + dateTo.toLocaleDateString() + \"\\n\"\n            textToSend += Object.keys(rekapKeluar).map((i) => `${i}: ${Number(rekapKeluar[i]).toLocaleString('id-ID')}`).join('\\n') || '---'\n            textToSend += '\\nTotal: ' + Object.values(rekapKeluar).reduce((acc, value) => acc + value, 0).toLocaleString('id-ID');\n            textToSend += \"\\n\"\n            textToSend += \"\\n\"\n\n          }\n          else {\n            textToSend += \"Pemasukan bulan \" + monthNames[_date.from.getMonth()] + ' ' + _date.from.getFullYear() + \"\\n\"\n\n            textToSend += Object.keys(rekapMasuk).map((i) => `${i}: ${Number(rekapMasuk[i]).toLocaleString('id-ID')}`).join('\\n') || '---'\n            textToSend += '\\nTotal: ' + Object.values(rekapMasuk).reduce((acc, value) => acc + value, 0).toLocaleString('id-ID');\n            textToSend += \"\\n\"\n\n            textToSend += \"\\n\"\n\n            textToSend += \"Pengeluaran bulan \" + monthNames[_date.from.getMonth()] + ' ' + _date.from.getFullYear() + \"\\n\"\n\n            textToSend += Object.keys(rekapKeluar).map((i) => `${i}: ${Number(rekapKeluar[i]).toLocaleString('id-ID')}`).join('\\n') || '---'\n            textToSend += '\\nTotal: ' + Object.values(rekapKeluar).reduce((acc, value) => acc + value, 0).toLocaleString('id-ID');\n            textToSend += \"\\n\"\n\n            textToSend += \"\\n\"\n          }\n        }\n\n        sendMessage({\n          chat_id: chatId,\n          text: textToSend\n        })\n\n      } else {\n        sendMessage({\n          chat_id: chatId,\n          text: 'Gagal. Pastikan sesuai format. \\n/rekap [tanggal/bulan] [tanggal/bulan (opsional)]\\nTanggal dan bulan berformat YYYY-MM-DD dan YYYY-MM\\nContoh: \\n/rekap 2024-01-01\\n/rekap 2024-01-01 2024-01-10\\n/rekap 2024-01\\n/rekap 2024-01 2024-06'\n        })\n      }\n    }\n  }\n}\n\nfunction sendMessage(postdata) {\n  var options = {\n    'method': 'post',\n    'contentType': 'application/json',\n    'payload': JSON.stringify(postdata),\n    'muteHttpExceptions': true\n  };\n  UrlFetchApp.fetch('https://api.telegram.org/bot' + BOT_TOKEN + '/sendMessage', options);\n}\n"
  },
  {
    "path": "README.md",
    "content": "# laporan-keuangan-bot\n[![Version](https://img.shields.io/badge/Version-2.0.1-green)]()\n[![Beta](https://img.shields.io/badge/Beta-orange)]()<br>\nLaporan keuangan, pencataan pemasukan dan pengeluaran dengan Bot Telegram yang terintegrasi dengan Google Spreadsheet\n\n### Video Tutorial\nhttps://youtu.be/sII577Ubv-E\n\n<br>\n<img src=\"https://github.com/tegohsx/laporan-keuangan-bot/assets/101353193/d8aaafe8-62f6-45a0-bf8c-7934f61c7d3b\" width=\"50%\">\n\n\n### Yang ada di bot\n1. Input pemasukan: <code>/masuk [nominal] [#kategori] [item1, item2, keterangan dsb.]</code> <br>\n   Contoh:  <br>\n      /masuk 100000 #gaji angkut barang <br>\n2. Input pengeluaran: <code>/keluar [nominal] [#kategori] [item1, item2, keterangan dsb.]</code> <br>\n   Contoh:  <br>\n      /keluar 50000 #makan roti dan kopi <br>\n3. Rekapitulasi: <code>/rekap [tanggal/bulan] [tanggal/bulan (opsional)]</code> <br>\n   Tanggal dan bulan berformat YYYY-MM-DD dan YYYY-MM <br>\n   Contoh: <br>\n      /rekap 2024-02-01<br>\n      /rekap 2024-02-01 2024-02-10<br>\n      /rekap 2024-02<br>\n      /rekap 2024-02 2024-06<br>\n\n\n# Mulai\n\n## Buat Bot telegram\n1. Buka telegram search @BotFather\n2. Create New Bot /newbot\n3. Masukkan nama kemudian username.\n4. Setelah berhasil maka akan mendapatkan Bot Token.\n\n## Buat Spreadsheet\nBuat dua sheet untuk pemasukan dan pengeluaran dengan kolom:\n1. _id\n2. _date\n3. Tanggal\n4. Kategori\n5. Item\n6. Nominal\n7. ReporterID\n8. ReporterName\n\n## Buat Apps Script\n1. Copy Kode.gs\n2. Sesuaikan Token, Spreadsheet URL, dan Nama Sheet untuk pemasukan dan pengeluaran\n3. Tambahkan Library dengan ID: <code>1CZD-ai-ImkabBPSBVOqnFFWlXoA5kUEfoXvUXOC3uQHr_qpF1H7amHMr</code>\n4. Deploy sebagai Web app, dan simpan URL-nya\n\n## Set webhook Bot Telegram\n1. Buka di browser <code>https[]()://api.telegram.org/bot[token]/setwebhook?url=[url hasil deploy]?users=ChatID1,ChatID2,...</code><br>\nSesuaikan ChatID* dengan user yang akan menggunakan bot, bisa lebih dari satu, pisahkan dengan koma.\n\n## *Note:\nUntuk mendapatkan Chat ID, buka telegram, search <code>@getYourID_bot</code> atau https://t.me/getyourid_bot\n\n\n## Contact\nTelegram: https://t.me/mastgh <br>\nWhatsApp: +62 855-1000-113\n\n## Donasi\nPaypal tegohsx@gmail.com <br>\nBRI 000401061441500 <br>\nJago 100310049829 <br>\nDANA/GOPAY 085290465350 <br>\na/n Teguh S\n"
  }
]