Sign inGet Started

Menggunakan data aplikasi dalam sequence suara

Gunakan voice.webhook saat aplikasi Anda menyimpan data yang dibutuhkan panggilan, misalnya status pesanan, tim, atau konfirmasi janji temu. Langkah ini mengembalikan data tersebut di success, lalu langkah Branch berikutnya memilih jalur berdasarkan data itu.

Menentukan respons

Atur config.output_schema ke skema objek untuk data yang dikembalikan. Langkah ini memiliki dua output: success membawa data sesuai skema tersebut, dan failure menangani masalah teknis. Jika konfigurasi tidak diisi, output-nya berupa objek kosong.

Input berisi HTTPS url statis dan data opsional berupa objek. Data mendukung objek literal, $literal, atau $expr untuk seluruh objek. URL dinamis, header buatan sendiri, dan kredensial tidak didukung.

Memverifikasi permintaan

Bird menandatangani setiap permintaan, termasuk continuation, dengan secret callback workspace Anda menggunakan header Standard Webhooks: webhook-id, webhook-timestamp, dan webhook-signature. Tanda tangan mencakup ID, timestamp, dan body persis. Selama 24 jam setelah rotasi secret, webhook-signature berisi satu entri v1, untuk setiap secret aktif, sehingga kedua secret dapat memverifikasi. Panggilan dapat membutuhkan sekitar satu menit sebelum mulai menandatangani dengan secret baru, jadi tetap terima secret sebelumnya sampai masa tumpang tindih berakhir. Respons Anda tidak ditandatangani: Bird memvalidasi sertifikat TLS penerima Anda, dan koneksi HTTPS mengautentikasi data yang dikembalikannya.

Verifikasi header terhadap body mentah dengan fungsi verify dari library Standard Webhooks sebelum melakukan parsing. webhooks.unwrap di SDK mem-parsing event platform dan tidak ditujukan untuk permintaan ini. Rotasi secret terlebih dahulu di Webhooks → Direct callbacks, karena secret awal tidak pernah ditampilkan. Tanda tangan menunjukkan bahwa pemegang secret workspace Anda telah menandatangani permintaan. Penerima callback SMS Anda memegang secret yang sama dan juga dapat menandatangani, jadi simpan secret hanya di penerima yang Anda percayai. Siapa pun yang dapat mengedit sequence di workspace dapat memilih URL dan data. Periksa bahwa target_url adalah URL Anda sendiri untuk menolak permintaan yang ditandatangani Bird untuk penerima lain, dan lakukan otorisasi tindakan bisnis di penerima Anda. Otorisasi pelanggan tidak pernah diteruskan.

Permintaan webhook sequence tidak menyertakan sertifikat klien, meskipun workspace Anda mewajibkan mTLS. Konfigurasikan penerima agar menerima koneksi tanpa sertifikat klien, lalu autentikasi permintaan yang ditandatangani sebagai gantinya.

Periksa webhook-timestamp yang ditandatangani, yaitu timestamp Unix dalam detik, terhadap jam server yang tersinkronisasi. Tolak permintaan yang lebih dari lima menit di masa lalu atau masa depan. Lakukan deduplikasi berdasarkan webhook-id sebelum menjalankan efek samping. Jika memungkinkan, simpan ID dan hasilnya secara atomik bersama tindakan tersebut, lalu kembalikan hasil yang tersimpan untuk permintaan berulang. Setiap continuation memiliki ID sendiri. Gunakan kunci idempotensi bisnis terpisah jika permintaan yang berbeda tidak boleh mengulangi tindakan yang sama.

Mengembalikan data

Penerima mengembalikan bentuk respons tertutup berikut:

Contoh kode
{
  "schema_version": 1,
  "type": "outcome",
  "output": { "status": "confirmed", "message": "Your appointment is confirmed." }
}

output harus sesuai dengan skema yang dikonfigurasi. Respons mengembalikan data, bukan port, ID node, atau perintah baru. Continuation berupa {"schema_version":1,"type":"continue","url":"https://example.com/voice/next"} pada origin kanonis dari URL asli.

Untuk merutekan berdasarkan data, hubungkan success ke langkah logic.branch dengan kasus seperti steps.decision.output.status == 'confirmed'. Deklarasikan field tersebut sebagai string enum dalam skema agar receiver hanya dapat mengembalikan nilai-nilai tersebut.

Permintaan berisi identitas run/sesi/panggilan, identitas sequence dan node yang diterima, data Anda yang telah dimaterialisasi, serta results. Simpan input bisnis di data. Hasil Gather privat langsung dapat muncul satu kali di results, dan rekaman yang sudah selesai membawa ID jika tersedia. Observasi ini tidak otomatis menjadi field ekspresi.

Membaca permintaan receiver

Run uji draf mengirim bentuk berikut. ID dan timestamp di bawah ini fiktif; permintaan sebenarnya menggunakan run yang diterima dan kemunculan node saat ini:

Contoh kode
{
  "schema_version": 1,
  "method": "POST",
  "target_url": "https://example.com/decision",
  "run_id": "vsr_01k5yb7p000000000000000000",
  "sequence": {
    "id": "vsq_01k5yb7p000000000000000000",
    "version_id": null,
    "draft_revision": 1,
    "entry_node_id": "start",
    "mode": "test"
  },
  "session_id": "vcs_01k5yb7p000000000000000000",
  "call": { "id": "vcl_01k5yb7p000000000000000000", "orig": null, "dest": null },
  "node": { "id": "decision", "occurrence_id": "00000000-0000-4000-8000-000000000001" },
  "data": { "appointment_id": "appointment_123" },
  "results": []
}

Untuk run yang dipublikasikan, version_id mengidentifikasi versi yang dipilih dan draft_revision bernilai null. Untuk panggilan yang menjalankan definisi inline, id, version_id, dan draft_revision semuanya bernilai null. mode dapat berupa test atau production. Asal dan tujuan menggunakan objek pihak panggilan yang dapat bernilai null. Verifikasi tanda tangan sebelum memercayai field identitas ini.

Observasi Gather di results memiliki type: "gather", node_id, UUID command_id, digits, dan reason. Observasi rekaman memiliki type: "recording", UUID command_id, state, dan recording_id jika tersedia. Gunakan digit privat hanya untuk permintaan yang dituju; digit tersebut tidak menjadi output ekspresi yang disimpan. Permintaan lanjutan mempertahankan kemunculan node yang sama, dengan observasi yang sudah dikirim dihapus dari results.

Menangani kegagalan

Sampel teknis menggunakan port failure dengan {"code":"webhook_unavailable"} atau {"code":"webhook_invalid_response"}. Kegagalan yang terhubung mengikuti jalur pemulihan; kegagalan yang tidak terhubung menggagalkan run. success yang tidak terhubung mengakhiri run secara normal. Permintaan webhook live memiliki batas waktu tiga detik dan tidak dicoba lagi secara otomatis. Preview tidak mengirim permintaan.

Batas waktu tiga detik tersebut mencakup waktu membaca kunci rahasia penandatanganan. Hubungkan failure ke jalur pemulihan agar panggilan dapat berlanjut saat receiver tidak tersedia atau mengembalikan respons yang tidak valid. Permintaan yang habis waktunya mungkin sudah memicu efek samping di receiver.

Perlakukan data, identitas panggilan, dan digit Gather sebagai data privat. Batasi akses ke receiver dan kunci rahasia, hindari mencatat body atau kunci rahasia ke log, dan simpan input penelepon hanya selama aplikasi Anda membutuhkannya. Jangan masukkan data privat atau kredensial ke URL, karena jejak panggilan menyimpan URL lengkap beserta query-nya. URL dan data yang Anda tulis serta output yang telah divalidasi disimpan dalam riwayat run; digit Gather sementara tidak disertakan dalam input langkah yang direkam. Kembalikan hanya data yang dibutuhkan sequence.

Baca data yang dikembalikan di steps.decision.output, dan baca kesalahan teknis di steps.decision.error.code. Jika kedua jalur bertemu, periksa wrapper dengan has(steps.decision.output) atau has(steps.decision.error) sebelum menggunakannya. Respons HTTP 200 dari receiver Anda belum berarti hasilnya valid sampai body-nya lolos kontrak.

Lanjutkan dengan dokumentasi, panduan, dan contoh untuk topik ini.