Status pesan WhatsApp menunjukkan perkembangan pesan setelah aplikasi mengirimkan request melalui API. Dengan webhook, perubahan status tersebut dapat diterima secara otomatis oleh server sehingga aplikasi tidak perlu terus-menerus melakukan pengecekan status pesan.
Status pesan dapat digunakan untuk memperbarui riwayat pengiriman, menampilkan status pada dashboard, mencatat pesan yang gagal, atau menentukan proses lanjutan setelah pesan diterima oleh WhatsApp.

Alur sederhananya:
Aplikasi
↓
API WhatsApp
↓
Pesan dikirim
↓
Status pesan berubah
↓
Webhook
↓
Server
↓
Database / Dashboard
`
Apa Itu Status Pesan WhatsApp?
Status pesan WhatsApp adalah informasi mengenai kondisi pesan dalam proses pengiriman.
Status ini berbeda dengan status koneksi device.
Status device menunjukkan apakah device WhatsApp terhubung, sedangkan status pesan menunjukkan kondisi pesan tertentu setelah dikirim.
Contohnya:
Device:
CONNECTED
berbeda dengan:
Pesan:
SENT
DELIVERED
READ
Aplikasi perlu menyimpan kedua jenis informasi tersebut secara terpisah jika membutuhkan monitoring device sekaligus monitoring pesan.
Mengapa Status Pesan Perlu Ditangani?
Ketika sistem mengirim ribuan pesan, aplikasi tidak cukup hanya mengetahui bahwa request API berhasil diterima.
Request berhasil diterima API belum tentu berarti pesan sudah sampai ke penerima.
Contoh alur:
Request berhasil
↓
Pesan diproses
↓
Pesan terkirim
↓
Pesan diterima
↓
Pesan dibaca
Dengan menerima event status melalui webhook, aplikasi dapat memperbarui informasi pesan berdasarkan event yang diterima.
Contohnya pada dashboard:
Pesan #12345
Status: READ
atau:
Pesan #12346
Status: FAILED
Buat Endpoint Webhook
Endpoint webhook harus dapat menerima HTTP request dari API.
Contoh menggunakan Node.js dan Express:
const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhook/whatsapp', (req, res) => {
console.log(
JSON.stringify(req.body, null, 2)
);
res.sendStatus(200);
});
app.listen(3000, () => {
console.log('Server berjalan di port 3000');
});
Pada tahap awal, tampilkan payload secara lengkap agar struktur event dapat diketahui.
Jangan langsung membuat kode berdasarkan asumsi nama field status. Gunakan payload aktual yang diterima dari API.
Membaca Payload Status
Setelah webhook menerima event, periksa isi request:
app.post('/webhook/whatsapp', (req, res) => {
const data = req.body;
console.log('Webhook diterima');
console.log(JSON.stringify(data, null, 2));
res.sendStatus(200);
});
Dari payload tersebut, tentukan:
- ID pesan
- Nomor tujuan
- Status pesan
- Waktu event
- Device yang digunakan
- Informasi lain yang diperlukan aplikasi
Nama field harus mengikuti struktur payload webhook yang digunakan.
Jika struktur payload belum diketahui, jangan membuat parser dengan nama field yang belum diverifikasi.
Simpan ID Pesan
ID pesan penting untuk menghubungkan event webhook dengan pesan yang sebelumnya dikirim.
Misalnya aplikasi mengirim pesan:
Pesan ID: ABC123
Tujuan: 628123456789
Status: SENT
Kemudian webhook menerima event untuk pesan yang sama.
Aplikasi dapat mencari:
message_id = ABC123
lalu memperbarui status pada database.
Alurnya:
Kirim pesan
↓
Simpan message_id
↓
Webhook menerima event
↓
Cari message_id
↓
Update status
Tanpa identifier yang konsisten, aplikasi akan kesulitan menentukan pesan mana yang harus diperbarui ketika jumlah pengiriman sudah besar.
Struktur Database untuk Status Pesan
Data pesan dan statusnya dapat disimpan pada tabel seperti:
messages
- id
- message_id
- device_id
- recipient
- message
- status
- created_at
- updated_at
Contoh:
| Message ID | Recipient | Status |
|---|---|---|
| ABC123 | 628123456789 | SENT |
| ABC124 | 628987654321 | DELIVERED |
| ABC125 | 628555555555 | READ |
Ketika event baru diterima, aplikasi mencari message_id yang sesuai dan memperbarui status.
Update Status dari Webhook
Contoh struktur handler:
app.post('/webhook/whatsapp', async (req, res) => {
const event = req.body;
res.sendStatus(200);
try {
const messageId = extractMessageId(event);
const status = extractMessageStatus(event);
if (!messageId || !status) {
return;
}
await updateMessageStatus(
messageId,
status
);
} catch (error) {
console.error(
'Gagal memproses status pesan:',
error
);
}
});
Fungsi extractMessageId() dan extractMessageStatus() perlu disesuaikan dengan struktur payload yang benar-benar diterima.
Jangan Menganggap Request API = Pesan Berhasil Terkirim
Salah satu kesalahan umum adalah mengubah status pesan menjadi SENT hanya karena request API menghasilkan response sukses.
Contohnya:
Aplikasi
↓
POST API
↓
HTTP 200
Response HTTP yang sukses menunjukkan request telah diproses oleh API. Status pesan berikutnya tetap perlu ditangani sesuai event yang diterima.
Karena itu, sistem dapat menyimpan status secara bertahap:
REQUESTED
↓
SENT
↓
DELIVERED
↓
READ
Nama dan urutan status harus mengikuti event yang tersedia pada API yang digunakan.
Menangani Pesan Gagal
Status gagal perlu diproses secara khusus karena aplikasi mungkin perlu mengambil tindakan berikutnya.
Contohnya:
Status: FAILED
↓
Simpan alasan jika tersedia
↓
Tandai pesan gagal
↓
Masuk antrean retry jika diperlukan
Data dapat disimpan seperti:
message_id: ABC123
status: FAILED
error: ...
updated_at: ...
Jangan langsung melakukan retry setiap kali menerima status gagal.
Retry harus memiliki batas percobaan dan aturan yang jelas agar satu pesan tidak dikirim berulang kali tanpa kontrol.
Membuat Retry untuk Pesan Gagal
Jika sistem membutuhkan retry, simpan jumlah percobaan pengiriman.
Contoh:
messages
- message_id
- status
- retry_count
- last_retry_at
Alurnya:
FAILED
↓
retry_count < batas?
↙ ↘
Ya Tidak
↓ ↓
Retry Tandai gagal
Misalnya batas retry ditetapkan sebanyak tiga kali:
Percobaan 1 → FAILED
Percobaan 2 → FAILED
Percobaan 3 → FAILED
→ Berhenti retry
Batas tersebut harus disesuaikan dengan kebutuhan sistem.
Menangani Status READ
Status READ dapat digunakan untuk memperbarui tampilan pada dashboard.
Contohnya:
Pesan:
Halo, apakah masih tersedia?
Status:
READ
Database kemudian diperbarui:
UPDATE messages
SET status = 'READ'
WHERE message_id = 'ABC123';
Pada aplikasi nyata, gunakan query parameterized atau ORM agar query tidak dibuat dari string input secara langsung.
Menangani Status DELIVERED
Status DELIVERED menunjukkan pesan telah mencapai tahap penerimaan yang sesuai dengan status tersebut.
Aplikasi dapat menggunakannya untuk:
- memperbarui dashboard;
- menghitung statistik pengiriman;
- mencatat waktu delivery;
- membedakan pesan yang sudah diterima dan belum.
Contoh data:
message_id: ABC123
status: DELIVERED
delivered_at: 2026-09-30 10:30:12
Simpan waktu setiap status jika laporan pengiriman membutuhkan data tersebut.
Simpan Waktu Setiap Perubahan Status
Untuk laporan yang lebih detail, database dapat menyimpan timestamp setiap perubahan.
Contoh:
messages
- message_id
- status
- sent_at
- delivered_at
- read_at
- failed_at
Data tersebut dapat digunakan untuk mengetahui durasi antara pengiriman, penerimaan, dan pembacaan pesan.
Contohnya:
sent_at → 10:00:00
delivered_at → 10:00:03
read_at → 10:01:15
Dari data tersebut, aplikasi dapat menghitung waktu yang dibutuhkan setiap tahap.
Hindari Status Mundur
Event webhook dapat datang tidak sesuai urutan waktu yang diharapkan jika aplikasi memproses banyak request secara bersamaan.
Contoh:
READ
↓
DELIVERED
Jika aplikasi langsung menyimpan event kedua, status pesan dapat berubah kembali dari READ menjadi DELIVERED.
Karena itu, aplikasi perlu memiliki aturan urutan status.
Contoh sederhana:
SENT < DELIVERED < READ
Jika status baru memiliki tingkat yang lebih rendah daripada status yang sudah tersimpan, aplikasi dapat mengabaikannya.
Contoh:
const statusOrder = {
SENT: 1,
DELIVERED: 2,
READ: 3
};
if (
statusOrder[newStatus] >=
statusOrder[currentStatus]
) {
await updateMessageStatus(
messageId,
newStatus
);
}
Daftar status dan urutannya harus disesuaikan dengan status yang benar-benar digunakan oleh API.
Hindari Event Duplikat
Webhook dapat menerima event yang sama lebih dari sekali. Jika setiap event langsung diproses, database dapat mencatat perubahan yang sama berulang kali.
Contoh:
ABC123 → DELIVERED
ABC123 → DELIVERED
ABC123 → DELIVERED
Untuk mencegah pemrosesan berulang, gunakan identifier event atau kombinasi data yang dapat membedakan event.
Jika identifier event tidak tersedia, aplikasi dapat menggunakan kombinasi seperti:
message_id + status
sebagai pemeriksaan tambahan.
Namun, cara ini perlu disesuaikan dengan kebutuhan aplikasi karena satu status dapat muncul lebih dari sekali dalam kondisi tertentu.
Pisahkan Webhook dan Proses Status
Endpoint webhook sebaiknya tidak menjalankan terlalu banyak pekerjaan sebelum memberikan response.
Contoh:
app.post('/webhook/whatsapp', async (req, res) => {
const event = req.body;
res.sendStatus(200);
await processMessageStatus(event);
});
Untuk volume tinggi, proses status dapat diteruskan ke queue:
Webhook
↓
Validasi
↓
Queue
↓
Worker
↓
Update database
↓
Dashboard
Dengan cara ini, endpoint tetap ringan ketika banyak event masuk secara bersamaan.
Contoh Proses Status Pesan
Struktur proses lengkap dapat dibuat seperti berikut:
async function processMessageStatus(event) {
const messageId = extractMessageId(event);
const newStatus = extractMessageStatus(event);
if (!messageId || !newStatus) {
return;
}
const message = await findMessage(messageId);
if (!message) {
return;
}
const currentStatus = message.status;
if (
shouldUpdateStatus(
currentStatus,
newStatus
)
) {
await updateMessageStatus(
messageId,
newStatus
);
}
}
Struktur ini memisahkan proses menjadi beberapa bagian:
- Membaca ID pesan.
- Membaca status.
- Mencari pesan pada database.
- Membandingkan status.
- Memperbarui status jika diperlukan.
Kode dapat dikembangkan tanpa membuat route webhook menjadi terlalu panjang.
Contoh Tampilan Status pada Dashboard
Data status dari webhook dapat ditampilkan seperti:
| Penerima | Pesan | Status |
|---|---|---|
| 628123456789 | Pesanan diterima | SENT |
| 628987654321 | Pembayaran berhasil | DELIVERED |
| 628555555555 | Tiket dibuat | READ |
| 628111111111 | OTP | FAILED |
Dashboard dapat menampilkan data terbaru berdasarkan status yang tersimpan di database.
Jika membutuhkan laporan, tambahkan filter:
Status:
[ Semua ]
[ SENT ]
[ DELIVERED ]
[ READ ]
[ FAILED ]
Cara Menguji Status Pesan
Pengujian dapat dilakukan dengan mengirim satu pesan terlebih dahulu.
Urutannya:
1. Kirim satu pesan melalui API
2. Simpan ID pesan
3. Periksa response API
4. Tunggu event webhook
5. Periksa payload
6. Cocokkan ID pesan
7. Periksa status
8. Pastikan database diperbarui
Gunakan log saat pengembangan:
console.log(
JSON.stringify(req.body, null, 2)
);
Setelah struktur payload sudah diketahui, gunakan logging yang lebih terkontrol pada server production.
Jika Status Pesan Tidak Masuk
Jika status pesan tidak muncul pada webhook, periksa beberapa bagian berikut:
Webhook Aktif
Pastikan URL webhook sudah dikonfigurasi dengan benar.
Endpoint Dapat Diakses
Pastikan server dapat menerima request dari internet.
Route Menerima POST
Periksa method dan path endpoint.
Payload Terbaca
Pastikan middleware membaca request body.
Device Terhubung
Status device perlu diperiksa karena pengiriman dan event pesan bergantung pada koneksi device.
ID Pesan Tersimpan
Pastikan aplikasi menyimpan identifier pesan dari proses pengiriman sehingga event webhook dapat dikaitkan dengan data yang benar.
Log Server
Periksa apakah event benar-benar sampai ke aplikasi.
Status Pesan untuk Laporan Pengiriman
Data status dari webhook dapat digunakan untuk membuat laporan.
Contohnya:
Total pesan : 10.000
SENT : 9.700
DELIVERED : 9.200
READ : 8.500
FAILED : 300
Data tersebut dapat dihitung berdasarkan status terakhir setiap pesan.
Jangan menghitung setiap event sebagai satu pesan. Satu pesan dapat menghasilkan beberapa perubahan status.
Contohnya:
ABC123 → SENT
ABC123 → DELIVERED
ABC123 → READ
Tetap dihitung sebagai satu pesan, bukan tiga pesan.
Kesimpulan
Cara menangani status pesan WhatsApp dari webhook dimulai dengan menerima event, mengambil identifier pesan dan status, kemudian memperbarui data pesan pada database.
Alurnya:
Pesan dikirim
↓
Simpan message ID
↓
Status berubah
↓
Webhook menerima event
↓
Cari message ID
↓
Periksa status
↓
Update database
↓
Dashboard / laporan
Hal penting yang perlu diperhatikan adalah membedakan status device dengan status pesan, menyimpan identifier pesan, menangani event duplikat, mencegah status mundur, dan tidak menganggap response API sebagai status akhir pesan.
Struktur webhook yang sederhana juga membuat proses status lebih mudah dikembangkan untuk dashboard, laporan pengiriman, retry, CRM, dan sistem notifikasi.


