telephony.incoming / web.incoming
Bloķējošs tīmekļa aizķeres punkts, kas reāllaikā konfigurē ienākošo zvanu.
Kad ienākošais tālruņa zvans sasniedz numuru bez piesaistīta
balss aģenta vai tīmekļa logrīka sesija tiek sākta ar publicējamu atslēgu režīmā
mode="webhook", ThunderPhone nosūta bloķējošu
telephony.incoming / web.incoming pieprasījumu uz jūsu
mantoto webhook URL
un gaida līdz 10 sekundēm konfigurācijas atbildi. Izmantojiet šo
apmaiņu, lai katram zvanam dinamiski izvēlētos uzvedni, balsi un rīkus —
pilnu procesu skatiet dinamiskās zvanu konfigurācijas ceļvedī.
Bloķējošajai apmaiņai nav rezerves varianta: ja jūsu apstrādātājs atgriež
ne-2xx statusu, pārsniedz noildzi vai atgriež konfigurāciju, kas neiztur
validāciju, zvans tiek noraidīts (tālruņa zvans netiek savienots; logrīka
sesijas pieprasījums neizdodas ar 502/422). Atbildiet ātri — kamēr
pieņemat lēmumu, zvanītājs dzird atzvana signālu.
Pieprasījuma dati
Tālruņa zvaniem (telephony.incoming):
{
"type": "telephony.incoming",
"data": {
"call_id": 987654321,
"from_number": "+14155550199",
"to_number": "+15551234567"
}
}| Lauks | Tips | Apraksts |
|---|---|---|
call_id | integer | Zvanu ID — nemainīgs visos šī zvana notikumos |
from_number | string | Zvanītāja E.164 numurs |
to_number | string | E.164 galamērķis (viens no jūsu ThunderPhone numuriem) |
Tīmekļa logrīka sesijām (web.incoming) data tālruņa numuru vietā
identificē iegulšanas lapu:
{
"type": "web.incoming",
"data": {
"call_id": 987654322,
"origin_domain": "https://example.com",
"publishable_key_prefix": "pk_live_a1b2"
}
}| Lauks | Tips | Apraksts |
|---|---|---|
call_id | integer | Zvanu ID |
origin_domain | string | Lapas avots, kurā tiek mitināts logrīks |
publishable_key_prefix | string | Publicējamās atslēgas pirmās rakstzīmes, kas atvēra sesiju |
language, primary_language | string | Pieejams, ja logrīka sesija pieprasīja valodas pārrakstīšanu |
voice | string | Pieejams, ja logrīka sesija pieprasīja balss pārrakstīšanu |
website_context | string | Pieejams, ja logrīks nodeva katras sesijas lapas kontekstu |
Atbildes shēma
Atgrieziet JSON objektu, kas apraksta balss aģenta konfigurāciju šim zvanam.
prompt un voice ir obligāti; viss pārējais nav obligāts.
{
"prompt": "You are a helpful booking assistant for Acme Restaurant.",
"voice": "john",
"product": "spark",
"background_track": null,
"tools": []
}| Lauks | Tips | Obligāts | Apraksts |
|---|---|---|---|
prompt | string | jā | Sistēmas uzvedne, kas vada balss aģentu |
voice | string | jā | Balss ID no GET /v1/voices, piemēram, john. voice_name tiek pieņemts kā aizstājvārds. Nezināmas balsis neiztur validāciju un zvans tiek noraidīts |
product | string | nē | Noklusējuma vērtība ir spark. Atļautās vērtības: spark, bolt, storm-base, storm-base-with-ack, storm-extra, storm-extra-with-ack |
thinking_level | string | nē | minimal, base (noklusējums) vai extra. Storm produktiem tiek ignorēts: storm-extra* piespiež extra, citi storm-* piespiež base |
audio_context_mode | string | nē | full (noklusējums) vai reduced |
watchdog_enabled | boolean | nē | Iespējojiet šī zvana uzraudzību. Noklusējuma vērtība ir false |
additional_audio_context | boolean | null | nē | Iekļaujiet pēdējos dažus zvanītāja audio dialoga posmus, nevis tikai pēdējo posmu, tādējādi uzlabojot labojumus un datu vākšanu, kurā ir daudz pareizrakstības vai ciparu, ar nelielu latentuma un izmaksu pieaugumu. Ienākošajām sesijām pēc noklusējuma ir ieslēgts, bet izejošajiem tālruņa zvaniem — izslēgts; null saglabā noklusējuma vērtību |
storm_feedback_mode | string | nē | none, acknowledgement (noklusējums) vai tick |
language | string | nē | Saīsinājums laukam primary_language |
primary_language | string | nē | Valodas kods, normalizēts (noklusējums en). Neatrisināmi kodi zvanu noraida |
has_additional_languages | boolean | nē | Noklusējuma vērtība ir false |
additional_languages | string masīvs | nē | Papildu valodas, uz kurām balss aģents var pārslēgties |
native_voice_switching | boolean | nē | Noklusējuma vērtība ir false. Kad zvans pārslēdzas uz citu valodu, konfigurētās balss vietā izmantojiet šai valodai dzimto balsi (atbilstoši dzimumam) |
background_track | string | null | nē | Fona audio ID vai null |
acknowledgement_prompt_mode | string | nē | auto (noklusējums) vai manual (Storm-with-ack produktiem) |
acknowledgement_prompt | string | nē | Tiek izmantots, ja acknowledgement_prompt_mode="manual" |
silence_interval_seconds | integer | null | nē | 5–120. Zvanītāja klusuma sekunžu skaits pirms saziņas pārbaudes |
silence_max_checkins | integer | null | nē | 1–10 |
silence_checkins_enabled | boolean | nē | Noklusējuma vērtība ir true |
connect_tone_enabled | boolean | nē | Noklusējuma vērtība ir false |
voicemail_action | string | nē | prompt (noklusējums), hangup vai message |
voicemail_message | string | nē | Tiek izmantots, ja voicemail_action="message" |
agent_name | string | nē | Parādāmais vārds, kas tiek rādīts informācijas paneļos un logrīkā |
org_name | string | nē | Organizācijas parādāmais nosaukums balss aģenta personībai |
tools | array | nē | Iekļautās funkciju rīku shēmas (skatiet Funkciju rīki) |
call_id | integer | nē | Neobligāta pieprasījuma zvana ID atbalss; tiek ignorēta |
Tā kā prompt un voice ir obligāti, atgriežot {} vai jebkuru
atbildi, kas neiztur validāciju, zvans tiek noraidīts ar 422 — šajā
ceļā nav statiska balss aģenta atkāpšanās varianta (numuram vai atslēgai
tīmekļa āķa režīmā nav piešķirts balss aģents).
Atbildes lieluma ierobežojums
Apstrādātāja piemērs
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({});
},
);Atbilde ar funkciju rīkiem
Pievienojiet rīkus, lai AI varētu izsaukt jūsu API sarunas laikā:
{
"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"
}
}
}
]
}Produkta līmeņu īsā atsauce
| Produkts | Latence | Spriešana | Apstiprinājums |
|---|---|---|---|
spark | Zemākā | Pamata | — |
bolt | Zema | Uzlabota | — |
storm-base | Vidēja | Spēcīga | — |
storm-base-with-ack | Vidēja | Spēcīga | Automātisks aizpildījums domāšanas laikā |
storm-extra | Augstāka | Padziļināta | — |
storm-extra-with-ack | Augstāka | Padziļināta | Automātisks aizpildījums domāšanas laikā |
Saistītie materiāli
Nebloķējošs zvana beigu notikums.
Pilna JSON shēma tools[] un parakstītā galapunkta līgumam.
Abonējiet vairākus URL adresēm telephony.incoming / web.incoming.
Modeļi uzvednēm, rīkiem un A/B testiem katram zvanītājam.