---
title: "Dinaminė konfigūracija kiekvienam skambučiui"
description: "Kiekvienam įeinančiam skambučiui atskirai pasirinkite atsiliepiantį agentą arba pakeiskite jo raginimą ir nustatymus, remdamiesi pasirinkta logika jūsų valdomame webhook."
---

Pagal numatytuosius nustatymus kiekvienam telefono numeriui ir viešajam raktui priskiriamas statinis agentas. Kai reikia tinkinti **kiekvienam skambintojui** arba **kiekvienam lankytojui** — nukreipti VIP klientus, įtraukti prisijungusio naudotojo kontekstą, atlikti A/B raginimų bandymus — perjunkite į žiniatinklio kabliuko režimą ir leiskite spręsti savo serveriui.

## Kaip tai veikia

1. Užsiprenumeruojate [`telephony.incoming`](/lt/webhooks/events)
   (telefono) arba [`web.incoming`](/lt/webhooks/events) (valdiklio)
   įvykį. Abu yra **blokuojantys** žiniatinklio kabliukai: ThunderPhone laukia iki
   10 sekundžių jūsų atsakymo prieš tęsdamas skambutį.
2. ThunderPhone siunčia jums `{call_id, from_number, to_number}` (valdiklio
   sesijose vietoje numerių pateikiami valdikliui būdingi laukai — žr.
   [užklausos schemą](/lt/webhooks/call-incoming)).
3. Jūsų serveris atsako agento konfigūracija (raginimu, balsu,
   produktu, įrankiais). ThunderPhone naudoja tą konfigūraciją skambučio metu.
4. Jei grąžinate `{}`, baigiasi laukimo laikas arba įvyksta klaida, kaip atsarginis variantas
   naudojamas statiškai priskirtas agentas. Saugus numatytasis nustatymas.

<Note>
  Veikia identiškai telefono skambučiams (`telephony.incoming`) ir valdiklio
  sesijoms (`web.incoming`), nesvarbu, ar jos pristatomos į žiniatinklio kabliuko galinį tašką,
  ar į senąjį vieno URL žiniatinklio kabliuką.
</Note>

<Warning>
  **Skambučiuose, sukonfigūruotuose tiesiogiai per žiniatinklio kabliuką, nėra atkuriamas ThunderPhone sutikimo pranešimas.** Šis kelias apeina
  agento lygio skambučio pradžios pranešimą ir yra aiškiai neįtrauktas į ThunderPhone sutikimo pranešimų
  sistemą (Paslaugų teikimo sąlygų skyrius „Įrašymas ir sutikimas“). Jūsų
  organizacija atsako už visus šių skambučių įrašymo, stebėjimo, DI dalyvavimo ir
  skambintojo identifikavimo pranešimus bei sutikimus. Pateikite
  juos savo procese — pavyzdžiui, raginimo pradžios scenarijuje —
  prieš įjungdami tiesioginį žiniatinklio kabliuko režimą. Žiniatinklio kabliuko atsakymas, kuriame nurodomas
  išsaugotas `agent_id`, naudoja to agento įprastą įrašymo ir informavimo politiką.
</Warning>

## 1. Sukonfigūruokite žiniatinklio kabliuko paskirties vietą

<Tabs>
<Tab title="Telefono skambučiai">
Telefono numeriams užsiprenumeruokite savo galinį tašką įvykiui `telephony.incoming`:

```bash
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label":  "Prod call-incoming",
    "url":    "https://example.com/thunderphone/incoming",
    "events": ["telephony.incoming"]
  }'
```

Atsakyme pateikiamas vienkartinis `secret` — išsaugokite jį; naudosite jį
parašo tikrinimui.
</Tab>
<Tab title="Žiniatinklio valdiklis">
Valdiklio sesijoms sukurkite viešąjį raktą su `mode="webhook"`,
kuriame įtraukta jūsų galinio taško URL:

```bash
curl -X POST https://api.thunderphone.com/v1/publishable-key \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name":            "Dynamic widget",
    "mode":            "webhook",
    "webhook_url":     "https://example.com/thunderphone/widget-incoming",
    "allowed_domains": ["example.com"]
  }'
```

Valdiklis siųs POST užklausą į šį URL kiekvienos sesijos pradžioje.
</Tab>
</Tabs>

## 2. Įdiekite tvarkytuvę

Trys pagrindinės taisyklės:

- **Patikrinkite parašą** kiekvienoje užklausoje (žr.
  [Tikrinkite webhook parašus](/lt/guides/verify-webhook-signatures)).
  Nepraleiskite to kūrimo aplinkoje – atlikite teisingai vieną kartą ir pakartotinai naudokite.
- **Atsakykite greitai**. Dešimt sekundžių yra griežta riba, o kiekviena sekundė
  skambinančiajam yra tyla. Jei reikia, atlikite duomenų bazės paieškas, bet
  nekvieskite tolesnių LLM sinchroniškai – jei norite dinamiškai generuoti raginimus, iš anksto apskaičiuokite ir išsaugokite podėlyje.
- **Tvarkingai grįžkite prie numatytojo sprendimo**. Bet kokia netikėta būsena turi grąžinti `{}`, kad
  statiškai priskirtas agentas apdorotų skambutį.

<CodeGroup>
```python FastAPI
import hashlib
import hmac
import json
import os

from fastapi import FastAPI, HTTPException, Request

app = FastAPI()
SECRET = os.environ["THUNDERPHONE_WEBHOOK_SECRET"]

def verify(body: bytes, sig: str) -> bool:
    expected = hmac.new(SECRET.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, sig or "")

@app.post("/thunderphone/incoming")
async def incoming(request: Request):
    body = await request.body()
    if not verify(body, request.headers.get("X-ThunderPhone-Signature", "")):
        raise HTTPException(401)

    event = json.loads(body)
    if event["type"] not in ("telephony.incoming", "web.incoming"):
        return {}  # fall back to default

    caller = event["data"]["from_number"]
    # Cheap DB lookup: is this a known VIP?
    customer = lookup_customer(caller)
    if customer and customer.tier == "vip":
        return {
            "prompt":  f"You are a VIP concierge for {customer.name}. Be proactive…",
            "voice":   "john",
            "product": "storm-base",
        }
    return {}  # default agent handles non-VIPs

def lookup_customer(phone: str):
    # ... your CRM integration ...
    pass
```

```javascript Express
import crypto from "node:crypto";
import express from "express";

const app = express();
const SECRET = process.env.THUNDERPHONE_WEBHOOK_SECRET;

function verify(body, sig) {
  const expected = crypto.createHmac("sha256", SECRET).update(body).digest("hex");
  return sig &&
    crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
}

app.post(
  "/thunderphone/incoming",
  express.raw({ type: "application/json" }),
  async (req, res) => {
    if (!verify(req.body, req.header("X-ThunderPhone-Signature"))) {
      return res.sendStatus(401);
    }
    const event = JSON.parse(req.body.toString("utf8"));

    const IMPORTANT_TYPES = new Set([
      "telephony.incoming",
      "web.incoming",
    ]);
    if (!IMPORTANT_TYPES.has(event.type)) return res.json({});

    const customer = await lookupCustomer(event.data.from_number);
    if (customer?.tier === "vip") {
      return res.json({
        prompt:  `You are a VIP concierge for ${customer.name}. Be proactive…`,
        voice:   "john",
        product: "storm-base",
      });
    }
    res.json({}); // fall back to default agent
  },
);
```
</CodeGroup>

## 3. Atsakymo schema

Atsakymo turinys tiksliai atitinka
[įeinančio skambučio atsakymo schemą](/lt/webhooks/call-incoming).
Dažniausiai naudojami laukai:

| Laukas | Tipas | Aprašymas |
|-------|------|-------------|
| `prompt` | eilutė (privaloma) | Sistemos raginimas agentui |
| `voice` | eilutė (privaloma) | Balso ID iš [`GET /v1/voices`](/api-reference/agents#voices) |
| `product` | eilutė | Numatytoji reikšmė yra `spark` |
| `background_track` | eilutė \| null | Aplinkos garso ID |
| `acknowledgement_prompt_mode` | eilutė | `auto` arba `manual` (tik Storm su patvirtinimu) |
| `acknowledgement_prompt` | eilutė | Privaloma, kai režimas yra `manual` |
| `tools` | masyvas | Įterptos funkcijų įrankių schemos — žr. [Funkcijų įrankiai](/lt/tools/overview) |

<Note>
  Skambučiui pritaikyta kalbėjimo tvarka ir `max_hold_seconds` nėra pasiekiami
  žiniatinklio kablio atsakyme. Nustatykite juos
  [agente](/api-reference/agents), kurį nurodote.
</Note>

### Išsaugokite agentą ir pateikite kintamuosius

Grąžinkite `{"agent_id": 12, "variables": {"name": "Ada"}}`, kad naudotumėte tos organizacijos
išsaugotą agentą su skambučiui skirtais duomenimis. Jo raginime gali būti `{{name}}` arba
`{{name|Friend}}`. Žiniatinklio kablio kintamieji perrašo užklausos lygio kintamuosius; null
naudoja vietos ženklo numatytąją reikšmę arba tuščią tekstą, jei ji nepateikta. Galutinės
reikšmės ir neišspręsti pavadinimai rodomi skambučio išsamioje informacijoje ir užbaigimo
žiniatinklio kabliuose. Išsaugoto agento atsakymai priima tik `agent_id` ir `variables`. Jei yra
`prompt`, atsakymas naudoja įterptąją konfigūraciją ir nepaiso `agent_id` (įskaitant
null arba ne sveikojo skaičiaus metaduomenis); įterptasis raginimas vis tiek turi būti galiojantis.
Įterptosios konfigūracijos atsakymai taip pat gali apimti `variables`. Išsaugoto agento atsakymai
naudoja agente įdiegtą A/B paskirstymą tiek telefono, tiek valdiklio skambučiams, tada pateikia
kintamuosius. Apribojimus ir sesijos API palaikymą žr. [skambučio kintamieji](/lt/guides/call-variables).
Blokavimo konfigūracija gaunama iš senstelėjusio telefono numerio / organizacijos URL arba
žiniatinklio kablio režimo valdiklio rakto; galinio taško sistemos įeinantys įvykiai yra tik pranešimai.

## Modeliai

### Prisijungusio naudotojo kontekstas

Žiniatinklio kablio režimo valdikliuose lankytojo puslapis jau žino, kas jis
yra. Iškvieskite savo žiniatinklio kablį su užklausos eilutės parametru, kurį
valdiklio SDK persiunčia (`?customer_id=123`), ir suraskite klientą serverio pusėje.

### A/B raginimų diegimas

Prieš kurdami tai patys, atkreipkite dėmesį, kad ThunderPhone turi vietinę
[eksperimentų](/lt/guides/concepts) funkciją
(`/dashboard/experiments` ir agento kūrimo priemonės **A/B** skirtuką), kuri
apibrėžia variantus, paskirsto srautą ir palygina kiekvieno varianto rezultatus —
žiniatinklio kablio nereikia.

Jei vis tiek reikia valdymo žiniatinklio kablio pusėje: maišykite `call_id` → segmentas;
pateikite raginimą A reikšmėms `0..49` ir raginimą B reikšmėms `50..99`. Įrašykite pasirinktą
segmentą savo DB ir vėliau susiekite jį su užbaigto skambučio įvertinimu.

### Maršrutizavimas pagal laiką

Darbo valandos → „tiesioginio palaikymo“ agentas; ne darbo valandomis → „priimti žinutę“
agentas. Tvarkyklėje tiesiog perjunkite pagal `new Date().getUTCHours()`.

---

## Tolesni veiksmai

<CardGroup cols={2}>
  <Card title="Įeinančio skambučio žiniatinklio kablio nuoroda" icon="phone" href="/lt/webhooks/call-incoming">
    Tikslios užklausų ir atsakymų schemos, įskaitant kiekvieną konfigūracijos raktą.
  </Card>
  <Card title="Patikrinkite žiniatinklio kablio parašus" icon="shield-check" href="/lt/guides/verify-webhook-signatures">
    Vieną kartą teisingai nustatykite HMAC; naudokite visur.
  </Card>
  <Card title="Sukurkite įrankio integraciją" icon="screwdriver-wrench" href="/lt/guides/build-tool-integration">
    Derinkite dinaminį maršrutizavimą su agentui skirtais įrankiais.
  </Card>
  <Card title="Pristatymo semantika" icon="bolt" href="/lt/webhooks/overview">
    Pakartotiniai bandymai, tvarka, laiko limitai.
  </Card>
</CardGroup>
