Ikhtisar
Terima event TicketWave sebagai permintaan HTTP bertanda tangan di aplikasi Anda sendiri.
Webhooks
Webhook adalah permintaan HTTP yang TicketWave kirim kepada Anda. Setiap kali sesuatu terjadi di server Anda — tiket dibuka, anggota masuk daftar hitam — TicketWave melakukan POST body JSON ke URL milik Anda.
Itulah perbedaannya dengan Log Channels: log channels menulis embed ke Discord agar dibaca manusia, sedangkan webhook menyerahkan event mentah ke kode Anda.
Webhook adalah fitur premium. Tanpa premium, endpoint tidak dapat dibuat dan tidak ada event yang dikirim.
Create an Endpoint
Open the endpoints page
Server dashboard → Webhooks → Endpoints.
Add an endpoint
Klik Add Endpoint dan isi dua field berikut:
| Field | Description |
|---|---|
| Endpoint URL | URL https:// yang menerima permintaan |
| Event Types | Event apa saja yang harus diterima endpoint ini |
Sebuah endpoint hanya menerima jenis yang Anda centang. Memilih tidak ada sama sekali tidak diperbolehkan — pilih setidaknya satu.
Copy the signing secret
TicketWave menghasilkan signing secret (whsec_…) tepat saat endpoint dibuat. Buka daftar endpoint, tampilkan dengan ikon mata, lalu salin ke konfigurasi aplikasi Anda.
Perlakukan secret seperti kata sandi. Siapa pun yang memilikinya dapat memalsukan permintaan yang lolos pemeriksaan signature Anda. Simpan di environment variable, jangan pernah di repository Anda.
Send a test event
Gunakan tombol Send test event (pesawat kertas) pada baris endpoint. Tombol ini mengirim permintaan nyata yang sepenuhnya ditandatangani dengan "test": true di payload, sehingga Anda bisa memastikan penerima Anda berfungsi sebelum ada tiket sungguhan yang bergantung padanya.
Hasilnya akan muncul di riwayat Webhooks seperti pengiriman lainnya.
Endpoint Requirements
| Requirement | Detail |
|---|---|
| Scheme | Hanya https:// — http:// ditolak |
| Host | Harus dapat di-resolve secara publik. Alamat private, loopback, link-local, dan CGNAT ditolak |
| Response | Status 2xx apa pun dihitung sebagai sukses |
| Timeout | Anda punya 10 detik untuk merespons |
| Redirects | Tidak diikuti. 3xx dihitung sebagai kegagalan |
| Limit | Maksimal 5 endpoint per server |
Pemeriksaan host dilakukan saat Anda menyimpan endpoint dan sebelum setiap pengiriman, jadi domain yang kemudian mulai mengarah ke alamat internal akan berhenti menerima pengiriman.
The Request
Setiap pengiriman adalah POST dengan body JSON.
Headers
| Header | Example | Meaning |
|---|---|---|
Content-Type | application/json | Selalu JSON |
User-Agent | TicketWave-Webhooks/1.0.5 | Versi bot yang mengirimnya |
X-TicketWave-Event | ticket.created | Jenis event |
X-TicketWave-Delivery | wh_3f2a… | Id unik untuk pengiriman ini |
X-TicketWave-Timestamp | 1786224191 | Detik Unix, bagian dari signature |
X-TicketWave-Signature | sha256=9f86d0… | HMAC dari request |
Body
Setiap payload menggunakan envelope yang sama. Hanya data yang berbeda untuk tiap jenis event:
{
"event": "ticket.created",
"timestamp": "2026-08-26T08:23:11.000Z",
"guild_id": "123456789012345678",
"data": {
"ticket_id": "ticket-1042",
"ticket_num_id": 1042,
"channel_id": "998877665544332211",
"category": "🤖 Support",
"user": { "id": "987654321098765432", "username": "Luna" },
"created_at": "2026-08-26T08:23:11.000Z"
}
}Lihat Event Reference untuk objek data dari setiap tipe.
Verifying the Signature
Siapa pun yang mengetahui URL endpoint Anda dapat mengirim permintaan POST ke sana. Signature adalah cara Anda membedakan pengiriman TicketWave yang asli dari yang dipalsukan.
Selalu verifikasi. Endpoint yang tidak diverifikasi dan membuat atau menutup sesuatu di sistem Anda adalah pintu terbuka.
How the signature is built
TicketWave menggabungkan timestamp dan body request mentah dengan tanda titik, lalu menjalankan HMAC-SHA256 atas hasilnya menggunakan secret endpoint Anda:
signed_payload = X-TicketWave-Timestamp + "." + raw_request_body
signature = HMAC_SHA256(signed_payload, your_endpoint_secret)Header membawa digest itu dalam bentuk hex dan dengan prefiks: sha256=<digest>.
What your receiver must do
Baca raw body. Verifikasi terhadap byte persis yang Anda terima. Jika framework Anda mem-parse JSON terlebih dahulu lalu Anda melakukan re-serialisasi, urutan key atau spasi bisa berubah dan digest tidak akan cocok.
Hitung ulang HMAC atas timestamp + "." + rawBody dengan secret Anda.
Bandingkan dalam constant time (crypto.timingSafeEqual di Node). === biasa membocorkan informasi timing.
Periksa timestamp masih baru — toleransi lima menit adalah default yang baik. Timestamp berada di dalam signed payload, jadi penyerang tidak bisa memutar ulang request lama dengan timestamp baru.
Implementasi lengkap ada di halaman Example Server.
Retries
Pengiriman yang gagal akan dicoba ulang secara otomatis.
| Attempts | 3 (percobaan pertama plus 2 retry) |
| Backoff | 1 detik, lalu 5 detik |
| Retried on | Error jaringan, timeout, 408, 429, dan semua 5xx |
| Not retried on | Semua 4xx lainnya — itu berarti endpoint Anda sengaja menolak request |
Karena retry, endpoint Anda bisa menerima event yang sama dua kali. Gunakan X-TicketWave-Delivery sebagai idempotency key: simpan id yang sudah Anda proses dan abaikan pengulangan.
Pengiriman tidak berurutan. Jika dua tiket dibuat pada saat yang sama, request bisa datang dalam urutan apa pun — gunakan field timestamp di body jika urutan penting bagi Anda.
Delivery History
Halaman Webhooks di dashboard menampilkan setiap pengiriman beserta status, response code, durasi, dan jumlah percobaan. Buka sebuah baris untuk melihat payload request persis yang dikirim dan response yang dikembalikan server Anda.
Pengiriman yang gagal dapat dikirim ulang dari halaman detail dengan Retry Webhook. Fitur ini mengirim lagi payload asli ke endpoint yang sama dan mencatat pengiriman baru.
Riwayat disimpan selama 30 hari, lalu dibersihkan secara otomatis.
Troubleshooting
| Problem | Fix |
|---|---|
| Endpoint tidak dapat disimpan | URL harus https:// dan resolve ke alamat publik |
| Semuanya terlihat gagal tanpa response code | Request tidak pernah sampai ke Anda — timeout, kegagalan DNS, atau connection refused |
| Signature tidak pernah cocok | Anda melakukan hashing pada body yang sudah diparse, bukan byte mentah, atau lupa prefiks timestamp + "." |
| Pengiriman berhenti setelah beberapa saat | Periksa apakah host Anda mulai mengembalikan 4xx — itu tidak di-retry |
| Sebuah event tidak pernah datang | Endpoint tidak berlangganan ke tipe itu, atau server kehilangan premium |
| Event duplikat | Diharapkan saat retry — deduplikasi berdasarkan X-TicketWave-Delivery |
Next Steps
- Event Reference (Setiap event dan payload-nya)
- Example Server (Penerima Express yang bisa dijalankan)
- Log Channels (Event yang sama, tetapi diposting ke Discord)
How is this guide?
