Lewati ke konten
Skematik
Semua template
Bot / Automasi (WA, Telegram, Trading)

TagihBot — Bot WA Pengingat Tagihan & Konfirmasi Bayar

Bot WhatsApp otomatis untuk UMKM yang mengirim pengingat tagihan sopan, menerima bukti pembayaran dari pelanggan, dan memungkinkan pemilik mengonfirmasi pembayaran serta mengontrol bot via perintah chat.

Pakai template

Bot Penagihan WhatsApp UMKM

Bot WhatsApp otomatis untuk UMKM yang mengirim pengingat tagihan sopan, menerima bukti pembayaran dari pelanggan, dan memungkinkan pemilik mengonfirmasi pembayaran serta mengontrol bot via perintah chat.

Problem

Pemilik UMKM sering kesulitan menagih pelanggan secara manual, menghabiskan waktu, dan berisiko lupa atau mengirim pengingat berulang. Proses konfirmasi pembayaran juga sering tidak efisien, membutuhkan pengecekan manual dan komunikasi bolak-balik.

Goals

  • Mengurangi waktu penagihan manual hingga 90% untuk pemilik UMKM.
  • Memastikan 100% tagihan jatuh tempo dikirimkan pengingatnya secara otomatis.
  • Memproses konfirmasi pembayaran dalam waktu kurang dari 5 menit setelah bukti diterima owner.
  • Mencegah pengiriman pengingat ganda untuk tagihan yang sama.

Non-Goals

  • Integrasi dengan sistem akuntansi atau POS pihak ketiga.
  • Fitur multi-bahasa untuk pengingat tagihan.
  • Dashboard atau antarmuka web untuk pemilik UMKM.
  • Manajemen pelanggan atau tagihan melalui antarmuka web.
  • Fitur pembayaran langsung melalui bot (misalnya, integrasi payment gateway).
  • Dukungan untuk platform chat selain WhatsApp.

Target Users

  • Pemilik UMKMOtomatisasi penagihan, konfirmasi pembayaran yang efisien, dan kontrol bot yang mudah.
  • Pelanggan UMKMMenerima pengingat yang jelas, mudah mengirim bukti pembayaran, dan tidak ditagih berulang.

User Stories

  • must-have
    Sebagai Pemilik UMKM, saya ingin Bot mengirim pengingat tagihan otomatis ke pelanggan saya setiap pagi, agar Saya tidak perlu menagih secara manual dan tagihan tidak terlewat..
  • must-have
    Sebagai Pelanggan UMKM, saya ingin Saya bisa membalas pengingat dengan foto bukti transfer, agar Pembayaran saya segera tercatat dan saya tidak ditagih lagi..
  • must-have
    Sebagai Pemilik UMKM, saya ingin Saya bisa mengonfirmasi pembayaran pelanggan melalui perintah chat, agar Status tagihan diperbarui dengan cepat dan bot berhenti menagih pelanggan tersebut..
  • must-have
    Sebagai Pemilik UMKM, saya ingin Saya bisa mematikan atau menyalakan bot penagihan sementara, agar Saya memiliki kontrol penuh atas operasional bot sesuai kebutuhan bisnis saya..

User Flow

  1. Pemilik UMKM menyiapkan bot dengan mengonfigurasi environment variables dan menjalankan aplikasi.
  2. Pemilik UMKM menambahkan data pelanggan dan tagihan secara manual ke database (untuk MVP).
  3. Setiap pagi pukul 09:00 WIB, bot secara otomatis mengambil daftar tagihan jatuh tempo.
  4. Bot mengirim pengingat tagihan ke setiap pelanggan yang memiliki tagihan jatuh tempo, dengan jeda aman antar pesan.
  5. Pelanggan menerima pengingat dan membalas dengan foto bukti transfer.
  6. Bot menerima foto, mengunggahnya ke Cloudinary, dan meneruskan URL serta detail ke nomor WhatsApp pemilik UMKM.
  7. Bot membalas pelanggan dengan konfirmasi penerimaan bukti pembayaran.
  8. Pemilik UMKM melihat bukti pembayaran dan mengirim perintah `/lunas <invoice_id>` ke bot.
  9. Bot memperbarui status invoice menjadi 'PAID' di database dan membalas pemilik UMKM dengan konfirmasi.
  10. Setiap hari pukul 18:00 WIB, bot mengirim laporan ringkas aktivitas harian ke pemilik UMKM.
  11. Pemilik UMKM dapat mengirim perintah `/tagihan` untuk melihat daftar tagihan pending.
  12. Pemilik UMKM dapat mengirim perintah `/stop` untuk menghentikan pengingat otomatis, dan `/start` untuk melanjutkannya.
Memuat diagram…

Features

Pengingat Tagihan Otomatis

must-have

Bot akan membaca daftar tagihan jatuh tempo dari database setiap pagi dan mengirim pengingat ke pelanggan satu per satu dengan jeda aman untuk menghindari banned WhatsApp.

  • Bot mengirim pengingat tagihan untuk semua invoice dengan status 'PENDING' dan due_date <= hari ini, setiap hari pukul 09:00 WIB.
  • Setiap pengingat dikirim dengan jeda minimal 5 detik antar pesan ke nomor berbeda.
  • Pengingat berisi nomor invoice, jumlah, tanggal jatuh tempo, dan instruksi untuk membalas dengan bukti bayar.
  • Bot tidak mengirim pengingat ke pelanggan yang nomor WhatsApp-nya tidak valid atau tidak terdaftar.
  • Bot tidak mengirim pengingat untuk invoice yang sudah berstatus 'PAID' atau 'CANCELLED'.

Kasus tepi yang ditangani

  • Tidak ada tagihan jatuh tempo pada hari itu.
  • Nomor WhatsApp pelanggan tidak valid atau tidak terdaftar.
  • WhatsApp API mengalami kegagalan saat mengirim pesan.

Penerimaan Bukti Pembayaran

must-have

Pelanggan dapat membalas pesan bot dengan foto bukti transfer. Bot akan menerima foto tersebut, menyimpannya, dan meneruskannya ke pemilik UMKM untuk konfirmasi.

  • Bot dapat menerima pesan masuk berupa gambar dari pelanggan.
  • Gambar bukti pembayaran disimpan ke penyimpanan cloud dan URL-nya dicatat di database.
  • Bot meneruskan gambar bukti pembayaran beserta nomor invoice terkait ke nomor WhatsApp pemilik UMKM.
  • Bot membalas pelanggan dengan pesan konfirmasi bahwa bukti pembayaran telah diterima dan akan segera diproses.
  • Bot mencatat ID pesan WhatsApp yang masuk untuk mencegah pemrosesan ganda.

Kasus tepi yang ditangani

  • Pelanggan mengirim pesan teks biasa, bukan gambar.
  • Pelanggan mengirim beberapa gambar dalam satu pesan.
  • Penyimpanan cloud gagal menyimpan gambar.

Konfirmasi Pembayaran via Chat Owner

must-have

Pemilik UMKM dapat menggunakan perintah chat `/lunas <invoice_id>` untuk mengonfirmasi pembayaran. Bot akan memperbarui status tagihan dan berhenti menagih pelanggan tersebut.

  • Pemilik UMKM dapat mengirim perintah `/lunas <invoice_id>` ke bot.
  • Jika `invoice_id` valid dan statusnya 'PENDING', bot mengubah status invoice menjadi 'PAID' dan mencatat tanggal pembayaran.
  • Bot membalas pemilik UMKM dengan konfirmasi bahwa invoice telah lunas.
  • Jika `invoice_id` tidak valid atau sudah lunas, bot membalas dengan pesan error yang informatif.
  • Bot tidak akan lagi mengirim pengingat untuk invoice yang sudah lunas.

Kasus tepi yang ditangani

  • Pemilik mengirim perintah dengan format yang salah.
  • Invoice ID yang diberikan tidak ditemukan di database.
  • Invoice ID yang diberikan sudah berstatus 'PAID'.

Kontrol Bot via Chat Owner

must-have

Pemilik UMKM dapat menggunakan perintah chat seperti `/tagihan`, `/stop`, dan `/start` untuk mengelola bot.

  • Pemilik UMKM dapat mengirim perintah `/tagihan` untuk mendapatkan daftar ringkas invoice 'PENDING' yang jatuh tempo.
  • Pemilik UMKM dapat mengirim perintah `/stop` untuk menghentikan sementara pengiriman pengingat tagihan otomatis.
  • Setelah `/stop`, bot tidak akan mengirim pengingat otomatis sampai perintah `/start` diberikan.
  • Pemilik UMKM dapat mengirim perintah `/start` untuk melanjutkan pengiriman pengingat tagihan otomatis.
  • Bot hanya merespons perintah dari nomor WhatsApp yang terdaftar sebagai pemilik.
  • Bot membalas dengan pesan error jika perintah tidak dikenal.

Kasus tepi yang ditangani

  • Pemilik mengirim perintah yang tidak dikenal.
  • Pemilik mencoba `/stop` saat bot sudah berhenti, atau `/start` saat bot sudah berjalan.

Laporan Harian ke Owner

should-have

Bot mengirimkan laporan ringkas aktivitas harian (jumlah pengingat terkirim, bukti bayar diterima) ke pemilik UMKM.

  • Bot mengirim laporan ringkas ke pemilik UMKM setiap hari pukul 18:00 WIB.
  • Laporan berisi jumlah pengingat yang berhasil terkirim hari itu.
  • Laporan berisi jumlah bukti pembayaran yang diterima dari pelanggan hari itu.
  • Laporan berisi daftar invoice yang dikonfirmasi lunas oleh owner hari itu.

Tech Stack

Frontend: N/A (Bot WhatsApp)
Backend: Node.js (Express.js)
Database: PostgreSQL
Hosting: Render.com (untuk Node.js dan PostgreSQL)

Akan menggunakan library untuk interaksi WhatsApp API (misalnya, whatsapp-web.js atau library resmi jika tersedia dan sesuai budget). Penyimpanan bukti pembayaran akan menggunakan layanan cloud storage.

Architecture

Sistem ini adalah bot WhatsApp berbasis Node.js yang berinteraksi dengan pelanggan dan pemilik UMKM melalui pesan WhatsApp. Bot menerima webhook dari WhatsApp untuk pesan masuk, memprosesnya, berinteraksi dengan database PostgreSQL untuk data tagihan dan status bot, serta mengirim pesan keluar melalui WhatsApp API.

WhatsApp API Client

Mengirim dan menerima pesan ke/dari WhatsApp.

Webhook Handler

Menerima dan memvalidasi payload webhook dari WhatsApp.

Message Processor

Menganalisis jenis pesan (teks/gambar), mem-parse perintah chat, dan mengorkestrasi respons.

Database Service

Mengelola operasi CRUD pada database PostgreSQL (tagihan, pelanggan, pembayaran, status bot).

Scheduler (Cron Job)

Memicu tugas terjadwal seperti pengiriman pengingat tagihan dan laporan harian.

Cloud Storage Service

Menyimpan gambar bukti pembayaran dan mengembalikan URL-nya.

Alur data

  1. Pelanggan mengirim pesan/gambar ke bot WhatsApp.
  2. WhatsApp mengirim webhook ke endpoint `/webhook/whatsapp` bot.
  3. Webhook Handler menerima, memvalidasi, dan meneruskan pesan ke Message Processor.
  4. Message Processor: Jika gambar, unggah ke Cloud Storage, simpan URL di DB, teruskan ke Owner. Jika teks, parse perintah (misal: `/lunas`, `/tagihan`, `/stop`, `/start`).
  5. Untuk perintah owner: Message Processor memanggil Database Service untuk memperbarui/mengambil data.
  6. Database Service berinteraksi dengan PostgreSQL.
  7. Message Processor/Database Service memanggil WhatsApp API Client untuk mengirim balasan ke pelanggan atau owner.
  8. Setiap pagi, Scheduler memicu `send-reminders` job.
  9. Job `send-reminders` memanggil Database Service untuk mengambil invoice jatuh tempo.
  10. Job `send-reminders` memanggil WhatsApp API Client untuk mengirim pengingat ke pelanggan dengan jeda aman.
Memuat diagram…

Database Schema

Ini struktur data aplikasimu. Kamu tidak perlu paham semuanya — AI yang akan membuatnya. Kolom created_at/updated_at ditambahkan otomatis tiap tabel.

usersData pengguna sistem (dalam MVP ini hanya pemilik UMKM).
iduuidPrimary key
whatsapp_numbertextNomor WhatsApp pemilik UMKM
nametextNama pemilik UMKM
customerssoft deleteData pelanggan UMKM.
iduuidPrimary key
owner_iduuidForeign key ke users.id
nametextNama pelanggan
whatsapp_numbertextNomor WhatsApp pelanggan
invoicessoft deleteData tagihan pelanggan.
iduuidPrimary key
owner_iduuidForeign key ke users.id
customer_iduuidForeign key ke customers.id
invoice_numbertextNomor invoice unik per owner
amountnumericJumlah tagihan
due_datedateTanggal jatuh tempo
statusenum:InvoiceStatusStatus tagihan (PENDING, PAID, CANCELLED)
paid_attimestampWaktu pembayaran dikonfirmasi
paymentsCatatan pembayaran yang diterima.
iduuidPrimary key
owner_iduuidForeign key ke users.id
invoice_iduuidForeign key ke invoices.id
amount_paidnumericJumlah yang dibayarkan
proof_urltextURL bukti pembayaran (gambar)
whatsapp_message_idtextID pesan WhatsApp dari bukti pembayaran, untuk anti-duplikasi
statusenum:PaymentStatusStatus pemrosesan pembayaran (RECEIVED, CONFIRMED, REJECTED)
bot_messages_logLog pesan yang dikirim dan diterima oleh bot, untuk debugging dan anti-duplikasi.
iduuidPrimary key
owner_iduuidForeign key ke users.id
whatsapp_message_idtextID pesan unik dari WhatsApp (untuk pesan masuk/keluar)
directiontextINBOUND atau OUTBOUND
message_typetextTEXT, IMAGE, COMMAND
contenttextIsi pesan atau URL media
from_numbertextNomor pengirim
to_numbertextNomor penerima
related_invoice_iduuidOpsional: FK ke invoices.id jika pesan terkait invoice
bot_stateMenyimpan status operasional bot per owner (ACTIVE/STOPPED).
iduuidPrimary key
owner_iduuidForeign key ke users.id
statusenum:BotStatusStatus bot (ACTIVE, STOPPED)

Relasi

  • customers.owner_id → users.id (many-to-one)
  • invoices.owner_id → users.id (many-to-one)
  • invoices.customer_id → customers.id (many-to-one)
  • payments.owner_id → users.id (many-to-one)
  • payments.invoice_id → invoices.id (many-to-one)
  • bot_messages_log.owner_id → users.id (many-to-one)
  • bot_messages_log.related_invoice_id → invoices.id (many-to-one)
  • bot_state.owner_id → users.id (one-to-one)
Memuat diagram…

Struktur Folder

Struktur ini dikunci agar AI agent membangun dengan susunan file yang sama.

  • src/
  • src/app.ts — entry point aplikasi
  • src/config/ — konfigurasi aplikasi dan env vars
  • src/db/ — skema database, koneksi, dan migrasi
  • src/controllers/ — logika pemrosesan request/pesan
  • src/services/ — logika bisnis inti dan interaksi dengan layanan eksternal
  • src/routes/ — definisi endpoint API (webhook)
  • src/jobs/ — definisi cron jobs
  • src/utils/ — fungsi utilitas (validasi, error handling)
  • src/tests/ — unit dan integrasi tests
  • drizzle/ — folder untuk migrasi Drizzle Kit

API Endpoints

POST
/webhook/whatsappMenerima pesan masuk dari pelanggan via webhook WhatsApp. Memproses pesan teks atau gambar (bukti pembayaran).
POST
/api/jobs/send-remindersEndpoint internal yang dipicu oleh cron job untuk memulai proses pengiriman pengingat tagihan harian.
POST
/api/jobs/send-daily-reportEndpoint internal yang dipicu oleh cron job untuk mengirim laporan aktivitas harian ke owner.

Enum

InvoiceStatusPENDING · PAID · CANCELLED
PaymentStatusRECEIVED · CONFIRMED · REJECTED
BotStatusACTIVE · STOPPED

Environment Variables

DATABASE_URLbackendwajibURL koneksi database PostgreSQL
WHATSAPP_API_TOKENbackendwajibToken untuk otentikasi ke WhatsApp API
OWNER_WHATSAPP_NUMBERbackendwajibNomor WhatsApp pemilik UMKM (format internasional tanpa '+')
CLOUDINARY_CLOUD_NAMEbackendwajibNama cloud Cloudinary untuk penyimpanan gambar
CLOUDINARY_API_KEYbackendwajibAPI Key Cloudinary
CLOUDINARY_API_SECRETbackendwajibAPI Secret Cloudinary
BOT_RATE_LIMIT_MSbackendJeda minimal antar pesan WhatsApp yang dikirim bot (dalam milidetik)

Library Inti

express · backendpg · backenddrizzle-orm · backenddrizzle-kit · devwhatsapp-web.js · backendnode-cron · backenddotenv · backendcloudinary · backendjimp · backendzod · shared

Tasks (siap kirim ke AI agent)

T1
Setup Test Runner & Unit Test untuk Logika Inti· S

Pasang Jest atau Vitest sebagai test runner. Tulis unit test untuk fungsi-fungsi inti seperti validasi nomor WhatsApp, parsing perintah chat, dan logika penentuan invoice jatuh tempo.

Lihat isi perintah
Instal Jest/Vitest. Buat file `src/utils/validation.ts` untuk fungsi `isValidWhatsappNumber(number: string)` dan `src/utils/invoice.ts` untuk `getDueInvoices(invoices: Invoice[], today: Date)`. Tulis unit test untuk kedua fungsi ini di `src/tests/`.
T2
Inisialisasi Proyek Node.js & Express.js· XS

Buat struktur proyek dasar Node.js dengan Express.js, termasuk konfigurasi TypeScript dan ESLint.

Lihat isi perintah
Inisialisasi proyek Node.js dengan `npm init -y`. Tambahkan TypeScript, Express.js, dan ESLint. Buat `src/app.ts` sebagai entry point.
T3
Konfigurasi Database PostgreSQL· M· Butuh dulu: T2

Siapkan koneksi database PostgreSQL menggunakan Drizzle ORM atau `pg` client, termasuk migrasi awal untuk tabel `users` dan `bot_state`.

Lihat isi perintah
Instal `pg` dan `drizzle-orm` (atau `knex` untuk migrasi). Buat `src/db/schema.ts` untuk definisi tabel `users` dan `bot_state`. Buat `src/db/index.ts` untuk koneksi database. Buat migrasi awal untuk tabel `users` dan `bot_state`.
T4
Definisi Skema Database Lengkap· M· Butuh dulu: T3

Definisikan semua tabel, kolom, enum, dan relasi yang diperlukan sesuai `databaseSchema`.

Lihat isi perintah
Lengkapi `src/db/schema.ts` dengan definisi tabel `customers`, `invoices`, `payments`, dan `bot_messages_log` beserta semua kolom, tipe, default, dan relasi yang ditentukan di PRD. Tambahkan definisi enum `InvoiceStatus`, `PaymentStatus`, `BotStatus`.
T5
Implementasi Migrasi Database· S· Butuh dulu: T4

Buat script migrasi untuk menerapkan skema database yang telah didefinisikan.

Lihat isi perintah
Buat script migrasi menggunakan Drizzle Kit atau Knex.js untuk membuat semua tabel dan enum yang didefinisikan di `src/db/schema.ts`. Pastikan migrasi bisa dijalankan dan di-rollback.
T6
Setup WhatsApp API Client· M· Butuh dulu: T2

Integrasikan library WhatsApp API (misal: `whatsapp-web.js`) dan siapkan inisialisasi client.

Lihat isi perintah
Instal `whatsapp-web.js`. Buat `src/services/whatsapp.ts` untuk inisialisasi `Client` dan fungsi `sendMessage(to: string, message: string)` serta `sendMedia(to: string, media: Media)`.
T7
Webhook Handler untuk Pesan Masuk WhatsApp· M· Butuh dulu: T6

Buat endpoint API untuk menerima webhook dari WhatsApp (pesan masuk dari pelanggan).

Lihat isi perintah
Buat `src/routes/webhook.ts` dengan endpoint `POST /webhook/whatsapp`. Endpoint ini harus mem-parse payload dari WhatsApp dan meneruskannya ke `src/controllers/messageController.ts`.
T8
Logika Pemrosesan Pesan Masuk· M· Butuh dulu: T7, T4

Implementasikan logika untuk membedakan jenis pesan (teks, gambar) dan mencatatnya ke `bot_messages_log`.

Lihat isi perintah
Di `src/controllers/messageController.ts`, buat fungsi untuk memproses pesan masuk. Jika pesan adalah gambar, simpan URL-nya. Catat setiap pesan masuk ke tabel `bot_messages_log` dengan `whatsapp_message_id` sebagai kunci unik untuk mencegah duplikasi.
T9
Penyimpanan Bukti Pembayaran ke Cloud Storage· S· Butuh dulu: T8

Implementasikan fungsi untuk mengunggah gambar bukti pembayaran ke Cloudinary dan mendapatkan URL-nya.

Lihat isi perintah
Instal `cloudinary`. Buat `src/services/cloudinary.ts` dengan fungsi `uploadImage(base64Image: string)` yang mengembalikan URL. Integrasikan ini ke `src/controllers/messageController.ts` saat menerima gambar.
T10
Penerusan Bukti Pembayaran ke Owner· S· Butuh dulu: T9, T6

Setelah menerima bukti pembayaran, bot harus meneruskannya ke nomor WhatsApp pemilik UMKM.

Lihat isi perintah
Di `src/controllers/messageController.ts`, setelah gambar diunggah, gunakan `whatsappService.sendMedia()` untuk meneruskan gambar ke `OWNER_WHATSAPP_NUMBER` beserta nomor invoice yang terdeteksi (jika ada) atau pesan default.
T11
Balasan Konfirmasi ke Pelanggan· XS· Butuh dulu: T8, T6

Bot membalas pelanggan setelah bukti pembayaran diterima.

Lihat isi perintah
Di `src/controllers/messageController.ts`, setelah memproses pesan masuk (baik teks atau gambar), kirim balasan ke pelanggan menggunakan `whatsappService.sendMessage()` dengan pesan 'Bukti pembayaran Anda telah diterima dan akan segera diproses. Terima kasih!'
T12
Scheduler untuk Pengingat Tagihan· S· Butuh dulu: T2

Siapkan cron job menggunakan `node-cron` untuk menjalankan logika pengingat tagihan setiap pagi.

Lihat isi perintah
Instal `node-cron`. Buat `src/jobs/reminderJob.ts` yang berisi logika penjadwalan cron untuk berjalan setiap hari pukul 09:00 WIB. Panggil fungsi `sendDailyReminders()` dari `src/services/invoiceService.ts`.
T13
Logika Pengambilan Invoice Jatuh Tempo· S· Butuh dulu: T4, T5

Implementasikan fungsi untuk mengambil semua invoice yang jatuh tempo dan berstatus 'PENDING'.

Lihat isi perintah
Di `src/services/invoiceService.ts`, buat fungsi `getDuePendingInvoices()` yang mengambil data dari tabel `invoices` dengan `status = 'PENDING'` dan `due_date <= hari ini`.
T14
Logika Pengiriman Pengingat dengan Jeda Aman· M· Butuh dulu: T13, T6

Implementasikan pengiriman pesan pengingat satu per satu dengan jeda yang dapat dikonfigurasi.

Lihat isi perintah
Di `src/services/invoiceService.ts`, buat fungsi `sendDailyReminders()`. Iterasi melalui invoice yang jatuh tempo, panggil `whatsappService.sendMessage()` untuk setiap pelanggan, dan gunakan `await new Promise(resolve => setTimeout(resolve, BOT_RATE_LIMIT_MS))` untuk jeda antar pesan. Pastikan pesan berisi detail invoice.
T15
Penanganan Perintah Chat Owner: `/lunas`· M· Butuh dulu: T8, T4

Implementasikan parsing perintah `/lunas <invoice_id>` dan logika pembaruan status invoice.

Lihat isi perintah
Di `src/controllers/messageController.ts`, tambahkan logika untuk mendeteksi perintah `/lunas` dari `OWNER_WHATSAPP_NUMBER`. Parse `invoice_id`. Panggil `src/services/invoiceService.ts` untuk fungsi `markInvoiceAsPaid(invoiceId: string, ownerId: string)`. Kirim balasan konfirmasi atau error ke owner.
T16
Fungsi `markInvoiceAsPaid`· S· Butuh dulu: T15

Buat fungsi di service layer untuk mengubah status invoice menjadi 'PAID'.

Lihat isi perintah
Di `src/services/invoiceService.ts`, buat fungsi `markInvoiceAsPaid(invoiceId: string, ownerId: string)`. Fungsi ini harus mencari invoice berdasarkan ID dan `owner_id`, memverifikasi statusnya 'PENDING', lalu memperbarui `status` menjadi 'PAID' dan `paid_at` menjadi `now()`.
T17
Penanganan Edge Case: Invoice Tidak Ditemukan/Sudah Lunas· XS· Butuh dulu: T16

Pastikan bot memberikan pesan error yang jelas saat owner mencoba `/lunas` untuk invoice yang tidak ada atau sudah lunas.

Lihat isi perintah
Modifikasi `markInvoiceAsPaid` di `src/services/invoiceService.ts` untuk melempar error jika invoice tidak ditemukan atau statusnya bukan 'PENDING'. Tangani error ini di `src/controllers/messageController.ts` dan kirim pesan error yang sesuai ke owner.
T18
Anti-Duplikasi Pengiriman Pengingat· S· Butuh dulu: T14

Pastikan pengingat hanya dikirim sekali per invoice per hari.

Lihat isi perintah
Modifikasi `sendDailyReminders()` di `src/services/invoiceService.ts`. Sebelum mengirim pesan, cek apakah `bot_messages_log` sudah memiliki entri pengingat untuk invoice ini pada hari yang sama. Jika sudah, lewati. Setelah berhasil mengirim, catat ke `bot_messages_log`.
T19
Penanganan Error & Retry untuk WhatsApp API· M· Butuh dulu: T6, T14

Implementasikan mekanisme retry dengan backoff eksponensial untuk pengiriman pesan WhatsApp yang gagal.

Lihat isi perintah
Modifikasi `whatsappService.sendMessage()` dan `sendMedia()` untuk menyertakan logika retry (misal, 3 kali percobaan) dengan jeda backoff (misal, 1s, 2s, 4s) jika terjadi error dari WhatsApp API. Catat kegagalan permanen ke log.
T20
Notifikasi Owner Saat Bot Error· S· Butuh dulu: T6, T19

Kirim notifikasi ke owner jika ada error kritis pada bot (misal, koneksi DB putus, WhatsApp API gagal terus-menerus).

Lihat isi perintah
Buat `src/utils/errorHandler.ts` untuk menangani error global. Jika terjadi error kritis, kirim pesan notifikasi ke `OWNER_WHATSAPP_NUMBER` menggunakan `whatsappService.sendMessage()`.
T21
Konfigurasi Environment Variables· XS· Butuh dulu: T3, T6, T9

Daftarkan semua environment variable yang dibutuhkan dan buat file `.env.example`.

Lihat isi perintah
Buat file `.env.example` dan daftarkan `DATABASE_URL`, `WHATSAPP_API_TOKEN`, `OWNER_WHATSAPP_NUMBER`, `CLOUDINARY_CLOUD_NAME`, `CLOUDINARY_API_KEY`, `CLOUDINARY_API_SECRET`, `BOT_RATE_LIMIT_MS`.
T22
Setup Process Manager (PM2/Systemd)· S· Butuh dulu: T2

Konfigurasi PM2 atau systemd untuk memastikan bot tetap berjalan dan restart otomatis jika crash.

Lihat isi perintah
Buat file konfigurasi `ecosystem.config.js` untuk PM2 atau unit file systemd untuk menjalankan aplikasi Node.js `src/app.ts` secara persisten dan otomatis restart.
T23
Penanganan Perintah Chat Owner: `/tagihan`· M· Butuh dulu: T8, T4

Implementasikan parsing perintah `/tagihan` dan logika untuk menampilkan daftar invoice 'PENDING' yang jatuh tempo.

Lihat isi perintah
Di `src/controllers/messageController.ts`, tambahkan logika untuk mendeteksi perintah `/tagihan` dari `OWNER_WHATSAPP_NUMBER`. Panggil `src/services/invoiceService.ts` untuk fungsi `getDuePendingInvoices()`. Format hasilnya menjadi pesan teks ringkas dan kirim ke owner.
T24
Penanganan Perintah Chat Owner: `/stop`· M· Butuh dulu: T8, T4

Implementasikan parsing perintah `/stop` dan logika untuk mengubah status bot menjadi 'STOPPED'.

Lihat isi perintah
Di `src/controllers/messageController.ts`, tambahkan logika untuk mendeteksi perintah `/stop` dari `OWNER_WHATSAPP_NUMBER`. Panggil `src/services/botStateService.ts` untuk fungsi `setBotStatus('STOPPED', ownerId)`. Kirim balasan konfirmasi ke owner.
T25
Penanganan Perintah Chat Owner: `/start`· M· Butuh dulu: T8, T4

Implementasikan parsing perintah `/start` dan logika untuk mengubah status bot menjadi 'ACTIVE'.

Lihat isi perintah
Di `src/controllers/messageController.ts`, tambahkan logika untuk mendeteksi perintah `/start` dari `OWNER_WHATSAPP_NUMBER`. Panggil `src/services/botStateService.ts` untuk fungsi `setBotStatus('ACTIVE', ownerId)`. Kirim balasan konfirmasi ke owner.
T26
Fungsi `setBotStatus`· S· Butuh dulu: T24, T25

Buat fungsi di service layer untuk mengubah status bot di tabel `bot_state`.

Lihat isi perintah
Buat `src/services/botStateService.ts` dengan fungsi `setBotStatus(status: BotStatus, ownerId: string)`. Fungsi ini harus memperbarui kolom `status` di tabel `bot_state` untuk `owner_id` yang sesuai. Jika belum ada entri, buat baru.
T27
Gating Pengiriman Pengingat Berdasarkan Status Bot· S· Butuh dulu: T14, T26

Modifikasi job pengingat agar hanya berjalan jika status bot adalah 'ACTIVE'.

Lihat isi perintah
Modifikasi `sendDailyReminders()` di `src/services/invoiceService.ts`. Sebelum memulai proses pengiriman, panggil `botStateService.getBotStatus(ownerId)`. Jika statusnya 'STOPPED', log dan keluar tanpa mengirim pesan.
T28
Scheduler untuk Laporan Harian Owner· S· Butuh dulu: T12

Siapkan cron job untuk mengirim laporan harian ke owner.

Lihat isi perintah
Di `src/jobs/dailyReportJob.ts`, buat penjadwalan cron untuk berjalan setiap hari pukul 18:00 WIB. Panggil fungsi `sendDailyReport()` dari `src/services/reportService.ts`.
T29
Logika Pembuatan Laporan Harian· M· Butuh dulu: T4, T5, T18, T16

Implementasikan fungsi untuk mengumpulkan data laporan harian (pengingat terkirim, bukti bayar diterima, invoice lunas).

Lihat isi perintah
Buat `src/services/reportService.ts` dengan fungsi `sendDailyReport(ownerId: string)`. Fungsi ini harus mengambil data dari `bot_messages_log` (untuk pengingat terkirim dan bukti bayar diterima) dan `invoices` (untuk invoice lunas) untuk hari sebelumnya. Format data menjadi pesan teks ringkas.
T30
Pengiriman Laporan Harian ke Owner· XS· Butuh dulu: T29, T6

Kirim laporan harian yang telah dibuat ke nomor WhatsApp pemilik UMKM.

Lihat isi perintah
Di `src/services/reportService.ts`, setelah laporan dibuat, gunakan `whatsappService.sendMessage()` untuk mengirim laporan ke `OWNER_WHATSAPP_NUMBER`.
T31
Penanganan Edge Case: Perintah Owner Tidak Dikenal· XS· Butuh dulu: T8

Bot harus merespons dengan pesan error yang jelas jika owner mengirim perintah yang tidak dikenal.

Lihat isi perintah
Di `src/controllers/messageController.ts`, setelah mencoba mem-parse semua perintah yang dikenal, jika tidak ada yang cocok, kirim balasan ke owner dengan pesan 'Perintah tidak dikenal. Gunakan /tagihan, /lunas <id>, /stop, atau /start.'.
T32
Penanganan Edge Case: Owner Mengirim Perintah Saat Bot Sudah di Status Tersebut· XS· Butuh dulu: T24, T25, T26

Bot harus memberikan pesan informatif jika owner mencoba `/stop` saat bot sudah berhenti, atau `/start` saat bot sudah berjalan.

Lihat isi perintah
Modifikasi logika di `src/controllers/messageController.ts` untuk perintah `/stop` dan `/start`. Sebelum mengubah status, cek status bot saat ini. Jika perintah yang diberikan sama dengan status saat ini, kirim balasan seperti 'Bot sudah dalam mode berhenti.' atau 'Bot sudah berjalan.'.

Risks

  • Perubahan API WhatsApp dapat memutus fungsionalitas bot.
  • Pembatasan rate limit dari WhatsApp API dapat menyebabkan pesan tertunda atau gagal terkirim.
  • Kesalahan parsing pesan pelanggan (misalnya, nomor invoice tidak terdeteksi) dapat menyebabkan proses manual.
  • Ketergantungan pada Cloudinary untuk penyimpanan gambar, jika layanan down atau kuota habis.
  • Potensi duplikasi pengiriman pesan jika ada masalah koneksi atau retry yang tidak tepat.