ThunderPhone 2.0 sasa inapatikana.Anza mwenyewe, kuanzia 2¢/dakika.Soma tangazo

Webhooks

telephony.incoming / web.incoming

Webhook inayozuia inayounda usanidi wa simu inayoingia kwa wakati halisi.

Simu inayoingia inapofikia nambari isiyo na ejenti aliyokabidhiwa, au kipindi cha wijeti ya wavuti kinapoanza kwa ufunguo wa kuchapisha katika mode="webhook", ThunderPhone hutuma ombi la kusubiri la telephony.incoming / web.incoming kwa URL yako ya zamani ya webhook na kusubiri hadi sekunde 10 kupata jibu la usanidi. Tumia mabadilishano haya kuchagua kwa njia ya kubadilika prompt, sauti, na zana kwa kila simu — tazama mwongozo wa usanidi wa simu unaobadilika kwa mtiririko kamili.

Mabadilishano ya kusubiri hayana njia mbadala: ikiwa kishughulikiaji chako kinarejesha hali isiyo ya 2xx, kinaisha muda, au kinarejesha usanidi usiopitisha 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"
  }
}
SehemuAinaMaelezo
call_idintegerKitambulisho cha simu — hubaki thabiti katika matukio yote ya simu hii
from_numberstringNambari ya mpigaji ya E.164
to_numberstringLengwa la E.164 (mojawapo ya nambari zako za ThunderPhone)

Kwa vipindi vya wijeti ya wavuti (web.incoming), data hutambulisha 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"
  }
}
SehemuAinaMaelezo
call_idintegerKitambulisho cha simu
origin_domainstringAsili ya ukurasa unaohifadhi wijeti
publishable_key_prefixstringHerufi za kwanza za ufunguo wa kuchapisha uliofungua kipindi
language, primary_languagestringHupo wakati kipindi cha wijeti kiliomba kubatilisha lugha
voicestringHupo wakati kipindi cha wijeti kiliomba kubatilisha sauti
website_contextstringHupo wakati wijeti ilipitisha muktadha wa ukurasa kwa kila kipindi

Skima ya majibu

Rudisha kitu cha JSON kinachoeleza usanidi wa ejenti kwa simu hii. prompt na voice zinahitajika; kila kitu kingine ni hiari.

{
  "prompt":  "You are a helpful booking assistant for Acme Restaurant.",
  "voice":   "john",
  "product": "spark",
  "background_track": null,
  "tools":   []
}
SehemuAinaInahitajikaMaelezo
promptstringndiyoPrompt ya mfumo inayoongoza ejenti
voicestringndiyoKitambulisho cha sauti kutoka GET /v1/voices, kwa mfano john. voice_name inakubaliwa kama jina mbadala. Sauti zisizojulikana hushindwa uthibitishaji na kukataa simu
productstringhapanaChaguo-msingi ni spark. Zinazoruhusiwa: spark, bolt, storm-base, storm-base-with-ack, storm-extra, storm-extra-with-ack
thinking_levelstringhapanaminimal, base (chaguo-msingi), au extra. Hubatilishwa kwa bidhaa za Storm: storm-extra* hulazimisha extra, na storm-* nyingine hulazimisha base
audio_context_modestringhapanafull (chaguo-msingi) au reduced
watchdog_enabledbooleanhapanaWasha usimamizi kwa simu hii. Chaguo-msingi ni false
additional_audio_contextboolean | nullhapanaJumuisha zamu chache za mwisho za sauti ya mpigaji simu badala ya zamu ya hivi karibuni pekee, kuboresha masahihisho na ukusanyaji wa data wenye tahajia/namba nyingi kwa ongezeko dogo la muda wa kusubiri/gharama. Huwashwa kwa chaguo-msingi kwa vipindi vinavyoingia na huzimwa kwa simu zinazotoka; null huhifadhi chaguo-msingi
storm_feedback_modestringhapananone, acknowledgement (chaguo-msingi), au tick
languagestringhapanaUfupisho wa primary_language
primary_languagestringhapanaMsimbo wa lugha, uliosanifishwa (chaguo-msingi en). Misimbo isiyoweza kutatuliwa hukataa simu
has_additional_languagesbooleanhapanaChaguo-msingi ni false
additional_languagesarray of stringhapanaLugha za ziada ambazo ejenti inaweza kubadilisha hadi kwazo
native_voice_switchingbooleanhapanaChaguo-msingi ni false. Simu inapobadilika hadi lugha nyingine, badilisha hadi sauti asilia ya lugha hiyo (inayolingana kwa jinsia) badala ya kuhifadhi sauti iliyosanidiwa
background_trackstring | nullhapanaKitambulisho cha sauti ya mazingira au null
acknowledgement_prompt_modestringhapanaauto (chaguo-msingi) au manual (bidhaa za Storm-with-ack)
acknowledgement_promptstringhapanaHutumika wakati acknowledgement_prompt_mode="manual"
silence_interval_secondsinteger | nullhapana5–120. Sekunde za ukimya wa mpigaji simu kabla ya ukaguzi
silence_max_checkinsinteger | nullhapana1–10
silence_checkins_enabledbooleanhapanaChaguo-msingi ni true
connect_tone_enabledbooleanhapanaChaguo-msingi ni false
voicemail_actionstringhapanaprompt (chaguo-msingi), hangup, au message
voicemail_messagestringhapanaHutumika wakati voicemail_action="message"
agent_namestringhapanaJina la kuonyesha linaloripotiwa kwa dashibodi na wijeti
org_namestringhapanaJina la kuonyesha la shirika kwa persona ya ejenti
toolsarrayhapanaSkima za ndani za zana za vitendaji (tazama Zana za Vitendaji)
call_idintegerhapanaRudisho la hiari la kitambulisho cha simu cha ombi; hupuuzwa

Kwa kuwa prompt na voice zinahitajika, kurudisha {} au jibu lolote linaloshindwa uthibitishaji hukataa simu kwa 422 — hakuna ejenti mbadala thabiti kwenye njia hii (namba au ufunguo katika modi ya webhook haina ejenti iliyoteuliwa).


Kikomo cha ukubwa wa jibu


Mfano wa kishughulikiaji

Python (FastAPI)
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 {}
Node.js (Express)
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 ejenti 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

BidhaaUcheleweshajiUwezo wa kufikiriUthibitisho
sparkChini zaidiMsingi
boltChiniUlioboreshwa
storm-baseWastaniImara
storm-base-with-ackWastaniImaraKijazaji kiotomatiki wakati wa kufikiri
storm-extraJuu zaidiKina
storm-extra-with-ackJuu zaidiKinaKijazaji kiotomatiki wakati wa kufikiri

Yanayohusiana