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_idintegerکال آئی ڈی — اس کال کے تمام ایونٹس میں مستقل
from_numberstringE.164 کالر نمبر
to_numberstringE.164 منزل (آپ کے ThunderPhone نمبروں میں سے ایک)

ویب ویجٹ سیشنز (web.incoming) کے لیے data فون نمبروں کے بجائے ایمبیڈنگ صفحے کی شناخت کرتا ہے:

{
  "type": "web.incoming",
  "data": {
    "call_id": 987654322,
    "origin_domain": "https://example.com",
    "publishable_key_prefix": "pk_live_a1b2"
  }
}
فیلڈقسموضاحت
call_idintegerکال آئی ڈی
origin_domainstringویجٹ کی میزبانی کرنے والے صفحے کا اوریجن
publishable_key_prefixstringسیشن کھولنے والی پبلش ایبل کلید کے ابتدائی حروف
language, primary_languagestringویجٹ سیشن میں زبان کی اووررائیڈ کی درخواست ہونے پر موجود
voicestringویجٹ سیشن میں آواز کی اووررائیڈ کی درخواست ہونے پر موجود
website_contextstringویجٹ کی جانب سے فی-سیشن صفحہ سیاق بھیجنے پر موجود

جوابی اسکیما

اس کال کے لیے ایجنٹ کی کنفیگریشن بیان کرنے والا 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زیادہگہراسوچتے وقت خودکار وقفہ پُر کرنے والا متن

متعلقہ