Panduan ini membahas arsitektur komunikasi dua arah (two-way conversation) untuk menangkap pesan masuk dari pelanggan melalui Webhook dan meresponsnya secara otomatis.
1. Pratinjau Alur Percakapan 2-Arah
Contoh alur tanya-jawab otomatis antara pelanggan dan bot WhatsApp:
CODE
1┌──────────────────────────────────────────────┐
2│ 👤 Pelanggan: │
3│ "Halo, boleh minta info menu dan harga?" │
4│ 13:00 ✓✓ │
5│ │
6│ 🤖 PFNApp Bot (Balasan Otomatis): │
7│ "Halo Kak! 👋 Terima kasih telah menghubungi │
8│ kami. Berikut pilihan menu cepat: │
9│ │
10│ 1️⃣ Ketik *PROMO* untuk diskon hari ini │
11│ 2️⃣ Ketik *MENU* untuk katalog lengkap │
12│ 3️⃣ Ketik *CS* untuk bicara dengan tim kami" │
13│ 13:00 ✓✓ │
14└──────────────────────────────────────────────┘
2. Konfigurasi Webhook (1 Menit)
- Buka menu Console > WhatsApp > Webhooks (
/console/whatsapp/webhooks). - Masukkan URL endpoint backend Anda yang dapat diakses publik:
- Contoh:
https://api.domainanda.com/api/whatsapp/webhook
- Contoh:
- Salin Webhook Secret untuk verifikasi signature keamanan.

3. Struktur Payload Pesan Masuk
Saat pengguna mengirim pesan ke nomor WhatsApp bisnis Anda, webhook akan menerima payload JSON dengan format standar:
JSON
1{
2 "event": "messages.upsert",
3 "data": {
4 "from": "+6281234567890",
5 "messageId": "wamid.HBgLM...",
6 "timestamp": 1771747200,
7 "type": "text",
8 "text": {
9 "body": "Halo, boleh minta info menu dan harga?"
10 }
11 }
12}
4. Contoh Backend Receiver & Auto-Reply
Node.js / Express (TypeScript)
TYPESCRIPT
1import express from "express"
2import crypto from "crypto"
3
4const app = express()
5app.use(express.json())
6
7const WEBHOOK_SECRET = process.env.WHATSAPP_WEBHOOK_SECRET || "pfn_whsec_..."
8const API_KEY = process.env.PFN_WHATSAPP_API_KEY || "pfn_wa_sec_..."
9
10// 1. Endpoint Penerima Webhook
11app.post("/api/whatsapp/webhook", async (req, res) => {
12 // A. Verifikasi Signature HMAC (Opsional tapi Direkomendasikan)
13 const signature = req.headers["x-hub-signature-256"] as string
14 if (signature) {
15 const hmac = crypto
16 .createHmac("sha256", WEBHOOK_SECRET)
17 .update(JSON.stringify(req.body))
18 .digest("hex")
19 if (`sha256=${hmac}` !== signature) {
20 return res.status(401).send("Invalid signature")
21 }
22 }
23
24 // B. Wajib beri respons 200 OK secepatnya
25 res.status(200).send("OK")
26
27 const { event, data } = req.body
28
29 // C. Proses pesan masuk tipe teks
30 if (event === "messages.upsert" && data?.type === "text") {
31 const senderPhone = data.from
32 const userText = data.text?.body?.toLowerCase() || ""
33
34 // Logika Auto-Reply Sederhana
35 let replyText =
36 "Halo Kak! Ketik *MENU* untuk melihat produk atau *CS* untuk bantuan."
37
38 if (userText.includes("menu") || userText.includes("harga")) {
39 replyText =
40 "📋 *Katalog Produk Kami*:\n1. Paket Starter: Rp 50.000\n2. Paket Pro: Rp 150.000\n\nKetik *BELI* untuk memesan."
41 } else if (userText.includes("cs") || userText.includes("bantuan")) {
42 replyText =
43 "👨💼 Tim CS kami akan segera membalas chat Anda dalam 5-10 menit."
44 }
45
46 // D. Kirim Balasan Instan (Free-form text message di dalam 24h window)
47 await fetch("https://pfnapp.id/api/whatsapp/messages", {
48 method: "POST",
49 headers: {
50 Authorization: `Bearer ${API_KEY}`,
51 "Content-Type": "application/json",
52 },
53 body: JSON.stringify({
54 to: senderPhone,
55 type: "text",
56 text: { body: replyText },
57 }),
58 })
59 }
60})
61
62app.listen(3000, () => console.log("Webhook receiver aktif di port 3000"))
PHP / Laravel (Route & Controller)
PHP
1namespace App\Http\Controllers;
2
3use Illuminate\Http\Request;
4use Illuminate\Support\Facades\Http;
5
6class WhatsAppWebhookController extends Controller
7{
8 public function handle(Request $request)
9 {
10 $payload = $request->all();
11
12 // 1. Tangani event pesan masuk
13 if (($payload['event'] ?? '') === 'messages.upsert') {
14 $sender = $payload['data']['from'] ?? null;
15 $text = strtolower($payload['data']['text']['body'] ?? '');
16
17 if ($sender && $text) {
18 $reply = "Terima kasih telah menghubungi kami. Ketik *INFO* untuk bantuan.";
19
20 if (str_contains($text, 'promo')) {
21 $reply = "🎉 Promo Spesial: Gunakan voucher *HEMAT50* untuk diskon 50%!";
22 }
23
24 // 2. Kirim balasan otomatis
25 Http::withToken(config('services.pfn.whatsapp_key'))
26 ->post('https://pfnapp.id/api/whatsapp/messages', [
27 'to' => $sender,
28 'type' => 'text',
29 'text' => ['body' => $reply],
30 ]);
31 }
32 }
33
34 return response()->json(['status' => 'success'], 200);
35 }
36}
5. Aturan Customer Care Window (24 Jam)
- Gratis Sesi Chat 24 Jam: Ketika pelanggan mengirim pesan terlebih dahulu ke nomor bisnis Anda, jendela percakapan 24 jam terbuka. Anda bebas membalas menggunakan pesan teks biasa (
type: "text") tanpa perlu persetujuan template. - Setelah 24 Jam: Jika jendela percakapan habis dan Anda ingin menghubungi kembali pelanggan, Anda wajib menggunakan pesan bertipe
template.