Signature dan verifikasi
Setiap request webhook yang dikirim Chatmo ditandatangani dengan HMAC-SHA256 secara default β Anda tidak perlu mengonfigurasi apa pun untuk ini. Selain itu, Anda juga bisa menambahkan custom header Anda sendiri (bearer token, API key) jika sistem penerima Anda memerlukan skema autentikasi sendiri. Pendekatan hybrid ini sama dengan pola yang digunakan Stripe, GitHub, dan Shopify.
Header yang dikirim di setiap request
| Header | Deskripsi |
|---|---|
X-Chatmo-Event | Jenis event, misalnya message.received. Sesuai dengan field event pada body. |
X-Chatmo-Signature | sha256=<HMAC dalam hex> β lihat verifikasi di bawah. |
X-Chatmo-Timestamp | Timestamp ISO 8601 saat request dikirim. Sesuai dengan created_at pada body. |
X-Chatmo-Delivery-Id | ID unik untuk grup percobaan pengiriman ini β gunakan untuk deduplikasi retry (lihat Membuat Endpoint Webhook). |
| Custom header Anda | Header apa pun yang Anda konfigurasi saat membuat webhook, dikirim apa adanya. |
Memverifikasi signature
Signature adalah HMAC-SHA256 dari raw request body, menggunakan signing secret webhook Anda sebagai key, di-encode sebagai string hex dengan prefix sha256=.
- Baca raw request body sebagai bytes, tanpa di-parsing.
- Hitung
HMAC-SHA256(secret, raw_body). - Encode hasilnya sebagai hex dan bandingkan β menggunakan perbandingan constant-time β dengan nilai pada
X-Chatmo-Signature(setelah menghapus prefixsha256=).
:::warning Gunakan raw body Signature dihitung berdasarkan byte persis yang dikirim Chatmo. Jika framework Anda mem-parsing JSON dan Anda melakukan serialize ulang sebelum membandingkan, perbedaan whitespace atau urutan key akan membuat semua pemeriksaan signature gagal. Selalu verifikasi terhadap raw body yang tidak diubah β lihat Membuat Endpoint Webhook untuk catatan spesifik per framework. :::
Lihat Contoh Kode untuk contoh verifikasi yang berfungsi dalam cURL, Node.js, Python, PHP, dan Go.
Di mana menemukan signing secret Anda
Secret dibuat otomatis saat Anda membuat webhook dan ditampilkan kepada Anda satu kali, segera setelah pembuatan β lihat Membuat Webhook. Chatmo tidak pernah menampilkannya lagi setelah itu; hanya preview yang disamarkan (misalnya whseβ¦9F2a) yang ditampilkan di dashboard setelahnya.
Jika Anda kehilangannya, gunakan Regenerate pada panel Edit webhook. Ini langsung membatalkan secret lama β perbarui kode verifikasi Anda sebelum melakukan regenerate, atau Anda akan menolak request yang sah sampai Anda memperbaruinya.
Menambahkan autentikasi Anda sendiri
Jika endpoint Anda sudah memerlukan autentikasi sendiri β API key statis, bearer token β tambahkan sebagai custom header saat membuat atau mengedit webhook (bagian Advanced: Custom Headers). Chatmo mengirimkannya di setiap request persis seperti yang dikonfigurasi, bersama header signature miliknya sendiri. Ini opsional; signature HMAC saja sudah cukup untuk memverifikasi bahwa request benar-benar berasal dari Chatmo dan tidak diubah di tengah jalan.
Praktik terbaik
- Simpan signing secret sama seperti Anda menyimpan kredensial lainnya β environment variable atau secrets manager, jangan pernah di source control.
- Selalu verifikasi signature sebelum melakukan apa pun dengan payload, termasuk sebelum memasukkannya ke queue pemrosesan.
- Tolak request dengan header
X-Chatmo-Signatureyang hilang atau tidak valid (401). - Rotasi secret (melalui Regenerate) jika Anda menduga secret tersebut telah bocor.
Percobaan ulang dan jaminan pengiriman
Chatmo mengirimkan webhook dengan jaminan at least once. Sebuah pengiriman akan dicoba ulang secara otomatis saat endpoint Anda tidak mengonfirmasi bahwa event tersebut diterima β artinya endpoint Anda harus bisa menangani penerimaan event yang sama lebih dari sekali dengan aman (lihat idempotency).
Jadwal percobaan ulang
| Percobaan | Waktu tunggu sebelum percobaan ini |
|---|---|
| 1 | β (langsung) |
| 2 | ~3 detik |
| 3 | ~9 detik |
| 4 | ~27 detik |
| 5 | ~81 detik |
| 6 (terakhir) | hingga 10 menit |
Setiap percobaan memiliki timeout 10 detik jika endpoint Anda tidak merespons. Waktu tunggu menyertakan sedikit jitter acak agar retry dari banyak endpoint yang gagal tidak jatuh pada infrastruktur Anda di waktu yang sama persis.
Apa yang dianggap gagal
| Endpoint Anda | Respons Chatmo |
|---|---|
Merespons 2xx dalam 10 detik | Terkirim β tidak di-retry |
Merespons 401, 403, atau 410 | Tidak di-retry β lihat respons non-retryable |
| Merespons status lain, timeout, atau koneksi gagal | Di-retry sesuai jadwal di atas |
Setelah percobaan terakhir gagal, pengiriman ditandai FAILED di log pengiriman β Anda bisa memeriksanya atau melakukan resend secara manual setelah endpoint Anda diperbaiki.
Nonaktif otomatis setelah kegagalan berulang
Jika sebuah webhook mengumpulkan 20 kali kegagalan pengiriman berturut-turut (semua percobaan dari 6 kali retry habis), Chatmo secara otomatis:
- Menonaktifkan webhook tersebut (
is_active: false). - Mencatat alasannya pada webhook.
- Mengirim notifikasi in-app, desktop, dan email ke pemilik organisasi.
Ini meniru cara Stripe dan penyedia serupa menangani endpoint yang mati β mencegah URL yang rusak permanen dicoba ulang selamanya. Satu kali pengiriman berhasil akan me-reset counter kegagalan ke nol, sehingga endpoint yang hanya sesekali bermasalah tidak akan pernah berisiko dinonaktifkan.
Untuk mengaktifkan kembali webhook yang dinonaktifkan, perbaiki masalah yang mendasarinya lalu ubah statusnya menjadi Active kembali dari panel Edit β ini juga akan me-reset counter kegagalan.
Urutan
Pengiriman ke webhook endpoint yang sama tidak dijamin tiba dalam urutan persis sesuai kejadian aslinya, terutama saat ada retry. Jika integrasi Anda bergantung pada urutan yang ketat, gunakan timestamp created_at pada event (atau timestamp resource itu sendiri di dalam data) untuk mengurutkan ulang di sisi Anda, bukan mengandalkan urutan kedatangan.
Apa yang tidak di-retry
Pengiriman yang Anda picu sendiri β test event atau resend manual β melalui jadwal retry yang sama seperti event sungguhan. Tidak ada mode "tanpa retry" terpisah untuk ini; jika Anda ingin melihat kegagalan mentah tanpa menunggu retry selesai, periksa entri log pengiriman saat percobaan masih berlangsung (status: PENDING).
