Skip to main content
Setiap permintaan yang kami kirim ke server Anda — pengiriman webhook dan pemanggilan endpoint tool — membawa tanda tangan HMAC-SHA256 dalam header X-ThunderPhone-Signature. Lakukan verifikasi dengan benar sekali, lalu gunakan helper yang sama di setiap handler.

Algoritme

  1. Baca body permintaan mentah — byte persis yang kami POST kepada Anda.
  2. Hitung hmac_sha256(secret, body).hexdigest().
  3. Bandingkan dalam waktu konstan dengan X-ThunderPhone-Signature. (Perbandingan string naif membocorkan informasi waktu.)
Kami menandatangani byte persis yang kami kirimkan, sehingga memverifikasi body mentah selalu berfungsi. Byte tersebut juga merupakan serialisasi JSON kanonis dari payload — kunci diurutkan secara alfabetis, pemisah ringkas (, dan : tanpa spasi), UTF-8. Ini memberi Anda resep kedua yang sepenuhnya setara ketika framework Anda hanya menyediakan JSON yang sudah diurai: serialisasikan ulang secara kanonis dan terapkan HMAC pada hasilnya.
Utamakan body mentah — ini mengurangi satu langkah dan kebal terhadap keanehan konversi bolak-balik angka JSON dalam beberapa bahasa.

Secret yang mana?

Simpan secret di pengelola secret atau variabel lingkungan Anda — jangan pernah melakukan commit.

Implementasi referensi

Keempat implementasi berikut memverifikasi body permintaan mentah:

Pengkabelan khusus framework

Memverifikasi panggilan tool

Saat agen memanggil salah satu function tool Anda secara langsung (tool tersebut memiliki endpoint), permintaan membawa dua header ThunderPhone berikut bersama endpoint.headers yang Anda konfigurasi:
  • X-ThunderPhone-Call-ID — ID numerik panggilan yang sedang berlangsung.
  • X-ThunderPhone-Signature — HMAC-SHA256, dengan kunci berupa secret webhook tingkat organisasi Anda, atas byte isi permintaan yang persis sama.
Helper verify() yang sama dapat digunakan tanpa perubahan, dengan dua perbedaan:
  1. Tool GET / DELETE tidak memiliki isi. Argumen dikirim sebagai parameter kueri, dan tanda tangan dihitung atas string byte kosong — sehingga gunakan verify(b"", sig, secret) (Python) atau verify(Buffer.alloc(0), sig, secret) (Node). Jangan melakukan hash pada string kueri.
  2. Organisasi tanpa webhook legacy yang dikonfigurasi tidak memiliki secret organisasi. Dalam kasus tersebut, panggilan tool hanya membawa X-ThunderPhone-Call-ID dan tidak ada header tanda tangan. Konfigurasikan webhook legacy (PUT /v1/webhook) untuk mendapatkan secret penandatanganan, atau autentikasi panggilan tool dengan header Anda sendiri melalui endpoint.headers.
Pengiriman tool mode-webhook (tool tanpa endpoint, dikirimkan ke webhook organisasi Anda sebagai telephony.tool / web.tool) adalah webhook bertanda tangan biasa — resep standar di atas berlaku. Lihat Function Tools untuk kedua bentuk permintaan.

Kesalahan umum

Mengurai body lalu melakukan dump ulang dengan pengaturan default library JSON Anda (spasi setelah , / :, kunci berurutan berdasarkan penyisipan) menghasilkan byte yang berbeda dan merusak HMAC. Verifikasi body mentah — atau jika Anda harus melakukan serialisasi ulang, samakan persis dengan bentuk kanonis kami: kunci diurutkan, pemisah ringkas, UTF-8.
Middleware express.json() Express menggunakan stream body sehingga Anda kehilangan byte mentah. Gunakan express.raw() khusus pada rute webhook, atau buffer body mentah dalam pre-middleware. Hal yang sama berlaku untuk NestJS / Koa — periksa dokumentasi “raw body” mereka.
expected === signature di JS atau expected == signature di Python adalah perbandingan dengan waktu yang bervariasi. Gunakan crypto.timingSafeEqual atau hmac.compare_digest secara berurutan. Perbedaan performanya tidak ada.
Panggilan endpoint tool langsung ditandatangani dengan secret webhook tingkat organisasi (GET /v1/webhook) — bukan dengan secret per-endpoint apa pun dari /v1/developer/webhook-endpoints. Gunakan kembali fungsi verify() yang sama, tetapi pastikan Anda memberinya secret organisasi pada rute tool.
Untuk metode tool tanpa body, tanda tangan mencakup string byte kosong, sehingga satu resep universal tetap digunakan: HMAC body permintaan mentah, apa pun isinya. Melakukan hash pada URL atau query string tidak akan pernah cocok.
Mengembalikan 200 saat verifikasi gagal menjadikan handler sebagai target replay. Selalu respons dengan non-2xx jika verifikasi gagal.

Langkah berikutnya

Ringkasan webhook

Semantik pengiriman, percobaan ulang, IP sumber.

Endpoint webhook

Kelola beberapa URL, rotasi secret.

Function Tools

Dua jalur pemanggilan tool dan bentuk permintaannya.

Integrasi tool

Buat integrasi lengkap yang didukung tool dari awal hingga akhir.