telephony.incoming / web.incoming
جب کسی آنے والی فون کال کا نمبر کسی مقرر کردہ
ایجنٹ کے بغیر ہو، یا ویب ویجٹ سیشن
mode="webhook" میں کسی پبلش ایبل کلید پر شروع ہو، تو ThunderPhone آپ کے
لیگیسی webhook URL
کو ایک روکنے والی
telephony.incoming / web.incoming درخواست بھیجتا ہے اور کنفیگریشن کے جواب کے لیے 10 سیکنڈ تک انتظار کرتا ہے۔ ہر کال کے لیے prompt، آواز، اور ٹولز کو متحرک طور پر منتخب کرنے کے لیے اس تبادلے کو استعمال کریں —
مکمل طریقۂ کار کے لیے متحرک کال کنفیگریشن گائیڈ
دیکھیں۔
اس روکنے والے تبادلے کا کوئی متبادل نہیں: اگر آپ کا ہینڈلر
غیر-2xx اسٹیٹس واپس کرے، وقت ختم ہو جائے، یا ایسی کنفیگ واپس کرے جو توثیق میں ناکام ہو،
تو کال مسترد کر دی جاتی ہے (فون کال کنیکٹ نہیں ہوتی؛ ویجٹ
سیشن کی درخواست 502/422 کے ساتھ ناکام ہو جاتی ہے)۔ فوری جواب دیں — جب آپ فیصلہ کر رہے ہوتے ہیں تو کالر رنگ بیک سن رہا ہوتا ہے۔
درخواست پے لوڈ
فون کالز کے لیے (telephony.incoming):
{
"type": "telephony.incoming",
"data": {
"call_id": 987654321,
"from_number": "+14155550199",
"to_number": "+15551234567"
}
}
| فیلڈ | قسم | وضاحت |
|---|---|---|
call_id | integer | کال آئی ڈی — اس کال کے تمام ایونٹس میں مستقل |
from_number | string | E.164 کالر نمبر |
to_number | string | E.164 منزل (آپ کے ThunderPhone نمبروں میں سے ایک) |
ویب ویجٹ سیشنز (web.incoming) کے لیے data فون نمبروں کے بجائے
ایمبیڈنگ صفحے کی شناخت کرتا ہے:
{
"type": "web.incoming",
"data": {
"call_id": 987654322,
"origin_domain": "https://example.com",
"publishable_key_prefix": "pk_live_a1b2"
}
}
| فیلڈ | قسم | وضاحت |
|---|---|---|
call_id | integer | کال آئی ڈی |
origin_domain | string | ویجٹ کی میزبانی کرنے والے صفحے کا اوریجن |
publishable_key_prefix | string | سیشن کھولنے والی پبلش ایبل کلید کے ابتدائی حروف |
language, primary_language | string | ویجٹ سیشن میں زبان کی اووررائیڈ کی درخواست ہونے پر موجود |
voice | string | ویجٹ سیشن میں آواز کی اووررائیڈ کی درخواست ہونے پر موجود |
website_context | string | ویجٹ کی جانب سے فی-سیشن صفحہ سیاق بھیجنے پر موجود |
جوابی اسکیما
اس کال کے لیے ایجنٹ کی کنفیگریشن بیان کرنے والا JSON آبجیکٹ واپس کریں۔
prompt اور voice لازمی ہیں؛ باقی سب اختیاری ہے۔
{
"prompt": "You are a helpful booking assistant for Acme Restaurant.",
"voice": "john",
"product": "spark",
"background_track": null,
"tools": []
}
| فیلڈ | قسم | لازمی | وضاحت |
|---|---|---|---|
prompt | اسٹرنگ | ہاں | ایجنٹ کو چلانے والا سسٹم prompt |
voice | اسٹرنگ | ہاں | GET /v1/voices سے وائس آئی ڈی، مثلاً john۔ voice_name بطور عرف قبول کیا جاتا ہے۔ نامعلوم وائسز توثیق میں ناکام ہو جاتی ہیں اور کال مسترد ہو جاتی ہے |
product | اسٹرنگ | نہیں | پہلے سے طے شدہ spark ہے۔ اجازت یافتہ: spark، bolt، storm-base، storm-base-with-ack، storm-extra، storm-extra-with-ack |
thinking_level | اسٹرنگ | نہیں | minimal، base (پہلے سے طے شدہ)، یا extra۔ Storm پروڈکٹس کے لیے اووررائیڈ ہوتا ہے: storm-extra*، extra نافذ کرتا ہے، دیگر storm-*، base نافذ کرتے ہیں |
audio_context_mode | اسٹرنگ | نہیں | full (پہلے سے طے شدہ) یا reduced |
watchdog_enabled | بولین | نہیں | اس کال کے لیے نگرانی فعال کریں۔ پہلے سے طے شدہ false |
storm_feedback_mode | اسٹرنگ | نہیں | none، acknowledgement (پہلے سے طے شدہ)، یا tick |
language | اسٹرنگ | نہیں | primary_language کے لیے مختصر نام |
primary_language | اسٹرنگ | نہیں | زبان کا کوڈ، معمول کے مطابق بنایا گیا (پہلے سے طے شدہ en)۔ ناقابلِ حل کوڈز کال مسترد کر دیتے ہیں |
has_additional_languages | بولین | نہیں | پہلے سے طے شدہ false |
additional_languages | اسٹرنگ کی ارے | نہیں | اضافی زبانیں جن پر ایجنٹ منتقل ہو سکتا ہے |
background_track | اسٹرنگ | null | نہیں | محیطی آڈیو آئی ڈی یا null |
acknowledgement_prompt_mode | اسٹرنگ | نہیں | auto (پہلے سے طے شدہ) یا manual (Storm-with-ack پروڈکٹس) |
acknowledgement_prompt | اسٹرنگ | نہیں | acknowledgement_prompt_mode="manual" ہونے پر استعمال ہوتا ہے |
silence_interval_seconds | انٹیجر | null | نہیں | 5 سے 120۔ جانچ سے پہلے کالر کی خاموشی کے سیکنڈز |
silence_max_checkins | انٹیجر | null | نہیں | 1 سے 10 |
silence_checkins_enabled | بولین | نہیں | پہلے سے طے شدہ true |
connect_tone_enabled | بولین | نہیں | پہلے سے طے شدہ false |
voicemail_action | اسٹرنگ | نہیں | prompt (پہلے سے طے شدہ)، hangup، یا message |
voicemail_message | اسٹرنگ | نہیں | voicemail_action="message" ہونے پر استعمال ہوتا ہے |
agent_name | اسٹرنگ | نہیں | ڈیش بورڈز اور ویجیٹ کو رپورٹ کیا جانے والا ڈسپلے نام |
org_name | اسٹرنگ | نہیں | ایجنٹ کی شخصیت کے لیے تنظیم کا ڈسپلے نام |
tools | ارے | نہیں | ان لائن فنکشن-ٹول اسکیماز (Function Tools دیکھیں) |
call_id | انٹیجر | نہیں | درخواست کی کال آئی ڈی کا اختیاری عکس؛ نظر انداز کر دیا جاتا ہے |
چونکہ prompt اور voice لازمی ہیں، اس لیے {} یا توثیق میں ناکام ہونے والا کوئی بھی
جواب کال کو 422 کے ساتھ مسترد کر دیتا ہے — اس راستے پر جامد ایجنٹ کا کوئی متبادل نہیں
ہے (ویب ہک موڈ میں کسی نمبر یا کلید کے ساتھ کوئی ایجنٹ مقرر نہیں ہوتا)۔
جوابی حجم کی حد
ہینڈلر کی مثال
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({});
},
);
فنکشن ٹولز کے ساتھ جواب
ٹولز منسلک کریں تاکہ AI گفتگو کے دوران آپ کی APIs کو کال کر سکے:
{
"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"
}
}
}
]
}
پروڈکٹ ٹئیر کا فوری حوالہ
| پروڈکٹ | تاخیر | استدلال | تصدیق |
|---|---|---|---|
spark | سب سے کم | بنیادی | — |
bolt | کم | بہتر | — |
storm-base | درمیانی | مضبوط | — |
storm-base-with-ack | درمیانی | مضبوط | سوچتے وقت خودکار وقفہ پُر کرنے والا متن |
storm-extra | زیادہ | گہرا | — |
storm-extra-with-ack | زیادہ | گہرا | سوچتے وقت خودکار وقفہ پُر کرنے والا متن |