Outgoing Webhooks
Outgoing Webhooks
Ringkasan
Outgoing Webhooks memungkinkan admin menghubungkan OmniStream ke sistem eksternal — CRM pihak ketiga, helpdesk, spreadsheet, Zapier, atau integrasi kustom — dengan cara berlangganan event yang terjadi di platform. Setiap event yang cocok dengan daftar langganan akan menghasilkan sebuah HTTP POST request ke URL yang Anda tentukan, lengkap dengan payload JSON dan signature HMAC-SHA256 untuk verifikasi.
Halaman pengaturan berada di rute /outgoing-webhooks dan menggunakan komponen frontend/src/lib/components/settings/OutgoingWebhooksPanel.svelte. Seluruh alur eksekusi webhook dikelola oleh background dispatcher di crates/api-gateway/src/webhook_dispatcher.rs yang mendengarkan channel Redis conversation_updates dan mengantrikan delivery di tabel webhook_deliveries.
Hak akses: Outgoing webhooks hanya dapat dikelola oleh supervisor dan admin.
Event types yang didukung
OmniStream v1 mem-publish enam event utama (plus contact.created opsional). Setiap webhook berlangganan ke satu atau lebih event:
| Event Type | Dipicu saat |
|---|---|
message.received | Pesan masuk (inbound) tersimpan di database |
message.sent | Pesan keluar (outbound) berhasil dikirim oleh message-sender |
message.status | Status pesan keluar berubah (sent → delivered → read atau failed) |
conversation.created | Percakapan baru dibuat di sistem |
conversation.resolved | Status percakapan diubah menjadi resolved |
conversation.assigned | Percakapan ditugaskan ke agent (baik otomatis maupun manual) |
Enam event di atas adalah kontrak publik — admin tidak perlu mengaktifkannya satu per satu di backend; cukup berlangganan lewat UI. Jika subsistem memproduksi event yang tidak berlangganan oleh satupun webhook, backend tidak akan menuliskan delivery row (efisiensi).
Headers yang dikirim
Setiap delivery POST request menyertakan header berikut:
| Header | Nilai | Catatan |
|---|---|---|
Content-Type | application/json | Payload selalu JSON |
X-Omnistream-Event | mis. message.received | Memudahkan routing di sisi penerima tanpa parsing body |
X-Omnistream-Signature | HMAC-SHA256 hex-encoded dari seluruh body menggunakan secret webhook | Untuk verifikasi autentisitas |
Implementasi signature di crates/api-gateway/src/routes/outgoing_webhooks.rs:393 — fungsi compute_hmac_signature. Contoh verifikasi di sisi penerima (Node.js):
Code
Retry & exponential backoff
Jika endpoint penerima mengembalikan status non-2xx atau timeout, dispatcher akan melakukan retry dengan exponential backoff. Formula perhitungan delay ada di crates/api-gateway/src/webhook_dispatcher.rs:344:
Code
Artinya delay setiap attempt berkembang dengan pengali 4: 30 * 4^(attempt-1) detik.
Perilaku default (max_attempts = 3)
Kolom max_attempts di tabel outgoing_webhooks memiliki nilai default 3 (lihat migrations/20260306000022_outgoing_webhooks.sql:31 — max_attempts INTEGER NOT NULL DEFAULT 3). Dengan default ini dispatcher mencoba mengirim 3 kali total (2 retries):
| Attempt | Waktu eksekusi | Jika gagal |
|---|---|---|
| 1 | Segera setelah event muncul | Tunggu 30 detik (formula: 30 * 4^0 = 30) |
| 2 | 30 detik setelah attempt 1 gagal | Tunggu 120 detik (formula: 30 * 4^1 = 120) |
| 3 | 120 detik setelah attempt 2 gagal | attempt >= max_attempts → permanent failure |
Kondisi terminasi ada di crates/api-gateway/src/webhook_dispatcher.rs:330 — branch if attempt >= max_attempts mengubah status = 'failed' dan menghentikan retry.
Menaikkan max_attempts
max_attempts dapat dikonfigurasi per-webhook lewat endpoint PUT /api/outgoing-webhooks/{id}. Jika Anda menaikkannya ke 4 atau lebih, jadwal retry mengikuti formula yang sama — berikut referensi delay untuk attempt lanjutan:
| Attempt | Delay sebelum attempt berikutnya | Formula |
|---|---|---|
| 1 | 30 detik | 30 * 4^0 |
| 2 | 120 detik (2 menit) | 30 * 4^1 |
| 3 | 480 detik (8 menit) | 30 * 4^2 |
| 4 | 1920 detik (32 menit) | 30 * 4^3 |
| 5 | 7680 detik (~2 jam) | 30 * 4^4 |
Dengan default max_attempts = 3, attempt 3 adalah yang terakhir dan delay 480 detik tidak pernah dipakai — baris kode di webhook_dispatcher.rs:343 yang menyebut "30s, 120s, 480s" hanya relevan jika max_attempts >= 4.
Retry manual
Admin dapat melihat delivery history per-webhook di panel Activity Log dan menekan tombol Retry manual (POST /api/outgoing-webhooks/deliveries/{id}/retry) jika endpoint sudah pulih — ini membuat baris baru di antrian dengan attempt = 1, terlepas dari status sebelumnya.
Detail polling dispatcher ada di crates/api-gateway/src/webhook_dispatcher.rs:173 — fungsi process_deliveries yang dipanggil setiap siklus scheduler (30 detik), sehingga granularitas minimum delay efektif adalah 30 detik (delay < 30s dibulatkan ke siklus berikutnya).
Langkah-langkah
Membuat webhook baru
- Buka
/outgoing-webhooksdari sidebar. - Klik + New Webhook.
- Isi form:
- Name — label internal, mis.
Zapier Integration Production - URL — endpoint HTTPS tujuan
- Secret — string rahasia untuk HMAC signature (simpan juga di sisi penerima)
- Events — pilih satu atau lebih dari 6 event type
- Is Active — centang untuk mengaktifkan
- Name — label internal, mis.
- Klik Save. Backend memanggil
POST /api/outgoing-webhooks(tag Outgoing Webhooks).
Menguji webhook
- Klik ikon Play di baris webhook.
- Backend akan mengirim payload dummy ke URL dan menampilkan hasil (status code, body, durasi).
- Periksa sisi penerima apakah signature cocok.
Memeriksa riwayat delivery
- Klik ikon Eye atau buka tab Activity Log.
- Daftar delivery menampilkan: timestamp, event type, URL, status code, attempt count, dan body respons.
- Filter berdasarkan status (
pending,success,failed,cancelled) tersedia di atas tabel. - Klik baris untuk mengembang (expand) dan melihat payload lengkap.
Menonaktifkan atau menghapus
- Ikon pensil untuk mengedit (mis. menambah/menghapus event dari langganan).
- Ikon trash untuk menghapus permanent. Delivery history yang belum dieksekusi akan di-cancel.

Endpoint (tag Outgoing Webhooks)
| Aksi | Endpoint |
|---|---|
| List webhook | GET /api/outgoing-webhooks |
| Detail | GET /api/outgoing-webhooks/{id} |
| Buat webhook | POST /api/outgoing-webhooks |
| Update webhook | PUT /api/outgoing-webhooks/{id} |
| Hapus webhook | DELETE /api/outgoing-webhooks/{id} |
| Test webhook | POST /api/outgoing-webhooks/{id}/test |
| List delivery history | GET /api/outgoing-webhooks/{id}/deliveries |
| Retry delivery manual | POST /api/outgoing-webhooks/deliveries/{id}/retry |
| List event types | GET /api/outgoing-webhooks/event-types |
Skema lengkap di API Reference — Outgoing Webhooks.
Praktik terbaik
- Gunakan HTTPS, bukan HTTP, untuk URL tujuan.
- Selalu verifikasi
X-Omnistream-Signaturesebelum memproses payload — ini satu-satunya cara memastikan payload berasal dari OmniStream. - Balas cepat di sisi penerima (≤ 1 detik) dan lakukan pemrosesan lama di background queue Anda sendiri, untuk menghindari timeout yang memicu retry.
- Simpan secret di environment variable, bukan di source code.
- Monitor failed deliveries — > 5% gagal menandakan endpoint atau jaringan tidak stabil.
Rute terkait
- Activity Logs — audit perubahan konfigurasi webhook
- Developer — Webhook Outgoing — detail kontrak kontrak untuk developer integrasi