ThunderPhone 2.0 ir klāt.Sāciet patstāvīgi — no 2 ¢/min.Lasīt paziņojumu

Webhooks

telephony.incoming / web.incoming

Bloķējošs tīmekļa aizķeres punkts, kas reāllaikā konfigurē ienākošo zvanu.

Kad ienākošs tālruņa zvans sasniedz numuru bez piešķirta 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 veco tīmekļa aizķeres URL un gaida konfigurācijas atbildi: līdz 13 sekundēm tālruņa zvanam, ieskaitot vienu atkārtotu mēģinājumu, un līdz 10 sekundēm logrīka sesijai (skatiet Noildzes un atkārtoti mēģinājumi). Izmantojiet šo apmaiņu, lai katram zvanam dinamiski izvēlētos uzvedni, balsi un rīkus — skatiet dinamiskās zvanu konfigurācijas ceļvedi, lai iepazītos ar pilnu procesu.

Noildzes un atkārtoti mēģinājumi

Atbildiet ātri: zvanītājs gaida līnijā, kamēr pieņemat lēmumu.

Tālruņa zvanam (telephony.incoming):

  • Pirmais mēģinājums var ilgt līdz 10 sekundēm.
  • Ja tas pārsniedz noildzi, nevar izveidot savienojumu vai saņem 5xx, 408 vai 429 atbildi, ThunderPhone mēģina vēlreiz. Atkārtotajam mēģinājumam tiek piešķirts viss, kas atlicis no 13 sekunžu budžeta visai apmaiņai: aptuveni 3 sekundes pēc pirmā mēģinājuma, kam iestājās noildze, un gandrīz visas 13 sekundes pēc ātras kļūmes. Atkārtots mēģinājums netiek veikts, ja atliktu mazāk par 2 sekundēm.
  • Jebkura cita 4xx atbilde, atbilde, kas pārsniedz izmēra ierobežojumu, vai 2xx atbilde, kuras pamatteksts nav derīga konfigurācija, ir galīga un netiek atkārtota.
  • Abi mēģinājumi nosūta vienādu pamattekstu, vienādu X-ThunderPhone-Signature un vienādu X-ThunderPhone-Idempotency-Key galveni (telephony-incoming-<call_id>), tādēļ apstrādātājs ar blakusietekmēm var atpazīt atkārtoto mēģinājumu.

Nav rezerves balss aģenta. Ja netiek saņemta izmantojama konfigurācija, zvans tiek nekavējoties pārtraukts, nevis zvanītājs tiek atstāts klusā līnijā. Zvanu vēsturē tas tiek rādīts kā neveiksmīgs zvans, par kuru netiek iekasēta maksa, ar end_reason inbound_config_webhook_failed, un tiek nosūtīts parastais telephony.complete notikums.

Logrīka sesijai (web.incoming) ir viens mēģinājums, kas var ilgt līdz 10 sekundēm. Ja tas neizdodas, sesijas pieprasījums neizdodas ar 502 vai 422.

Pieprasījuma dati

Tālruņa zvaniem (telephony.incoming):

{
  "type": "telephony.incoming",
  "data": {
    "call_id":     987654321,
    "from_number": "+14155550199",
    "to_number":   "+15551234567"
  }
}
LauksTipsApraksts
call_idintegerZvanu ID — nemainīgs visos šī zvana notikumos
from_numberstringZvanītāja E.164 numurs
to_numberstringE.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"
  }
}
LauksTipsApraksts
call_idvesels skaitlisZvanu ID
origin_domainvirkneLapas izcelsme, kurā tiek mitināts logrīks, kā to nosūtīja pārlūks. Klients, kas nav pārlūks, var nosūtīt jebkuru vērtību, tāpēc neuzskatiet to par pierādījumu pieprasījuma izcelsmei
publishable_key_prefixvirknePublicējamās atslēgas, kas atvēra sesiju, pirmās rakstzīmes
language, primary_languagevirkneNorādīts, ja logrīka sesijā tika pieprasīta valodas pārrakstīšana
voicevirkneNorādīts, ja logrīka sesijā tika pieprasīta balss pārrakstīšana
website_contextvirkneNorādīts, ja logrīks pārsūtīja lapas kontekstu katrai sesijai

Pārrakstīšanas lauki (language, voice, website_context un jebkuri pārlūka variables) tiek saņemti tikai tad, ja publicējamā atslēga tos atļauj savos pārlūka pārrakstījumos. Sesijas pieprasījums, kas ietver kādu vērtību, kuru atslēga neatļauj, tiek noraidīts, pirms tiek izsaukts šis tīmekļa aizķeres punkts.


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":   []
}
LauksTipsObligātsApraksts
promptvirknejāSistēmas uzvedne, kas vada balss aģentu
voicevirknejā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
productvirknenēNoklusējuma vērtība ir spark. Atļauts: spark, bolt, storm-base, storm-base-with-ack, storm-extra, storm-extra-with-ack
thinking_levelvirknenēminimal, base (noklusējums) vai extra. Storm produktiem tiek ignorēts: storm-extra* piespiež extra, citi storm-* piespiež base
audio_context_modevirknenēfull (noklusējums) vai reduced
watchdog_enabledBūla vērtībanēIespējo šī zvana uzraudzību. Noklusējuma vērtība ir false
additional_audio_contextBūla vērtība | nullnēIekļaujiet zvanītāja audio pēdējās dažas sarunas kārtas, nevis tikai jaunāko kārtu, lai ar nelielu latentuma un izmaksu pieaugumu uzlabotu labojumus un datu apkopošanu, kurā ir daudz burtu vai skaitļu. 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_modevirknenēnone, acknowledgement (noklusējums) vai tick. Norāda arī to, ko zvanītājs dzird, kamēr audio modeļi apstrādā sarunas kārtu, ja audio_tier ir hearing
languagevirknenēSaīsinājums laukam primary_language
primary_languagevirknenēNormalizēts valodas kods (noklusējums en). Neatrisināmi kodi noraida zvanu
has_additional_languagesBūla vērtībanēNoklusējuma vērtība ir false
additional_languagesvirkņu masīvsnēPapildu valodas, uz kurām balss aģents var pārslēgties
native_voice_switchingBūla vērtībanē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)
language_switchingvirkne | nullnēask_first (noklusējums) vai follow_caller; null ir tas pats, kas ask_first. Nosaka, kā daudzvalodu balss aģents rīkojas, ja sarunas biedrs runā citā no tā valodām. ask_first uzreiz pārslēdzas, kad sarunas biedrs pieprasa valodu vai pasaka tajā pilnu teikumu, bet pēc kaut kā īsa, piemēram, "sí", jautā, vai turpināt šajā valodā. follow_caller pārslēdzas uz jebkuru konfigurēto valodu, kurā sarunas biedrs runā, pat ja tas ir tikai viens vārds. Attiecas tikai tad, ja ir iestatīts additional_languages
audio_tiervirkne | nullnēTikai product: "bolt". standard (noklusējums; "" un null nozīmē to pašu) izmanto trīs transkribētājus (zvani, kuros apstrādā PHI, izmanto tikai ar BAA segtus transkribētājus). lean samazina to līdz vienam transkribētājam, kas biežāk sadzird nepareizi. hearing paplašina standard ar jaudīgu audio modeļu kopumu, kas dažās sarunas kārtās klausās zvanītāja audio, un tas aizņem aptuveni par 1–2 sekundēm ilgāk. Citi produkti to ignorē
endpointingvirkne | nullnēfaster (200 ms), fast (300 ms), normal (500 ms, noklusējums) vai patient (800 ms); null ir tas pats, kas normal. Nosaka, cik ilgi Bolt v2 balss aģents gaida pēc tam, kad zvanītājs ir beidzis runāt, pirms lūdz modelim atbildi. Īsāka gaidīšana var ļaut atbildēt ātrāk, bet nosūta vairāk pieprasījumu, kurus zvanītāja nākamie vārdi padara novecojušus, tādējādi palielinot modeļa izmaksas. Citi produkti to ignorē
eagernessvirkne | nullnēNovecojis: endpointing nosaukums līdz 2026. gada 19. oktobrim, joprojām tiek nolasīts. Tiek ignorēts, ja ir iestatīts endpointing
intelligencevirkne | nullnēexpress, lite vai standard (noklusējums); null ir tas pats, kas standard. bolt balss aģenta intelekta līmenis Bolt v2 procesā: kurš modelis raksta tā atbildes. express līdz pirmajam vārdam aizņem ~600 ms, ir lētāks par standarta režīmu un vismazāk uzticami ievēro norādījumus; lite aizņem ~900 ms, ir lētākais un mazāk uzticams; standard aizņem ~900 ms un vislabāk ievēro norādījumus. Express un Lite atbildes, kas tikai izsauktu rīku, tiek nodotas Standard modelim. Citi produkti to ignorē
background_trackvirkne | nullnēApkārtējās skaņas audio ID vai null
acknowledgement_prompt_modevirknenēauto (noklusējums) vai manual (Storm-with-ack produktiem)
acknowledgement_promptvirknenēTiek izmantots, ja acknowledgement_prompt_mode="manual"
silence_interval_secondsvesels skaitlis | nullnē5–120. Zvanītāja klusuma sekundes pirms statusa pārbaudes
silence_max_checkinsvesels skaitlis | nullnē1–10
silence_checkins_enabledBūla vērtībanēNoklusējuma vērtība ir true
silence_final_actionvirknenēPēc pēdējās statusa pārbaudes: hang_up (noklusējums) vai transfer uz silence_transfer_destination
silence_transfer_destinationvirknenēIeraksta nosaukums šīs konfigurācijas transfer_destinations; nepieciešams kopā ar transfer. Bez transfer_destinations savienojumu nevar pārsūtīt, un balss aģents pārtrauc zvanu
silence_final_messagevirknenē≤ 300 rakstzīmes, tiek nolasīts tieši kā uzrakstīts; "" (noklusējums) izmanto noklusējuma tekstu
connect_tone_enabledBūla vērtībanēNoklusējuma vērtība ir false
pronunciation_dictsBūla vērtība | nullnēNoklusējuma vērtība ir false; null ir tas pats, kas false. Ja vērtība ir true, zvana Cartesia runa izmanto ThunderPhone izrunas vārdnīcu zvana valodai, ja tāda pastāv. Darbojas tālruņa un logrīka zvaniem. Attiecas tikai uz ThunderPhone pašu Cartesia balsīm, nevis balsīm, kas izmanto jūsu Cartesia API atslēgu. Netiek izmantots ar agent_id, kur tiek piemēroti saglabātā balss aģenta iestatījumi
voicemail_actionvirknenēprompt (noklusējums), hangup vai message
voicemail_messagevirknenēTiek izmantots, ja voicemail_action="message"
agent_namevirknenēParādāmais nosaukums, kas tiek rādīts informācijas paneļos un logrīkā
org_namevirknenēOrganizācijas parādāmais nosaukums balss aģenta personai
toolsmasīvsnēIekļautas funkciju rīku shēmas (skatiet Funkciju rīki)
transfer_destinationsobjektu masīvs | nullnēLīdz 50 {name, number} ierakstiem, uz kuriem šis zvans var pārsūtīt savienojumu; tie tiek validēti tāpat kā balss aģenta pārsūtīšanas numuri. Balss aģents pārsūta savienojumu pēc nosaukuma un tikai uz šiem ierakstiem; [] nozīmē, ka pārsūtīšana nav pieejama. Izlaidiet šo lauku vai nosūtiet null, lai ļautu balss aģentam pārsūtīt savienojumu uz tā izvēlētu numuru
timezonevirknenēŠī zvana IANA laika josla, piemēram, America/Chicago. Balss aģents tajā norāda datumu un laiku, nevis izmanto savu laika joslu. Atļauts arī līdzās agent_id. Vērtības, kas nav IANA joslas, tiek ignorētas. Skatiet Iestatiet laika joslu katram zvanam
call_idvesels skaitlisnēNeobligāta pieprasījuma zvana ID atbalss; tiek ignorēta

Tā kā prompt un voice ir obligāti, {} vai jebkura atbilde, kas neiztur validāciju, noraida zvanu: tālruņa zvans tiek beigts, kā aprakstīts sadaļā Noildzes un atkārtoti mēģinājumi, un logrīka sesijas pieprasījums neizdodas ar 422. Šajā ceļā nav rezerves statiskā balss aģenta (numuram vai atslēgai tīmekļa aizķeres režīmā nav piešķirta balss aģenta).


Atbildes lieluma ierobežojums


Apstrādātāja piemērs

Python (FastAPI)
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 {}
Node.js (Express)
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

ProduktsLatenceSpriešanaApstiprinājums
sparkZemākāPamata—
boltZemaUzlabota—
storm-baseVidējaSpēcīga—
storm-base-with-ackVidējaSpēcīgaAutomātisks aizpildījums domāšanas laikā
storm-extraAugstākaPadziļināta—
storm-extra-with-ackAugstākaPadziļinātaAutomātisks aizpildījums domāšanas laikā

Saistītie materiāli