Webhook WhatsApp: Tutorial Terima Pesan Masuk di Aplikasimu
Mengirim pesan WhatsApp dari aplikasi itu gampang, tinggal panggil satu endpoint API, selesai. Tapi bagaimana cara menerima pesan WhatsApp yang masuk ke nomor kamu, lalu memprosesnya di aplikasi sendiri? Misalnya: pelanggan membalas "ya, saya jadi order", dan kamu ingin balasan itu otomatis masuk ke CRM atau sistem tiket.
Jawabannya: webhook WhatsApp. Di tutorial ini kita akan bahas tuntas cara kerjanya, cara mendaftarkan webhook di LoginWA, cara memverifikasi signature HMAC-SHA256 (lengkap dengan kode PHP dan Node.js yang bisa langsung dijalankan), sampai perilaku retry dan ide use case-nya.
Apa Itu Webhook WhatsApp?
Webhook adalah mekanisme "push": alih-alih aplikasimu yang terus-menerus bertanya ke server "ada pesan baru nggak?" (polling), server gateway-lah yang mengirim HTTP POST ke URL milikmu setiap kali ada kejadian, pesan masuk, status pengiriman berubah, device terputus, dan sebagainya.
Bedanya dengan polling kira-kira begini:
| Aspek | Polling | Webhook |
|---|---|---|
| Arah komunikasi | Aplikasimu bertanya berulang-ulang | Server mendorong data saat ada event |
| Latensi | Tergantung interval polling (detik–menit) | Hampir real-time |
| Beban server | Boros request walau tidak ada data | Request hanya saat ada event |
| Kompleksitas | Mudah, tapi tidak efisien | Perlu endpoint publik + verifikasi |
Untuk chat WhatsApp yang sifatnya percakapan real-time, webhook jelas pilihan yang masuk akal.
Persiapan
Sebelum mulai, siapkan tiga hal:
- Akun LoginWA dengan device yang sudah terhubung. Daftar gratis pakai nomor WA di loginwa.com/auth/otp, buat app, lalu scan QR untuk menghubungkan device. Paket Free sudah cukup untuk eksperimen (500 pesan/bulan).
- Endpoint HTTPS yang bisa diakses publik. Kalau masih develop di laptop, pakai tunnel seperti ngrok atau Cloudflare Tunnel:
ngrok http 3000akan memberi kamu URL publik yang meneruskan request ke localhost. - API key dari dashboard, kalau kamu mau mendaftarkan webhook lewat API (bisa juga lewat dashboard tanpa coding).
Langkah 1: Daftarkan Webhook
Cara paling cepat: buka dashboard LoginWA, masuk ke menu webhook di app kamu, isi URL endpoint (misalnya https://abc123.ngrok.io/webhook/whatsapp), pilih event yang mau didengarkan, dan simpan. Dashboard akan menampilkan webhook secret, simpan baik-baik, ini kunci untuk verifikasi signature di langkah 3.
Event Types
LoginWA mendukung 10 event types. Yang paling sering dipakai adalah message.incoming, terkirim setiap ada pesan masuk ke nomor WhatsApp yang terhubung. Event lain mencakup perubahan status pengiriman pesan keluar dan status koneksi device, jadi kamu juga bisa tahu kapan device terputus dan perlu scan QR ulang. Daftar lengkap 10 event beserta struktur payload masing-masing ada di dokumentasi.
Saran praktis: subscribe hanya event yang benar-benar kamu proses. Endpoint yang menerima semua event tapi cuma memakai satu jenis hanya menambah noise di log.
Contoh Payload
Saat ada pesan masuk, LoginWA mengirim HTTP POST berisi JSON kurang lebih seperti ini:
{
"event": "message.incoming",
"data": {
"from": "6281234567890",
"message": "Halo, saya mau tanya soal pesanan kemarin",
"device_id": "dev_xxxx",
"timestamp": "2026-06-12T09:30:00+07:00"
}
}
Field persisnya per event bisa kamu cek di docs, yang penting polanya: ada event sebagai penanda jenis kejadian, dan data berisi detailnya.
Langkah 2: Buat Endpoint Penerima
Endpoint webhook pada dasarnya cuma route HTTP POST biasa. Aturan mainnya:
- Balas cepat dengan status 2xx. Jangan melakukan proses berat (kirim email, panggil API lain) sebelum merespons, antrekan dulu, balas
200, baru proses di background. - Selalu verifikasi signature sebelum memercayai isi payload (kita bahas di langkah 3).
- Buat handler idempoten. Karena ada mekanisme retry, event yang sama bisa datang lebih dari sekali. Simpan ID pesan yang sudah diproses dan lewati duplikat.
Langkah 3: Verifikasi Signature HMAC-SHA256
Ini bagian yang sering dilewati orang, padahal krusial. Endpoint webhook kamu terbuka di internet, siapa pun yang tahu URL-nya bisa mengirim POST palsu seolah-olah ada "pesan masuk". Kalau handler kamu otomatis membuat tiket atau memberi akses berdasarkan pesan WA, ini celah serius.
Solusinya: LoginWA menandatangani setiap request dengan HMAC-SHA256. Server menghitung HMAC dari raw body request memakai webhook secret kamu, lalu menyertakan hasilnya di header X-Webhook-Signature. Di sisi kamu, hitung ulang HMAC dari raw body yang diterima dan bandingkan. Kalau cocok, request itu asli dari LoginWA dan isinya tidak diubah di tengah jalan.
Dua hal yang sering bikin verifikasi gagal:
- Pakai raw body, bukan hasil parse. JSON yang sudah di-decode lalu di-encode ulang bisa berbeda urutan key atau spasinya, HMAC-nya pasti meleset.
- Bandingkan dengan constant-time comparison (
hash_equalsdi PHP,crypto.timingSafeEqualdi Node.js), bukan==, untuk mencegah timing attack.
Contoh PHP
Simpan sebagai webhook.php dan arahkan URL webhook ke file ini:
<?php
// webhook.php, penerima webhook WhatsApp dari LoginWA
$secret = getenv('LOGINWA_WEBHOOK_SECRET'); // dari dashboard
$rawBody = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
// hitung ulang HMAC dari raw body
$expected = hash_hmac('sha256', $rawBody, $secret);
// bandingkan secara constant-time
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit('Invalid signature');
}
$payload = json_decode($rawBody, true);
if (($payload['event'] ?? '') === 'message.incoming') {
$from = $payload['data']['from'];
$text = $payload['data']['message'];
// contoh sederhana: catat ke file (di produksi: simpan ke DB / antrekan job)
file_put_contents(
__DIR__ . '/inbox.log',
date('c') . " {$from}: {$text}\n",
FILE_APPEND
);
}
// balas cepat supaya tidak dianggap gagal lalu di-retry
http_response_code(200);
echo json_encode(['status' => 'ok']);
Kalau kamu pakai Laravel, logikanya sama persis: ambil $request->getContent() sebagai raw body, verifikasi di middleware, lalu dispatch job untuk pemrosesan berat.
Contoh Node.js (Express)
const express = require('express');
const crypto = require('crypto');
const app = express();
const SECRET = process.env.LOGINWA_WEBHOOK_SECRET; // dari dashboard
// penting: simpan raw body, karena HMAC dihitung dari bytes mentah
app.use(express.json({
verify: (req, res, buf) => { req.rawBody = buf; }
}));
app.post('/webhook/whatsapp', (req, res) => {
const signature = req.headers['x-webhook-signature'] || '';
const expected = crypto
.createHmac('sha256', SECRET)
.update(req.rawBody)
.digest('hex');
const valid =
signature.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
if (!valid) return res.status(401).send('Invalid signature');
const { event, data } = req.body;
if (event === 'message.incoming') {
console.log(`Pesan dari ${data.from}: ${data.message}`);
// di produksi: push ke queue, simpan ke DB, trigger notifikasi, dst.
}
// balas cepat, proses berat jangan di sini
res.json({ status: 'ok' });
});
app.listen(3000, () => console.log('Webhook listening on :3000'));
Jalankan dengan LOGINWA_WEBHOOK_SECRET=secret_kamu node server.js, expose lewat ngrok, daftarkan URL-nya, lalu kirim pesan WA ke nomor device kamu. Kalau semuanya benar, log akan menampilkan pesan masuknya dalam hitungan detik.
Bonus: Balas Otomatis dari Handler
Begitu pesan masuk sudah sampai di aplikasimu, membalasnya tinggal satu panggilan API:
curl -X POST https://api.loginwa.com/api/v1/messages/send \
-H "Authorization: Bearer API_KEY" \
-H "Content-Type: application/json" \
-d '{"phone":"6281234567890","message":"Terima kasih, pesan kamu sudah kami terima. Tim kami akan membalas segera."}'
Catatan kuota: satu balasan API dihitung satu pesan dari kuota bulananmu (sama seperti satu OTP atau satu blast). Untuk auto-reply sederhana berbasis keyword (exact, contains, starts_with, sampai regex), kamu sebenarnya tidak perlu webhook sama sekali, fitur auto-reply bawaan sudah menanganinya, lengkap dengan prioritas dan cooldown. Webhook baru diperlukan saat logikamu butuh data dari sistemmu sendiri: cek status pesanan di database, eskalasi ke agen manusia, dan semacamnya.
Perilaku Retry: Apa yang Terjadi Kalau Endpoint Kamu Down?
Server bisa down, deploy bisa bikin endpoint sempat mati. LoginWA tidak langsung membuang event: kalau endpoint kamu merespons selain 2xx atau tidak merespons sama sekali (timeout), pengiriman akan dicoba ulang beberapa kali dengan jeda antar percobaan. Detail jadwal retry ada di dokumentasi.
Konsekuensi praktisnya untuk kode kamu:
- Idempotensi wajib. Retry berarti event yang sama bisa datang dua kali, apalagi kalau endpoint kamu sempat merespons lambat lalu timeout padahal sebenarnya sudah memproses. Cek ID/timestamp pesan sebelum memproses ulang.
- Jangan balas 5xx untuk error bisnis. Kalau payload valid tapi datanya tidak relevan buat kamu, tetap balas
200. Balas non-2xx hanya kalau kamu memang ingin event itu dikirim ulang. - Pantau log webhook. Kegagalan beruntun biasanya berarti ada yang salah di sisimu (sertifikat HTTPS kedaluwarsa, route berubah, secret tidak cocok).
Ide Use Case Webhook WhatsApp
Begitu pesan masuk bisa mengalir ke aplikasimu, banyak pintu terbuka:
- CRM. Setiap balasan pelanggan otomatis tercatat di timeline kontak, sales tidak perlu copy-paste chat manual.
- Sistem tiket / helpdesk. Pesan masuk membuat tiket baru, balasan berikutnya dari nomor yang sama menempel ke tiket yang sama. Cocok digabung dengan multi-device (paket Regular ke atas mendukung 3–10 device, lihat pricing).
- Chatbot custom. Webhook menerima pesan, aplikasimu memprosesnya (termasuk memanggil LLM kalau mau), lalu membalas via API kirim pesan. Kamu pegang kendali penuh atas logikanya.
- Konfirmasi transaksi. Pelanggan membalas "YA" pada pesan konfirmasi order, sistemmu otomatis mengubah status pesanan.
- Notifikasi internal. Teruskan pesan dari pelanggan VIP ke channel tim (Slack, Telegram, email) supaya tidak ada chat penting yang terlewat.
Gateway lain seperti Fonnte dan Wablas juga menyediakan webhook untuk pesan masuk, fitur ini memang standar di kelasnya. Yang layak kamu bandingkan adalah detailnya: LoginWA menandatangani setiap request dengan HMAC-SHA256 plus retry otomatis, dan di paket Business (Rp149.000/bulan) ada IP whitelist untuk lapisan keamanan API ekstra.
Penutup
Rangkuman alurnya: siapkan endpoint HTTPS, daftarkan URL + pilih event di dashboard LoginWA, verifikasi header X-Webhook-Signature dengan HMAC-SHA256 dari raw body, balas 2xx secepat mungkin, dan buat handler kamu idempoten karena ada retry. Dengan pola ini, pesan WhatsApp masuk bisa langsung menggerakkan CRM, sistem tiket, atau chatbot buatanmu sendiri.
Mau langsung coba? Daftar gratis di loginwa.com/auth/otp, cukup nomor WA, tanpa kartu kredit, dan paket Free memberi 500 pesan per bulan untuk eksperimen. Referensi lengkap event types dan payload webhook ada di loginwa.com/docs.