# Webhook Keluar

Webhook keluar mengirim permintaan HTTP `POST` ke server Anda setiap kali ada kejadian pesan di tumbuh.ai. Gunakan untuk menyinkronkan pesan ke sistem lain atau memicu otomasi di luar tumbuh.ai.

## Sebelum mulai

- Anda adalah pemilik workspace.
- Paket Anda menyertakan akses Pengembang. Bila kuota webhook penuh, tombol berubah menjadi "Limit Reached".
- Server Anda punya URL HTTPS publik yang menerima `POST` dengan isi JSON.

## Membuat webhook

1. Buka **Pengembang > Webhooks**.
2. Klik "Add Webhook".
3. Isi "Name" (misalnya `n8n Production`) dan "URL Endpoint".
4. Pilih "Events" yang ingin diterima.
5. Pilih "Channels", lalu "Accounts" bila ingin membatasi ke akun tertentu.
6. Klik "Create Webhook".
7. Salin "Webhook Secret" sebelum menekan "Done". Secret hanya tampil sekali.

![Dialog Webhook Created yang menampilkan Webhook Secret dan tombol salin](/images/webhook-dibuat.png)

## Event yang tersedia

| Event | Kapan dikirim |
|---|---|
| `message.received` | Pesan masuk dari pelanggan. |
| `message.sent` | Pesan keluar diterima oleh penyedia channel. |
| `message.delivered` | Pesan sampai ke perangkat pelanggan. |
| `message.read` | Pelanggan membaca pesan. |
| `message.failed` | Pengiriman pesan gagal. |

Pilihan **Channels** saat membuat webhook adalah **WhatsApp**, **Instagram**, atau **All**. Pilih **All** bila Anda ingin menerima event dari seluruh channel, termasuk Messenger, Telegram, dan TikTok. Penyaringan khusus untuk ketiga channel itu belum tersedia. Dashboard juga masih menampilkan opsi Telegram, tetapi server menolaknya. Gunakan **All**.

## Header yang dikirim

Setiap permintaan membawa header berikut. `<PREFIX>` adalah awalan merek untuk deployment Anda, yang ditetapkan oleh penyedia layanan Anda. Lihat nama persisnya lewat menu "View Logs" atau pada permintaan pertama yang Anda terima.

```text
Content-Type: application/json
X-<PREFIX>-Signature: <tanda-tangan-hex>
X-<PREFIX>-Event: message.received
X-<PREFIX>-Delivery: <event_id>
X-<PREFIX>-Idempotency-Key: <kunci-idempotensi>
```

Header `Idempotency-Key` hanya ada pada event yang membawanya. Gunakan `X-<PREFIX>-Delivery` atau `event_id` di isi pesan untuk membuang kiriman ganda.

## Bentuk isi pesan

```json
{
  "event_type": "message.received",
  "event_id": "<uuid>",
  "timestamp": "2026-01-15T10:30:00.000Z",
  "data": {
    "message_id": "<id-pesan>",
    "customer_id": "<id-pelanggan>",
    "direction": "inbound",
    "message_type": "text",
    "content": "Halo",
    "channel": "whatsapp"
  }
}
```

Bidang tambahan seperti `customer_phone`, `customer_username`, `media_url`, dan `business_phone` muncul sesuai channel dan jenis pesan.

## Memverifikasi tanda tangan

Tanda tangan adalah HMAC-SHA256 dalam format hex, dihitung dari isi mentah permintaan (string JSON apa adanya) dengan "Webhook Secret" sebagai kunci. Tidak ada awalan `sha256=`.

```js
import { createHmac, timingSafeEqual } from "crypto";

function valid(rawBody, headerSignature, secret) {
  const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(headerSignature);
  return a.length === b.length && timingSafeEqual(a, b);
}
```

Hitung dari body mentah, bukan dari JSON yang sudah di-parse ulang.

## Retry dan penonaktifan otomatis

- Server Anda harus membalas status 2xx. Selain itu dianggap gagal.
- Batas waktu setiap percobaan: 30 detik.
- Maksimal 5 percobaan. Jeda retry: 1 menit, 5 menit, 30 menit, lalu 2 jam.
- Bila 10 pengiriman gagal beruntun, webhook dinonaktifkan otomatis dan pemilik menerima email. Satu pengiriman sukses mengembalikan hitungan gagal ke nol.
- Aktifkan lagi lewat menu baris webhook: "Enable".

## Menguji dan memantau

Di menu baris tiap webhook, pilih "Test Webhook" untuk mengirim event uji (`test`, batas waktu 10 detik) atau "View Logs" untuk melihat riwayat pengiriman. Menu juga berisi "Disable" / "Enable" dan "Delete".

## Hasil yang diharapkan

Server Anda menerima `POST` bertanda tangan untuk setiap event yang dipilih, dan log pengiriman menunjukkan status sukses.

## Masalah umum

- **Webhook nonaktif sendiri:** server Anda gagal 10 kali beruntun. Perbaiki endpoint, lalu "Enable".
- **Tanda tangan tidak cocok:** pastikan memakai body mentah dan secret yang benar. Secret tidak bisa dilihat lagi setelah dibuat.
- **Event ganda:** retry dapat mengirim event yang sama lebih dari sekali. Deduplikasi dengan `event_id`.
- Untuk memicu workflow tanpa menulis kode, lihat [n8n](/integrasi/n8n).
