Open in
Dünaamiline kõnepõhine seadistamine
Vali vastav häälagent või kirjuta selle juhis ja seaded ümber iga sissetuleva kõne jaoks eraldi, lähtudes sinu hallatavas veebikonksus olevast kohandatud loogikast.
Vaikimisi on igale telefoninumbrile ja avaldatavale võtmele määratud staatiline agent. Kui vajad helistajapõhist või külastajapõhist kohandamist — VIP-marsruutimist, sisselogitud kasutaja konteksti, A/B-viibetestimist — lülitu webhooki režiimi ja lase oma serveril otsustada.
Kuidas see toimib
- Tellid sündmuse
telephony.incoming(telefon) võiweb.incoming(vidin) jaoks. Mõlemad on blokeerivad veebikonksud: ThunderPhone ootab sinu vastust enne kõne jätkamist — telefonikõne puhul kuni 13 sekundit (sh üks korduskatse) ja vidinaseansi puhul 10 sekundit. - ThunderPhone saadab sulle
{call_id, from_number, to_number}(vidina seansid sisaldavad numbrite asemel vidinapõhiseid välju — vt päringu skeemi). - Sinu server vastab agendi konfiguratsiooniga (viip, hääl, toode, tööriistad, sõnad). ThunderPhone kasutab seda konfiguratsiooni kõne jaoks.
- Varuagenti ei ole. Kui tagastad
{}või vigase konfiguratsiooni või kui päring nurjub ka pärast korduskatset, lõpetatakse telefonikõne kohe ja salvestatakseend_reasonväärtusegainbound_config_webhook_failed; vidinaseansi päring nurjub.
1. Seadista webhooki sihtkoht
Telefoninumbrite jaoks telli oma lõpp-punkt sündmusele telephony.incoming:
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "Prod call-incoming",
"url": "https://example.com/thunderphone/incoming",
"events": ["telephony.incoming"]
}'Vastus sisaldab ühekordset secret-it — salvesta see; kasutad seda
allkirja kontrollimiseks.
Vidinaseansside jaoks loo avaldatav võti režiimis mode="webhook",
mille sisse on lisatud sinu lõpp-punkti URL:
curl -X POST https://api.thunderphone.com/v1/publishable-key \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Dynamic widget",
"mode": "webhook",
"webhook_url": "https://example.com/thunderphone/widget-incoming",
"allowed_domains": ["example.com"]
}'Vidin saadab iga seansi alustamisel sellele URL-ile POST-päringu.
2. Rakenda töötleja
Kolm rusikareeglit:
- Kontrolli allkirja iga päringu puhul (vt Veebikonksu allkirjade kontrollimine). Ära jäta seda arenduses vahele — tee see üks kord õigesti ja kasuta uuesti.
- Vasta kiiresti. Telefonikõne esimene katse katkestatakse 10 sekundi järel ja kogu vahetus 13 sekundi järel ning iga sekund on helistaja jaoks vaikus. Tee vajadusel andmebaasipäringuid, kuid ära kutsu järgnevaid LLM-e sünkroonselt — kui soovid dünaamilist viiba genereerimist, arvuta see ette ja vahemällu salvesta.
- Kasuta selget varuvarianti. Iga ootamatu oleku korral vasta
vaikimisi
prompti javoiceiga (või salvestatudagent_idga). Väärtuse{}või veastaatuse tagastamine lõpetab kõne.
import hashlib
import hmac
import json
import os
from fastapi import FastAPI, HTTPException, Request
app = FastAPI()
SECRET = os.environ["THUNDERPHONE_WEBHOOK_SECRET"]
def verify(body: bytes, sig: str) -> bool:
expected = hmac.new(SECRET.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sig or "")
@app.post("/thunderphone/incoming")
async def incoming(request: Request):
body = await request.body()
if not verify(body, request.headers.get("X-ThunderPhone-Signature", "")):
raise HTTPException(401)
event = json.loads(body)
if event["type"] not in ("telephony.incoming", "web.incoming"):
return {} # fall back to default
caller = event["data"]["from_number"]
# Cheap DB lookup: is this a known VIP?
customer = lookup_customer(caller)
if customer and customer.tier == "vip":
return {
"prompt": f"You are a VIP concierge for {customer.name}. Be proactive…",
"voice": "john",
"product": "storm-base",
}
return {} # default agent handles non-VIPs
def lookup_customer(phone: str):
# ... your CRM integration ...
passimport crypto from "node:crypto";
import express from "express";
const app = express();
const SECRET = process.env.THUNDERPHONE_WEBHOOK_SECRET;
function verify(body, sig) {
const expected = crypto.createHmac("sha256", SECRET).update(body).digest("hex");
return sig &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
}
app.post(
"/thunderphone/incoming",
express.raw({ type: "application/json" }),
async (req, res) => {
if (!verify(req.body, req.header("X-ThunderPhone-Signature"))) {
return res.sendStatus(401);
}
const event = JSON.parse(req.body.toString("utf8"));
const IMPORTANT_TYPES = new Set([
"telephony.incoming",
"web.incoming",
]);
if (!IMPORTANT_TYPES.has(event.type)) return res.json({});
const customer = await lookupCustomer(event.data.from_number);
if (customer?.tier === "vip") {
return res.json({
prompt: `You are a VIP concierge for ${customer.name}. Be proactive…`,
voice: "john",
product: "storm-base",
});
}
res.json({}); // fall back to default agent
},
);3. Vastuse skeem
Vastuse sisu vastab täpselt sissetuleva kõne vastuse skeemile. Levinud väljad:
| Väli | Tüüp | Kirjeldus |
|---|---|---|
prompt | string (nõutud) | Agendi süsteemiviip |
voice | string (nõutud) | Hääle ID asukohast GET /v1/voices |
product | string | Vaikeväärtus on spark. |
background_track | string | null | Taustaheli ID |
acknowledgement_prompt_mode | string | auto või manual (ainult Storm koos kinnitusega) |
acknowledgement_prompt | string | Nõutud, kui režiim on manual |
language_switching | string | Mitmekeelsete agentide jaoks ask_first või follow_caller |
tools | array | Reasisesed funktsioonitööriistade skeemid — vt Funktsioonitööriistad |
Hoia salvestatud agenti ja edasta muutujad või kontekst
Tagasta {"agent_id": 12, "variables": {"name": "Ada"}}, et kasutada selle organisatsiooni
salvestatud agenti koos kõnepõhiste andmetega. Selle viip võib sisaldada {{name}} või
{{name|Friend}}. Veebikonksu muutujad ühendatakse päringutaseme muutujate peale; null
kasutab kohatäite vaikeväärtust või tühja teksti, kui vaikeväärtust pole määratud. Lõplikud
väärtused ja lahendamata nimed kuvatakse kõne üksikasjades ning lõpetamise veebikonksudes.
Lisa context, kuni 20 000 tähemärgi pikkune vabavormiline string, et anda agendile
selle kõne jaoks lühike ülevaade (märkmed sinu CRM-ist või põhjus, miks kõnet ootad);
see lisatakse pärast viipa eraldatud plokina.
Salvestatud agendi vastused aktsepteerivad ainult välju agent_id, variables, context, timezone ja language. Kui prompt on
olemas, kasutab vastus reasisest konfiguratsiooni ja eirab agent_id-d (sealhulgas
null- või mittetäisarvulisi metaandmeid); reasisene viip peab siiski olema kehtiv. Reasisese
konfiguratsiooni vastused võivad sisaldada ka välju variables ja context. Salvestatud agendi vastused kasutavad
agendi avaldatud A/B-jaotust nii telefoni- kui ka vidinakõnede puhul ning seejärel kuvavad muutujad. Piirangute ja
seansi API toe kohta vaata kõnemuutujaid.
Blokeeriv konfiguratsioon pärineb pärandtelefoninumbri/organisatsiooni URL-ist või veebikonksurežiimis vidina võtmest;
lõpp-punkti süsteemi sissetulevad sündmused on ainult teavitused.
Määra ajavöönd kõnepõhiselt
Üks häälagent saab vastata kontaktidele eri ajavööndites. Lisa salvestatud agendi või tekstisisese vastuse juurde IANA nimi timezone ning agent ütleb selle kõne puhul kuupäeva ja kellaaja ning pakub aegu selles ajavööndis, sõltumata agendi enda ajavööndist:
{"agent_id": 12, "timezone": "America/Chicago", "variables": {"name": "Ada"}}Saada ajavöönd, mitte ajatempel, variables-is: agendi kell töötab kõne ajal edasi ja edastatud aeg aegub. Väärtust, mis ei ole IANA ajavöönd, eiratakse ning kõne ühendatakse agendi ajavööndis.
Määra keel iga kõne jaoks
Üks agent saab vastata igas oma keeles. Lisa language, toetatud
keelekood, näiteks es (es-MX loetakse kui es), väljade agent_id ja
kõne kõrvale ning kõne algab selles keeles:
{"agent_id": 12, "language": "es", "variables": {"name": "Ada"}}Agent räägib seda oma selle keele häälega: selle
language_voices kirje abil; muul juhul,
kui native_voice_switching on sisse lülitatud, emakeelse häälega, millele agent
selles keeles üle läheks; muul juhul oma häälega, kui see hääl seda keelt räägib. Seejärel
jäävad keelte vahetamiseks kättesaadavaks agendi muud keeled ja selle esmane keel. Kui ükski neist ei saa seda keelt rääkida,
algab kõne siiski selles keeles, kasutades keele vaikehäält (kohandatud häälega agent säilitab
selle) ning muid keeli pole saadaval. Tagasi lükatakse ainult kood, mis ei ole toetatud keel.
Vidina- ja reaalajas seansid kasutavad sama language välja.
Mustrite näited
Sisselogitud kasutaja kontekst
Veebikonksurežiimis vidinates teab külastaja leht juba, kes ta
on. Kutsu oma veebikonks välja päringustringi parameetriga, mille vidina SDK
edastab (?customer_id=123), ja otsi klient serveripoolel üles.
A/B-juhise kasutuselevõtt
Enne kui selle ise käsitsi lahendad, pane tähele, et ThunderPhone'il on sisseehitatud
eksperimentide funktsioon
(/dashboard/experiments ja agendiehitaja A/B vahekaart), mis
määratleb variandid, jagab liikluse ja võrdleb tulemusi variantide kaupa —
veebikonksu pole vaja.
Kui vajad siiski veebikonksupoolset juhtimist: räsi call_id → ämber;
serveeri juhist A väärtustele 0..49 ja juhist B väärtustele 50..99. Salvesta,
millise ämbri valisid, oma andmebaasi ning korreleeri see hiljem lõpetatud
kõne hindega.
Ajapõhine suunamine
Tööajal → „otseabi” agent; väljaspool tööaega → „võta sõnum”
agent. Puhtalt lüliti new Date().getUTCHours() põhjal sinu töötlejas.
Järgmised sammud
Täpsed päringu- ja vastuseskeemid, sealhulgas kõik konfiguratsioonivõtmed.
Seadista HMAC üks kord õigesti; kasuta seda kõikjal uuesti.
Ühenda dünaamiline suunamine agendipõhiste tööriistadega.
Korduskatsed, järjestamine, ajalõpud.