Lesson 6 / 7 · 10 min
Hardening: dedup, retry, dan pengambilalihan manusia
Tiga kegagalan yang pasti ditemui bot live dan kode yang menyintasinya. Checkpoint: duplikat diabaikan, kiriman di-retry, takeover admin bekerja.
Tiga hal akan menimpa bot Anda di minggu produksi pertamanya: webhook yang sama tiba dua kali, satu kiriman gagal di tengah keramaian, dan seorang pelanggan butuh manusia. Tak satu pun dari ini kasus pinggiran; inilah pekerjaannya. Masing-masing dapat perbaikan kecil yang permanen sekarang.
Perbaikan 1: dedup dengan id pesan
// server.js, first thing inside the POST /webhook handler:
const fresh = db
.prepare("INSERT OR IGNORE INTO processed(message_id) VALUES (?)")
.run(msg.id).changes === 1;
if (!fresh) return; // we already handled this exact messagePerbaikan 2: retry kiriman dengan backoff
// wa.js
async function withRetry(fn, tries = 3) {
for (let i = 0; i < tries; i++) {
try {
return await fn();
} catch (err) {
if (i === tries - 1) throw err;
await new Promise((r) => setTimeout(r, 1000 * 2 ** i));
}
}
}
// wrap the fetch inside sendText:
// return withRetry(async () => { ...the existing fetch... });Perbaikan 3: pengambilalihan manusia sungguhan
// server.js, inside the webhook handler
// 1. Entering HUMAN state notifies you (set ADMIN_PHONE in .env):
if (session.state === "HUMAN" && previousState !== "HUMAN") {
await sendText(process.env.ADMIN_PHONE,
"Takeover: " + msg.from + " butuh admin. " +
"Balas dia langsung dari WhatsApp Business. " +
"Ketik RESUME " + msg.from + " ke bot untuk menyalakan lagi.");
}
// 2. You can hand the chat back to the bot:
if (msg.from === process.env.ADMIN_PHONE &&
msg.text.body.toUpperCase().startsWith("RESUME ")) {
const phone = msg.text.body.split(" ")[1];
const s = getSession(phone);
s.state = "MENU";
saveSession(s);
await sendText(process.env.ADMIN_PHONE, "Bot aktif lagi untuk " + phone);
return;
}Dan selalu: catat keputusan
Tambahkan satu console.log per pesan yang ditangani: nomor, state sebelum, state sesudah, balasan terkirim. Saat sesuatu yang aneh terjadi bulan depan, satu baris per pesan itu adalah beda antara diagnosis lima menit dan semalaman menebak. Di produksi baris ini masuk file atau layanan log, idenya sama.
Checkpoint: kirim pesan, restart ngrok di tengah percakapan, ketik admin dan lihat ponsel Anda menerima ping takeover, lalu RESUME chat-nya. Kalau ketiganya berperilaku benar, bot Anda kini tahan tiga pukulan favorit dunia nyata.
Yang Anda dapatkan
- INSERT OR IGNORE pada id pesan membuat pengiriman ulang webhook tak berbahaya
- Backoff eksponensial (1, 2, 4 detik) menyerap sebagian besar kegagalan jaringan tanpa terlihat
- Takeover mem-ping admin dengan konteks; RESUME mengembalikan chat
- Satu baris log per pesan adalah tali penyelamat debugging masa depan Anda
Sumber terkurasi
Referensi pilihan untuk mendalami lebih jauh, direview oleh tim kami.