telephony.incoming / web.incoming
Wakati simu inayoingia inapofikia nambari isiyo na
ejenti iliyoteuliwa, au kipindi cha wijeti ya wavuti kinapoanza kwenye ufunguo unaoweza kuchapishwa katika
mode="webhook", ThunderPhone hutuma ombi linalozuia
la telephony.incoming / web.incoming kwa
URL yako ya webhook ya urithi
na husubiri hadi sekunde 10 kwa jibu la usanidi. Tumia
ubadilishanaji huu kuchagua kwa mabadiliko prompt, sauti na zana kwa kila simu —
angalia mwongozo wa usanidi wa simu unaobadilika
kwa mchakato wa kutoka mwanzo hadi mwisho.
Ubadilishanaji wa kuzuia hauna mbadala: ikiwa kishughulikiaji chako kinarejesha
hali isiyo ya 2xx, kinaisha muda, au kinarejesha usanidi unaoshindwa uthibitishaji,
simu inakataliwa (simu ya simu haiunganishwi; ombi la kipindi cha wijeti
linashindwa kwa 502/422). Jibu haraka — mpigaji anasikia mlio wa kuita huku
ukiamua.
Payload ya ombi
Kwa simu za simu (telephony.incoming):
{
"type": "telephony.incoming",
"data": {
"call_id": 987654321,
"from_number": "+14155550199",
"to_number": "+15551234567"
}
}
| Sehemu | Aina | Maelezo |
|---|---|---|
call_id | integer | Kitambulisho cha simu — thabiti katika matukio yote ya simu hii |
from_number | string | Nambari ya mpigaji ya E.164 |
to_number | string | Lengwa la E.164 (moja ya nambari zako za ThunderPhone) |
Kwa vipindi vya wijeti ya wavuti (web.incoming), data hutambua
ukurasa unaopachika wijeti badala ya nambari za simu:
{
"type": "web.incoming",
"data": {
"call_id": 987654322,
"origin_domain": "https://example.com",
"publishable_key_prefix": "pk_live_a1b2"
}
}
| Sehemu | Aina | Maelezo |
|---|---|---|
call_id | integer | Kitambulisho cha simu |
origin_domain | string | Asili ya ukurasa unaopangisha wijeti |
publishable_key_prefix | string | Herufi za kwanza za ufunguo unaoweza kuchapishwa uliofungua kipindi |
language, primary_language | string | Huwepo wakati kipindi cha wijeti kiliomba ubadilishaji wa lugha |
voice | string | Huwepo wakati kipindi cha wijeti kiliomba ubadilishaji wa sauti |
website_context | string | Huwepo wakati wijeti ilipitisha muktadha wa ukurasa kwa kila kipindi |
Muundo wa jibu
Rudisha kitu cha JSON kinachoeleza usanidi wa ejenti kwa simu hii.
prompt na voice zinahitajika; kila kitu kingine ni cha hiari.
{
"prompt": "You are a helpful booking assistant for Acme Restaurant.",
"voice": "john",
"product": "spark",
"background_track": null,
"tools": []
}
| Sehemu | Aina | Inahitajika | Maelezo |
|---|---|---|---|
prompt | string | ndiyo | Prompt ya mfumo inayoendesha ejenti |
voice | string | ndiyo | Kitambulisho cha sauti kutoka GET /v1/voices, kwa mfano john. voice_name inakubaliwa kama jina mbadala. Sauti zisizojulikana hushindwa uthibitishaji na hukataa simu |
product | string | hapana | Chaguo-msingi ni spark. Zinazoruhusiwa: spark, bolt, storm-base, storm-base-with-ack, storm-extra, storm-extra-with-ack |
thinking_level | string | hapana | minimal, base (chaguo-msingi), au extra. Hubatilishwa kwa bidhaa za Storm: storm-extra* hulazimisha extra, storm-* nyingine hulazimisha base |
audio_context_mode | string | hapana | full (chaguo-msingi) au reduced |
watchdog_enabled | boolean | hapana | Washa usimamizi kwa simu hii. Chaguo-msingi ni false |
storm_feedback_mode | string | hapana | none, acknowledgement (chaguo-msingi), au tick |
language | string | hapana | Ufupisho wa primary_language |
primary_language | string | hapana | Msimbo wa lugha, uliosanifishwa (chaguo-msingi en). Misimbo isiyoweza kutatuliwa hukataa simu |
has_additional_languages | boolean | hapana | Chaguo-msingi ni false |
additional_languages | array of string | hapana | Lugha za ziada ambazo ejenti inaweza kubadilisha kwenda kwazo |
background_track | string | null | hapana | Kitambulisho cha sauti ya mandharinyuma au null |
acknowledgement_prompt_mode | string | hapana | auto (chaguo-msingi) au manual (bidhaa za Storm-with-ack) |
acknowledgement_prompt | string | hapana | Hutumika wakati acknowledgement_prompt_mode="manual" |
silence_interval_seconds | integer | null | hapana | 5–120. Sekunde za ukimya wa mpigaji simu kabla ya ukaguzi |
silence_max_checkins | integer | null | hapana | 1–10 |
silence_checkins_enabled | boolean | hapana | Chaguo-msingi ni true |
connect_tone_enabled | boolean | hapana | Chaguo-msingi ni false |
voicemail_action | string | hapana | prompt (chaguo-msingi), hangup, au message |
voicemail_message | string | hapana | Hutumika wakati voicemail_action="message" |
agent_name | string | hapana | Jina la kuonyesha linaloripotiwa kwa dashibodi na wijeti |
org_name | string | hapana | Jina la kuonyesha la shirika kwa persona ya ejenti |
tools | array | hapana | Miundo ya ndani ya zana za function (tazama Function Tools) |
call_id | integer | hapana | Mwangwi wa hiari wa kitambulisho cha simu cha ombi; hupuzwa |
Kwa kuwa prompt na voice zinahitajika, kurudisha {} au jibu lolote
linaloshindwa uthibitishaji hukataa simu kwa 422 — hakuna mbadala wa ejenti
tuli katika njia hii (namba au ufunguo katika hali ya webhook hauna ejenti
iliyowekwa).
Kikomo cha ukubwa wa jibu
Kishughulikiaji cha mfano
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({});
},
);
Jibu lenye zana za function
Ambatisha zana ili AI iweze kuita API zako katikati ya mazungumzo:
{
"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"
}
}
}
]
}
Muhtasari wa viwango vya bidhaa
| Bidhaa | Ucheleweshaji | Mantiki | Uthibitisho |
|---|---|---|---|
spark | Ndogo zaidi | Msingi | — |
bolt | Ndogo | Imeboreshwa | — |
storm-base | Wastani | Imara | — |
storm-base-with-ack | Wastani | Imara | Kijazaji kiotomatiki wakati wa kufikiri |
storm-extra | Kubwa zaidi | Kina | — |
storm-extra-with-ack | Kubwa zaidi | Kina | Kijazaji kiotomatiki wakati wa kufikiri |
Yanayohusiana
Tukio lisilozuia la mwisho wa simu.
Schema kamili ya JSON ya tools[] na mkataba wa endpoint uliotiwa saini.
Jiandikishe URL nyingi kwa telephony.incoming / web.incoming.
Miundo ya prompt, zana na majaribio ya A/B kwa kila mpigaji simu.