Perilaku pengiriman
Payload standar, batas waktu 5 detik, alasan tidak ada percobaan ulang, dan arti setiap status pengiriman.
Mekanisme pengiriman webhook sengaja dibuat sederhana, dan kesederhanaan ini memiliki konsekuensi bagi penerima Anda: satu percobaan HTTP, lima detik, tanpa percobaan ulang. Baca halaman ini sebelum menentukan seberapa banyak pekerjaan yang dijalankan langsung oleh handler Anda.
Payload standar
Setiap peristiwa kecuali listing.submission diterima dengan struktur tingkat teratas yang sama, dengan field khusus peristiwa tersebut di dalam data.
{ "event": "connection.location_connected", "timestamp": "2026-08-25T14:32:10Z", "account_id": 11073, "location_id": "279381", "data": { "platform": "google", "connected_account_id": "ba03bc4b-9f8c-4d3b-8e93-9628034c63cc" }}Field opsional di dalam data tidak disertakan jika kosong, alih-alih dikirim sebagai null. Tulis kode yang mengantisipasi kondisi ini: perlakukan key yang tidak ada dan nilai null yang diberikan secara eksplisit dengan cara yang sama, dan jangan pernah menganggap key yang didokumentasikan sebagai opsional akan selalu ada.
Dua pengecualian
Batas waktu 5 detik
Setiap pengiriman berupa satu POST dengan batas waktu koneksi 5 detik dan batas waktu pembacaan 5 detik. Jika endpoint Anda belum merespons dalam waktu yang ditentukan, percobaan dihentikan dan dicatat sebagai timeout.
Batas waktu tersebut mencakup seluruh proses handler Anda. Satu-satunya rancangan yang aman adalah:
- Verifikasi tanda tangan.
- Simpan payload di penyimpanan persisten: antrean, tabel, atau log.
- Kembalikan
200.
Semua pekerjaan lainnya (pengayaan data, pendistribusian ke beberapa tujuan, pemanggilan kembali REST API, atau apa pun yang melibatkan pihak ketiga) harus dilakukan setelah data diambil dari antrean tersebut.
Tidak ada percobaan ulang
Pengiriman dicoba tepat satu kali. Tidak ada backoff, antrean percobaan ulang, ataupun dead-letter queue. Jika endpoint Anda tidak tersedia selama dua menit, peristiwa yang dipicu dalam dua menit tersebut akan hilang. Peristiwa tersebut tidak akan diterima kemudian.
Dua konsekuensi yang perlu dijelaskan secara tegas:
- Pengalihan tidak diikuti. Pengalihan dinonaktifkan sepenuhnya, sehingga
301atau302dari endpoint Anda dicatat sebagai pengiriman yang gagal, tanpa mengikuti pengalihan ke URL kedua. Konfigurasikan URL webhook Anda sebagai URL akhir. Perhatikan pengalihan dari domain tanpa subdomain kewwwdan pengalihan yang menambahkan garis miring di akhir URL, yang ditambahkan secara default oleh banyak server web. - Hanya
2xxyang dianggap berhasil dikirim.3xx,4xx, dan5xxsemuanya dicatat sebagai kegagalan.
Duplikasi dan urutan
- Anda mungkin menerima event yang sama dua kali, serta id yang sama untuk dua perubahan berbeda. Pengidentifikasi di dalam
data(id interaksi, id item postingan, id akun terhubung) mengidentifikasi sumber daya, bukan perubahannya.interaction.reviewdipicu kembali dengan id interaksi yang sama setiap kali ulasan berubah, dan tidak ada payload yang memuat versi atau field waktu pembaruan, sehingga handler yang secara permanen mengabaikan event berdasarkan id +eventakan membuang perubahan yang sebenarnya tanpa diketahui. Sebagai gantinya, deteksi duplikat yang persis sama: hitung hash dari byte mentah body dan abaikan pengulangan hash yang sama dalam rentang waktu singkat yang dibatasi (hitungan menit, bukan selamanya). Body yang berbeda untuk id yang sama merupakan perubahan baru, bukan duplikat. Kemudian baca kembali sumber daya dari REST API dan gunakan hasil pembacaan tersebut sebagai acuan utama; gunakan id sumber daya sebagai kunci saat menulis, alih-alih melewatkan penulisan. - Urutan tidak dijamin, dan
timestamptidak akan mengatasinya. Event berasal dari beberapa jalur independen dan dikirim sesuai waktu kedatangannya, sehinggalocal_post.publisheddapat tiba sebelumlocal_post.createdyang Anda harapkan tiba lebih dahulu. Jangan mengurutkan dua perubahan pada sumber daya yang sama berdasarkantimestamp: waktu tersebut dicatat saat pengiriman disiapkan, bukan saat perubahan terjadi, dan tidak ada versi atau nomor urut di bagian mana pun dalam payload. Jika urutan penting, baca kembali sumber daya dan gunakan hasil yang dikembalikan API. profile.updateddibatasi dengan debounce menjadi satu pengiriman per lokasi per 60 detik, pada awal rentang waktu. Mekanisme ini benar-benar menggabungkan beberapa perubahan menjadi satu pengiriman, bukan menundanya: perubahan pertama membuka rentang waktu dan dikirim, setiap perubahan dalam rentang tersebut dibuang dan tidak pernah tiba, danchanged_fieldshanya menjelaskan perubahan yang membuka rentang tersebut. Karena itu, event sampai kepada Anda pada awal rentang waktu, sehingga pembacaan ulang yang dipicu oleh kedatangannya hanya dapat melihat perubahan pertama tersebut. Jadwalkan pembacaan ulang kedua setelah rentang waktu berakhir, setidaknya 60 detik setelah event, dan lakukan juga rekonsiliasi lokasi secara berkala, karena notifikasi itu sendiri dapat hilang: hanya satu upaya, tanpa percobaan ulang. Debounce tidak diterapkan pada hal lainnya.
Pemulihan dari event yang terlewat
Tidak ada percobaan ulang maupun pemutaran ulang, sehingga setiap kelompok event memerlukan pembacaan dari sumber acuan utama yang dapat Anda gunakan sebagai cadangan. Lakukan rekonsiliasi secara terjadwal, bukan hanya saat ada sesuatu yang tampak salah.
Hasil pengiriman
Setiap upaya pengiriman, termasuk yang tidak pernah mengirimkan permintaan keluar dari sistem, dicatat dengan status. Berikut adalah string persisnya.
Daftar periksa penerima
- Verifikasi tanda tangan pada setiap permintaan; kembalikan
401dan jangan proses apa pun jika tanda tangan tidak cocok. - Hitung hash dari byte mentah isi permintaan, jangan pernah dari objek yang diserialisasi ulang.
- Kembalikan
2xxdalam waktu jauh di bawah 5 detik; masukkan pekerjaan ke antrean. - Gunakan ID di dalam
datasebagai kunci untuk setiap operasi tulis handler agar pengulangan menghasilkan hasil yang sama, tetapi jangan pernah menganggap ID yang berulang berarti tidak ada yang perlu dikerjakan. - Jangan simpulkan urutan dari urutan kedatangan, dan jangan urutkan berdasarkan
timestamp. - Normalisasikan
location_idmenjadi string saat diterima. - Abaikan nilai
eventyang tidak Anda kenali, dan tetap kembalikan200. - Layani URL webhook sebagai URL akhir, tanpa pengalihan.
- Lakukan rekonsiliasi secara berkala dengan REST API; tidak ada percobaan ulang yang dapat memulihkan pengiriman yang gagal.