telephony.incoming / web.incoming

जेव्हा इनबाउंड फोन कॉल नियुक्त एजंट नसलेल्या क्रमांकावर येतो, किंवा वेब विजेट सत्र mode="webhook" मधील प्रकाशित करण्यायोग्य कीवर सुरू होते, तेव्हा ThunderPhone तुमच्या लेगसी webhook URL वर ब्लॉकिंग telephony.incoming / web.incoming विनंती पाठवते आणि कॉन्फिगरेशन प्रतिसादासाठी कमाल 10 सेकंद प्रतीक्षा करते. प्रत्येक कॉलबाबत prompt, व्हॉइस आणि टूल्स गतिमानपणे निवडण्यासाठी हा विनिमय वापरा — संपूर्ण नमुन्यासाठी डायनॅमिक कॉल कॉन्फिगरेशन मार्गदर्शक पहा.

ब्लॉकिंग विनिमयाला कोणताही फॉलबॅक नाही: तुमचा हँडलर non-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":   []
}
फील्डप्रकारआवश्यकवर्णन
promptstringहोयएजंटला मार्गदर्शन करणारा सिस्टम prompt
voicestringहोयGET /v1/voices मधील व्हॉइस आयडी, उदा. john. voice_name हे उपनाव म्हणून स्वीकारले जाते. अज्ञात व्हॉइस प्रमाणीकरणात अयशस्वी होतात आणि कॉल नाकारतात
productstringनाहीडीफॉल्ट spark. अनुमत: spark, bolt, storm-base, storm-base-with-ack, storm-extra, storm-extra-with-ack
thinking_levelstringनाहीminimal, base (डीफॉल्ट), किंवा extra. Storm उत्पादनांसाठी ओव्हरराइड केले जाते: storm-extra* extra सक्तीचे करते, इतर storm-* base सक्तीचे करतात
audio_context_modestringनाहीfull (डीफॉल्ट) किंवा reduced
watchdog_enabledbooleanनाहीया कॉलसाठी पर्यवेक्षण सक्षम करा. डीफॉल्ट false
storm_feedback_modestringनाहीnone, acknowledgement (डीफॉल्ट), किंवा tick
languagestringनाहीprimary_language साठी संक्षिप्त रूप
primary_languagestringनाहीभाषा कोड, सामान्यीकृत (डीफॉल्ट en). न सोडवता येणारे कोड कॉल नाकारतात
has_additional_languagesbooleanनाहीडीफॉल्ट false
additional_languagesarray of stringनाहीएजंट ज्या अतिरिक्त भाषांवर स्विच करू शकतो त्या
background_trackstring | nullनाहीवातावरणीय ऑडिओ आयडी किंवा null
acknowledgement_prompt_modestringनाहीauto (डीफॉल्ट) किंवा manual (Storm-with-ack उत्पादने)
acknowledgement_promptstringनाहीacknowledgement_prompt_mode="manual" असताना वापरले जाते
silence_interval_secondsinteger | nullनाही5–120. तपासणीपूर्वी कॉलरच्या शांततेचे सेकंद
silence_max_checkinsinteger | nullनाही1–10
silence_checkins_enabledbooleanनाहीडीफॉल्ट true
connect_tone_enabledbooleanनाहीडीफॉल्ट false
voicemail_actionstringनाहीprompt (डीफॉल्ट), hangup, किंवा message
voicemail_messagestringनाहीvoicemail_action="message" असताना वापरले जाते
agent_namestringनाहीडॅशबोर्ड आणि विजेटमध्ये दर्शवले जाणारे नाव
org_namestringनाहीएजंटच्या व्यक्तिमत्त्वासाठी संस्थेचे प्रदर्शन नाव
toolsarrayनाहीइनलाइन फंक्शन-टूल स्कीमा (फंक्शन टूल्स पहा)
call_idintegerनाहीविनंतीच्या कॉल आयडीचा पर्यायी इको; दुर्लक्षित केला जातो

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 ला संभाषणादरम्यान तुमचे API कॉल करता यावेत यासाठी टूल्स जोडा:

{
  "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जास्तसखोलविचार करत असताना स्वयंचलित भराव

संबंधित