Open in
telephony.incoming / web.incoming
Blokuojanti žiniatinklio užklausa, realiuoju laiku nustatanti įeinančio skambučio konfigūraciją.
Kai įeinantis telefono skambutis pasiekia numerį be priskirto
agento arba žiniatinklio valdiklio sesija pradedama naudojant viešąjį raktą su
mode="webhook", ThunderPhone siunčia blokuojančią
telephony.incoming / web.incoming užklausą į jūsų
senąjį webhook URL
ir iki 10 sekundžių laukia konfigūracijos atsakymo. Naudokite šį
apsikeitimą, kad kiekvienam skambučiui dinamiškai pasirinktumėte raginimą, balsą ir įrankius —
visą procesą rasite dinaminės skambučio konfigūracijos vadove.
Blokuojantis apsikeitimas neturi atsarginio varianto: jei jūsų apdorotojas grąžina
ne 2xx būseną, baigiasi jo skirtasis laikas arba jis grąžina konfigūraciją, kuri
nepraeina tikrinimo, skambutis atmetamas (telefono skambutis neprisijungia;
valdiklio sesijos užklausa nepavyksta su 502/422). Atsakykite greitai —
kol nusprendžiate, skambintojas girdi skambučio signalą.
Užklausos duomenys
Telefono skambučiams (telephony.incoming):
{
"type": "telephony.incoming",
"data": {
"call_id": 987654321,
"from_number": "+14155550199",
"to_number": "+15551234567"
}
}| Laukas | Tipas | Aprašymas |
|---|---|---|
call_id | integer | Skambučio ID — nekinta visuose šio skambučio įvykiuose |
from_number | string | Skambintojo E.164 numeris |
to_number | string | E.164 paskirties numeris (vienas iš jūsų ThunderPhone numerių) |
Žiniatinklio valdiklio sesijoms (web.incoming) data identifikuoja
įterpimo puslapį, o ne telefono numerius:
{
"type": "web.incoming",
"data": {
"call_id": 987654322,
"origin_domain": "https://example.com",
"publishable_key_prefix": "pk_live_a1b2"
}
}| Laukas | Tipas | Aprašymas |
|---|---|---|
call_id | integer | Skambučio ID |
origin_domain | string | Valdiklį talpinančio puslapio kilmė |
publishable_key_prefix | string | Pirmieji viešojo rakto, kuris pradėjo sesiją, simboliai |
language, primary_language | string | Pateikiama, kai valdiklio sesijoje prašoma pakeisti kalbą |
voice | string | Pateikiama, kai valdiklio sesijoje prašoma pakeisti balsą |
website_context | string | Pateikiama, kai valdiklis perdavė vienos sesijos puslapio kontekstą |
Atsakymo schema
Grąžinkite JSON objektą, aprašantį šio skambučio agento konfigūraciją.
prompt ir voice yra privalomi; visa kita yra pasirinktinė.
{
"prompt": "You are a helpful booking assistant for Acme Restaurant.",
"voice": "john",
"product": "spark",
"background_track": null,
"tools": []
}| Laukas | Tipas | Privaloma | Aprašymas |
|---|---|---|---|
prompt | string | taip | Sisteminė instrukcija, valdanti agentą |
voice | string | taip | Balso ID iš GET /v1/voices, pvz., john. voice_name priimamas kaip alternatyvus pavadinimas. Nežinomi balsai neatitinka tikrinimo ir skambutis atmetamas |
product | string | ne | Numatytoji reikšmė yra spark. Leidžiama: spark, bolt, storm-base, storm-base-with-ack, storm-extra, storm-extra-with-ack |
thinking_level | string | ne | minimal, base (numatytoji reikšmė) arba extra. Storm produktams perrašoma: storm-extra* nustato extra, kiti storm-* nustato base |
audio_context_mode | string | ne | full (numatytoji reikšmė) arba reduced |
watchdog_enabled | boolean | ne | Įjungti šio skambučio priežiūrą. Numatytoji reikšmė false |
additional_audio_context | boolean | null | ne | Įtraukti kelis paskutinius skambintojo garso pokalbio ėjimus, o ne tik naujausią, taip pagerinant pataisymus ir duomenų, kuriuose daug raidžių ar skaičių, rinkimą, šiek tiek padidinant delsą ir kainą. Numatyta įjungta įeinantiems seansams ir išjungta išeinantiems telefono skambučiams; null palieka numatytąją reikšmę |
storm_feedback_mode | string | ne | none, acknowledgement (numatytoji reikšmė) arba tick |
language | string | ne | Trumpinys, skirtas primary_language |
primary_language | string | ne | Kalbos kodas, normalizuotas (numatytoji reikšmė en). Neišsprendžiami kodai atmeta skambutį |
has_additional_languages | boolean | ne | Numatytoji reikšmė false |
additional_languages | array of string | ne | Papildomos kalbos, į kurias agentas gali persijungti |
native_voice_switching | boolean | ne | Numatytoji reikšmė false. Skambučiui persijungus į kitą kalbą, pakeiskite balsą į tai kalbai gimtąjį balsą (atitinkantį lytį), užuot išlaikę sukonfigūruotą balsą |
background_track | string | null | ne | Aplinkos garso ID arba null |
acknowledgement_prompt_mode | string | ne | auto (numatytoji reikšmė) arba manual (Storm su patvirtinimu produktams) |
acknowledgement_prompt | string | ne | Naudojama, kai acknowledgement_prompt_mode="manual" |
silence_interval_seconds | integer | null | ne | 5–120. Skambintojo tylos sekundės iki pasiteiravimo |
silence_max_checkins | integer | null | ne | 1–10 |
silence_checkins_enabled | boolean | ne | Numatytoji reikšmė true |
connect_tone_enabled | boolean | ne | Numatytoji reikšmė false |
voicemail_action | string | ne | prompt (numatytoji reikšmė), hangup arba message |
voicemail_message | string | ne | Naudojama, kai voicemail_action="message" |
agent_name | string | ne | Rodomas pavadinimas, pateikiamas valdymo skydeliuose ir valdiklyje |
org_name | string | ne | Organizacijos rodomas pavadinimas agento personai |
tools | array | ne | Įterptinės funkcijų įrankių schemos (žr. Funkcijų įrankiai) |
call_id | integer | ne | Pasirinktinis užklausos skambučio ID atkartojimas; ignoruojamas |
Kadangi prompt ir voice yra privalomi, grąžinus {} arba bet kokį
atsakymą, kuris neatitinka tikrinimo, skambutis atmetamas su 422 —
šiuo keliu nėra statinio agento atsarginio varianto (numeris arba raktas
žiniatinklio kablio režimu neturi priskirto agento).
Atsakymo dydžio apribojimas
Apdorojimo programos pavyzdys
import hashlib
import hmac
import json
import os
from fastapi import FastAPI, HTTPException, Request
app = FastAPI()
WEBHOOK_SECRET = os.environ["THUNDERPHONE_WEBHOOK_SECRET"]
def verify(body: bytes, signature: str) -> bool:
expected = hmac.new(WEBHOOK_SECRET.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature or "")
@app.post("/thunderphone-webhook")
async def webhook(request: Request):
body = await request.body()
if not verify(body, request.headers.get("X-ThunderPhone-Signature", "")):
raise HTTPException(status_code=401)
event = json.loads(body)
if event["type"] == "telephony.incoming":
caller = event["data"]["from_number"]
prompt = (
"Greet the caller as a San Francisco local…"
if caller.startswith("+1415")
else "You are a friendly customer support agent…"
)
return {
"prompt": prompt,
"voice": "john",
"product": "spark",
}
if event["type"] == "web.incoming":
return {
"prompt": "You are the website's helpful voice assistant…",
"voice": "john",
"product": "spark",
}
return {}import crypto from "node:crypto";
import express from "express";
const app = express();
const SECRET = process.env.THUNDERPHONE_WEBHOOK_SECRET;
function verify(body, signature) {
const expected = crypto
.createHmac("sha256", SECRET)
.update(body)
.digest("hex");
return signature &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
app.post(
"/thunderphone-webhook",
express.raw({ type: "application/json" }),
(req, res) => {
if (!verify(req.body, req.header("X-ThunderPhone-Signature"))) {
return res.sendStatus(401);
}
const event = JSON.parse(req.body.toString("utf8"));
if (event.type === "telephony.incoming" || event.type === "web.incoming") {
const caller = event.data.from_number || "web";
const prompt = caller.startsWith("+1415")
? "Greet the caller as a San Francisco local…"
: "You are a friendly customer support agent…";
return res.json({
prompt,
voice: "john",
product: "spark",
});
}
res.json({});
},
);Atsakymas su funkcijų įrankiais
Pridėkite įrankius, kad dirbtinis intelektas pokalbio metu galėtų iškviesti jūsų API:
{
"prompt": "You are a booking assistant. Use the available tools to help customers schedule appointments.",
"voice": "john",
"product": "spark",
"tools": [
{
"type": "function",
"function": {
"name": "search_appointments",
"description": "Find available appointment slots",
"parameters": {
"type": "object",
"properties": {
"date": { "type": "string", "description": "YYYY-MM-DD" },
"service": { "type": "string" }
},
"required": ["date"]
}
},
"endpoint": {
"url": "https://api.example.com/appointments/search",
"method": "POST",
"headers": {
"X-Api-Key": "your-key"
}
}
}
]
}Produktų pakopų atmintinė
| Produktas | Delsa | Mąstymas | Patvirtinimas |
|---|---|---|---|
spark | Mažiausia | Pagrindinis | — |
bolt | Maža | Patobulintas | — |
storm-base | Vidutinė | Stiprus | — |
storm-base-with-ack | Vidutinė | Stiprus | Automatinė užpildo frazė mąstant |
storm-extra | Didesnė | Gilus | — |
storm-extra-with-ack | Didesnė | Gilus | Automatinė užpildo frazė mąstant |
Susiję
Neblokuojantis skambučio pabaigos įvykis.
Visa tools[] JSON schema ir pasirašyto galinio taško sutartis.
Prenumeruokite kelis URL adresus įvykiams telephony.incoming / web.incoming.
Šablonai raginimams, įrankiams ir A/B testams pagal skambinantįjį.