Skip to content

Handle pesan teks masuk

Belajar cara nerima, verifikasi, dan ngambil isi pesan teks yang dikirim customer ke WhatsApp kamu.

Updated View as Markdown

Tiap customer nge-chat nomor WhatsApp kamu, Wazapin bakal ngirim webhook ke endpoint yang udah kamu set.

Ikutin guide ini buat verifikasi webhook-nya, cek tipe pesannya, dan tarik isi teks lengkapnya lewat API Wazapin.

Prasyarat

Sebelum mulai, siapin dulu:

  1. Channel WhatsApp udah connect dan endpoint webhook HTTPS udah jadi. Lihat Ikhtisar webhook.
  2. Webhook kamu udah subscribe ke event message.new.
  3. Endpoint Signing Secret (misal whsec_abc123...) dan API Key kamu udah siap.

Alur prosesnya

Handle pesan masuk itu cuma tiga langkah utama:

graph TD
    A[Wazapin kirim message.new] --> B[Verifikasi signature & svix-id]
    B --> C{msg_type == 'text'?}
    C -->|Ya| D[GET /v1/messages/{id} buat ambil konten]
    C -->|Tidak| E[Arahin ke handler lain]
    D --> F[Proses teks & bales]

1. Verifikasi signature

Biar endpoint kamu aman, cek header signature (svix-signature, svix-timestamp, svix-id) pakai signing secret kamu. Butuh helper library? Lihat Verifikasi signature webhook.

2. Parse payload

Pastiin pesannya itu inbound (direction: "inbound") dan tipenya teks (msg_type: "text").

Ini contoh payload JSON buat event teks masuk:

{
  "message_id": "9f1fd66d-c37a-4b50-a8c2-b4dca523f9c8",
  "conversation_id": "0f89b0f9-74b4-44f9-b9b6-48f6d4de57aa",
  "contact_id": "c1a2b3c4-d5e6-7890-abcd-ef1234567890",
  "channel_id": "wzp_abc123",
  "direction": "inbound",
  "from_phone": "6281234567890",
  "msg_type": "text"
}

3. Tarik isi pesannya

Webhook inbound itu notifikasi ringan — nggak langsung bawa body teksnya. Pakai message_id dari payload buat hit endpoint GET /v1/messages/{messageID} dan ambil isi teksnya.


Contoh kode

Gini cara handle webhook dan ngambil body pesannya:

# Tarik data pesan pakai message_id dari payload webhook
curl -X GET "https://api.wazapin.com/v1/messages/9f1fd66d-c37a-4b50-a8c2-b4dca523f9c8" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Accept: application/json"
import express from "express";
import { Webhook } from "svix";
import { WazapinClient } from "@wazapin/sdk";

const app = express();
const wazapin = new WazapinClient({ apiKey: process.env.WAZAPIN_API_KEY });
const wh = new Webhook(process.env.WAZAPIN_WEBHOOK_SECRET!);

app.post("/webhooks/wazapin", express.raw({ type: "application/json" }), async (req, res) => {
  try {
    // 1. Verifikasi signature pakai raw body
    wh.verify(req.body, req.headers as Record<string, string>);
  } catch (err) {
    return res.status(403).send("Invalid signature");
  }

  const payload = JSON.parse(req.body.toString("utf8"));

  // 2. Filter cuma buat pesan teks masuk
  if (payload.direction === "inbound" && payload.msg_type === "text") {
    const messageId = payload.message_id;

    // 3. Tarik konten lengkapnya
    const { data: message } = await wazapin.messages.get(messageId);
    
    // Body teks masuk ada di message.content.text.body
    const textContent = message.content?.text?.body;
    console.log(`Dapat teks dari ${payload.from_phone}: ${textContent}`);
    
    // Proses pesannya async di sini...
  }

  res.status(200).send("OK");
});
from fastapi import FastAPI, Request, HTTPException
from svix.webhooks import Webhook, WebhookVerificationError
import requests
import os

app = FastAPI()
wh = Webhook(os.environ["WAZAPIN_WEBHOOK_SECRET"])
API_KEY = os.environ["WAZAPIN_API_KEY"]

@app.post("/webhooks/wazapin")
async def handle_webhook(request: Request):
    body = await request.body()
    try:
        # 1. Verifikasi signature
        wh.verify(body, dict(request.headers))
    except WebhookVerificationError:
        raise HTTPException(status_code=403, detail="Invalid signature")

    payload = await request.json()

    # 2. Filter cuma buat pesan teks masuk
    if payload.get("direction") == "inbound" and payload.get("msg_type") == "text":
        message_id = payload.get("message_id")
        
        # 3. Tarik konten lengkapnya
        response = requests.get(
            f"https://api.wazapin.com/v1/messages/{message_id}",
            headers={"X-Api-Key": API_KEY, "Accept": "application/json"}
        )
        
        if response.status_code == 200:
            message_data = response.json().get("data", {})
            text_content = message_data.get("content", {}).get("text", {}).get("body")
            print(f"Dapat teks dari {payload.get('from_phone')}: {text_content}")
            
            # Proses pesannya async di sini...

    return {"ok": True}

Troubleshooting

Kok body pesan nggak ada di webhook?

Wajar — Wazapin sengaja bikin webhook-nya ringan biar payload kecil dan latensi rendah. Kamu emang harus hit GET /v1/messages/{messageID} lagi buat baca body teksnya.

Pesan kekirim dobel

Wazapin pakai at-least-once delivery buat webhook. Kalau server kamu slow respon (lebih dari 3 detik) atau bales status non-2xx, Wazapin bakal retry ngirim event-nya. Jadi selalu bales 200 OK secepatnya, terus proses body-nya secara async.

from_phone nggak ada

Field from_phone pasti keisi format internasional (misal 6281234567890) buat pesan inbound. Kalau kamu dapet event tanpa from_phone, cek dulu direction-nya — jangan-jangan itu outbound (echo status pesan terkirim).


Langkah selanjutnya

Navigation

Type to search…

↑↓ navigate↵ selectEsc close