> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thunderphone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tīmekļa āķu pārskats

> Kā ThunderPhone piegādā reāllaika notikumus, kā verificēt parakstus un kā salīdzināmi mantotais un galapunktos balstītais piegādes modelis.

ThunderPhone sūta HTTP `POST` pieprasījumus uz jūsu serveri, kad zvana
laikā kaut kas notiek — sākas ienākošs zvans, zvans beidzas, tiek pabeigta
novērtēšanas izpilde, tiek aktivizēts brīdinājums un tā tālāk. Ir **divi piegādes
modeļi**:

<CardGroup cols={2}>
  <Card title="Tīmekļa aizķeres galapunkti (ieteicams)" icon="bolt" href="/lv/webhooks/endpoints">
    Vairāki URL, atsevišķi noslēpumi katram galapunktam, notikumu filtri katram galapunktam
    un automātiski atkārtoti mēģinājumi.
    Pārvaldiet, izmantojot `GET/POST/PATCH/DELETE /v1/developer/webhook-endpoints`.
  </Card>

  <Card title="Mantotā tīmekļa aizķere ar vienu URL" icon="link" href="/api-reference/organizations#legacy-single-url-webhook">
    Viens URL katrai organizācijai. Ietver zvana dzīves cikla notikumus, tostarp
    **bloķējošo** konfigurācijas apmaiņu. Pārvalda, izmantojot `GET/PUT /v1/webhook`.
  </Card>
</CardGroup>

Visi desmit notikumu veidi [notikumu katalogā](/lv/webhooks/events) tiek
piegādāti, izmantojot tīmekļa aizķeres galapunktus. Seši zvana dzīves cikla notikumi
(`telephony.incoming`, `telephony.complete`, `telephony.tool`,
`web.incoming`, `web.complete`, `web.tool`) tiek sūtīti **arī** uz
mantoto tīmekļa aizķeri ar vienu URL — ja jums ir gan mantotais URL, gan
atbilstošs galapunkts, jūs saņemat notikumu abos ceļos. Bloķējošā
darbība ([`telephony.incoming` / `web.incoming` konfigurācijas
apmaiņa](/lv/webhooks/call-incoming) un tīmekļa aizķeres režīma
[rīku izsaukšana](/lv/tools/overview)) ir pieejama
tikai mantotajā ceļā; katra piegāde uz galapunktu ir paziņojums bez atbildes gaidīšanas.

## Satura formāts

Piegādes uz galapunktiem ir JSON objekts ar `data`, `event_id` un
`type`:

```json theme={null}
{
  "data": {
    "call_id": 987654321,
    "from_number": "+14155550199",
    "to_number": "+15551234567"
  },
  "event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
  "type": "telephony.incoming"
}
```

`event_id` ir unikāls katram ģenerētajam notikumam. Tas ir identisks atkārtotos
mēģinājumos **un** visos galapunktos, kas saņem notikumu — izmantojiet to
dublikātu novēršanai.

Mantotā tīmekļa aizķere ar vienu URL sūta to pašu `type` un `data`, bet
**bez** `event_id`:

```json theme={null}
{
  "type": "telephony.incoming",
  "data": { "call_id": 987654321, "from_number": "+14155550199", "to_number": "+15551234567" }
}
```

Pārsūtē katrs pamatteksts tiek serializēts kanoniski — atslēgas sakārtotas
alfabētiski, bez atstarpēm, UTF-8. Skaisti formatētie piemēri šajā
dokumentācijā ir paredzēti tikai lasāmībai.

Skatiet [notikumu katalogu](/lv/webhooks/events), lai iegūtu pilnu notikumu
veidu un satura lauku sarakstu.

## Paraksta verifikācija

Katram pieprasījumam galvenē `X-ThunderPhone-Signature` ir HMAC-SHA256 paraksts, kas aprēķināts pār **neapstrādāto pieprasījuma
pamattekstu**. Parakstīšanas atslēga ir galapunkta `secret` (vai jūsu organizācijas līmeņa tīmekļa aizķeres `secret` mantotām
piegādēm).

### Darbības

1. Nolasiet neapstrādāto pieprasījuma pamattekstu **pirms** jebkādas parsēšanas.
2. Aprēķiniet `hmac_sha256(secret, body).hexdigest()`.
3. Salīdziniet to konstantā laikā ar galveni `X-ThunderPhone-Signature`.

Mēs parakstām tieši tos baitus, ko nosūtām, un šie baiti ir
kanoniskā JSON serializācija (sakārtotas atslēgas, kompakti atdalītāji). Tāpēc
verifikācija pret neapstrādāto pamattekstu vienmēr darbojas — un, ja jūsu ietvars
nodrošina tikai parsētu JSON, tā atkārtota serializācija ar sakārtotām atslēgām un
kompaktiem atdalītājiem rada identiskus baitus. Abas metodes ir aprakstītas
[verifikācijas ceļvedī](/lv/guides/verify-webhook-signatures).

<CodeGroup>
  ```python Python theme={null}
  import hmac
  import hashlib

  def verify_signature(body: bytes, signature: str, secret: str) -> bool:
      expected = hmac.new(
          secret.encode("utf-8"),
          body,
          hashlib.sha256,
      ).hexdigest()
      return hmac.compare_digest(expected, signature or "")

  # Example Flask handler
  from flask import Flask, request, abort
  app = Flask(__name__)

  @app.post("/thunderphone-webhook")
  def handle():
      body = request.get_data()
      sig = request.headers.get("X-ThunderPhone-Signature", "")
      if not verify_signature(body, sig, WEBHOOK_SECRET):
          abort(401)
      event = request.get_json()
      # dispatch on event["type"] …
      return "", 204
  ```

  ```javascript Node.js (Express) theme={null}
  import crypto from "node:crypto";
  import express from "express";

  function verifySignature(body, signature, secret) {
    const expected = crypto
      .createHmac("sha256", secret)
      .update(body)
      .digest("hex");
    if (!signature || expected.length !== signature.length) return false;
    return crypto.timingSafeEqual(
      Buffer.from(expected),
      Buffer.from(signature),
    );
  }

  const app = express();
  app.post(
    "/thunderphone-webhook",
    express.raw({ type: "application/json" }),
    (req, res) => {
      const sig = req.header("X-ThunderPhone-Signature") || "";
      if (!verifySignature(req.body, sig, process.env.WEBHOOK_SECRET)) {
        return res.sendStatus(401);
      }
      const event = JSON.parse(req.body.toString("utf8"));
      // dispatch on event.type …
      res.sendStatus(204);
    },
  );
  ```
</CodeGroup>

## Piegādes semantika

Šī semantika attiecas uz **galapunktu** piegādēm. Mantotais viena URL
webhook ir viens sinhrons mēģinājums bez atkārtotiem mēģinājumiem.

<AccordionGroup>
  <Accordion title="Atkārtoti mēģinājumi">
    Katrs notikums tiek mēģināts piegādāt vienu reizi nekavējoties. Jebkura `2xx` atbilde
    apstiprina piegādi. Jebkura cita rezultāta gadījumā (ne-2xx,
    savienojuma kļūda, noildze) atkārtojam mēģinājumu **pēc 1 min, 5 min, 30 min, 2 h, 6 h,
    12 h un 24 h pēc pirmā mēģinājuma** — 8 mēģinājumi
    24 stundu laikā. Ja visi mēģinājumi neizdodas, piegāde tiek pārtraukta un galapunktam
    sadaļā [webhook galapunkti](/lv/webhooks/endpoints) tiek iestatīts
    `status="failing"`. Atgrieziet `2xx`, tiklīdz lietderīgā slodze ir droši pieņemta;
    apstrādājiet to asinhroni.
  </Accordion>

  <Accordion title="Secība">
    Piegādes secība tiek nodrošināta pēc iespējas. Praksē notikumus piegādājam to
    izraisīšanas secībā, taču kļūmju gadījumā atkārtotie mēģinājumi var mainīt secību.
    Vienmēr noņemiet dublikātus un saskaņojiet pēc `call_id` / objekta id.
  </Accordion>

  <Accordion title="Dublikāti">
    Piegāde ir **vismaz vienu reizi**: atkārtots mēģinājums pēc atbildes, kuru
    nesaņēmām, var dublēt notikumu. Katram atkārtotajam mēģinājumam ir tas pats
    `event_id`, tāpēc saglabājiet apstrādātos id un izlaidiet atkārtojumus. `event_id` ir
    kopīgs arī starp galapunktiem — divi galapunkti, kas abonē vienu un to pašu
    notikumu, saņem vienādu `event_id`.
  </Accordion>

  <Accordion title="Noildzes">
    Galapunktu piegādēm katram mēģinājumam ir **30 s** noildze. Mantotajā ceļā bloķējošie
    pieprasījumi, kas nosaka aktīva zvana darbību —
    [`telephony.incoming` / `web.incoming`](/lv/webhooks/call-incoming)
    konfigurācijas apmaiņa — pārsniedz noildzi pēc **10 s**, taču lēna
    atbilde aizkavē zvana pieņemšanu, tāpēc centieties atbildēt pāris
    sekunžu laikā. [Rīku izsaukšana](/lv/tools/overview) webhook režīmā ļauj 20 s.
  </Accordion>

  <Accordion title="Avota IP adreses">
    Izejošie webhook tiek sūtīti no ThunderPhone mākoņpakalpojuma IP adrešu diapazona.
    Ja jūsu ugunsmūrim nepieciešams atļauto saraksts, sazinieties ar atbalsta komandu, un mēs
    kopīgosim pašreizējos diapazonus.
  </Accordion>
</AccordionGroup>

## Izvēle starp mantotajiem un uz galapunktiem balstītajiem webhook

| Funkcija                         | Mantotais (`/v1/webhook`)                                                | Galapunkti (`/v1/developer/webhook-endpoints`) |
| -------------------------------- | ------------------------------------------------------------------------ | ---------------------------------------------- |
| URL skaits                       | 1 katrai organizācijai                                                   | Vairāki katrai organizācijai                   |
| Notikumu tvērums                 | Tikai `telephony.*` / `web.*`                                            | Visi 10 notikumu tipi                          |
| Notikumu filtrs                  | —                                                                        | Katram galapunktam                             |
| Atkārtoti mēģinājumi             | Nav                                                                      | 8 mēģinājumi 24 h laikā                        |
| Aploksne                         | `type` + `data`                                                          | `type` + `data` + `event_id`                   |
| Slepenās atslēgas rotācija       | Aizstāj vienu slepeno atslēgu                                            | Slepenā atslēga katram galapunktam             |
| Atspējošana bez dzēšanas         | —                                                                        | `status=disabled`                              |
| Statusa redzamība                | —                                                                        | `active` / `disabled` / `failing`              |
| Bloķējoša konfigurācijas apmaiņa | Jā ([`telephony.incoming` / `web.incoming`](/lv/webhooks/call-incoming)) | Nekad — tikai paziņojumi                       |
| Vispiemērotākais                 | Dinamiska zvanu konfigurācija                                            | Notikumu patēriņš produkcijā                   |

Jaunajām integrācijām notikumi jāsaņem, izmantojot uz galapunktiem balstītus
webhook. Saglabājiet (vai pievienojiet) mantoto URL tikai tad, ja zvanus
dinamiski konfigurējat to pieņemšanas brīdī vai izmantojat rīku izsaukšanu webhook režīmā — šīs
pieprasījuma/atbildes apmaiņas darbojas tikai mantotajā ceļā.

***

## Saistītie resursi

<CardGroup cols={2}>
  <Card title="Notikumu katalogs" icon="list" href="/lv/webhooks/events">
    Visi notikumu tipi un to lietderīgās slodzes.
  </Card>

  <Card title="Webhook galapunkti" icon="bolt" href="/lv/webhooks/endpoints">
    Pārvaldiet vairākus galapunktus, notikumu filtrus un slepenās atslēgas.
  </Card>

  <Card title="telephony.incoming / web.incoming" icon="phone" href="/lv/webhooks/call-incoming">
    Bloķējošais pieprasījums, uz kuru jūsu serverim jāatbild, lai konfigurētu zvanus.
  </Card>

  <Card title="telephony.complete / web.complete" icon="phone" href="/lv/webhooks/call-complete">
    Pēc zvana nosūtīta lietderīgā slodze ar transkriptu, ierakstu un metrikām.
  </Card>
</CardGroup>
