* feat(docs): mirror every docs/ page in all 65 locales Extends the documentation mirrors from the 22-page core set (#13940) to every Markdown page under docs/: 152 sources x 65 locales = 9,880 mirrors (6,208 new), language bars rewritten for the full locale list, state adopted so the blocking drift gate now covers all 152 pages. run-translation.mjs: an oversized block made only of table rows or list items (PROVIDER_REFERENCE.md 244-row table, FREE_TIERS.md 71-item list) is cut at item boundaries and rejoined without a blank line — the single 16-40 KB request outlived the backend socket for verbose scripts. 48 older mirrors whose tables had lost rows were retranslated with --force. * docs(i18n): refresh mirrors for the sources the base changed since the branch cut Section-level retranslation of the 29 docs (and README.md) whose source or mirrors moved on release/v3.8.51 during the run, then state adoption; the drift gate is green again on the merged tree.
14 KiB
Webhooks (Hrvatski)
🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW
Izvor istine:
src/lib/webhookDispatcher.ts,src/lib/db/webhooks.ts,src/app/api/webhooks/Posljednje ažuriranje: 2026-06-28 — v3.8.40
OmniRoute može slati HTTP webhookove pri događajima na platformi. Upotrijebite ih za integraciju sa Slackom, PagerDutyjem, Datadogom, internim servisima za upozoravanje ili bilo kojim HTTP primateljem.
Dispečer potpisuje svaku isporuku pomoću HMAC-SHA256, ponavlja pokušaje pri privremenim pogreškama, prati pouzdanost isporuke za svaki webhook i automatski onemogućuje krajnje točke koje nastavljaju otkazivati.
Podržani događaji
Tip WebhookEvent (src/lib/webhooks/eventDescriptions.ts, koristi ga src/lib/webhookDispatcher.ts) trenutačno modelira točno četiri događaja:
| Događaj | Aktivira se kada |
|---|---|
request.completed |
Posredovani zahtjev uspješno završi |
request.failed |
Posredovani zahtjev ne uspije nakon svih ponovnih pokušaja/rezervnih opcija |
quota.exceeded |
API ključ prijeđe prag proračuna/kvote |
test.ping |
Sintetički događaj koji koristi testna krajnja točka |
Pretplate prihvaćaju doslovnu vrijednost "*" za primanje svakog događaja. Nepoznati nazivi događaja
u events zanemaruju se tijekom slanja.
Napomena: API dispečera je povezan, ali produkcijska mjesta poziva za neke od događaja koji nisu
test.pingjoš se uvode. Provjeritegrep dispatchEventkako biste vidjeli koji putovi trenutačno pozivaju dispečer u vašem izdanju.
Arhitektura
Pozivatelj (rukovatelj, servis, nadzornik)
dispatchEvent(event, data) [src/lib/webhookDispatcher.ts]
-> getEnabledWebhooks() [src/lib/db/webhooks.ts]
-> filtriranje prema webhook.events
-> za svako podudaranje (paralelno):
deliverWebhook(url, payload, secret)
izradi korisni sadržaj { event, timestamp, data }
potpiši tijelo s HMAC-SHA256 (ako postoji tajna)
POST s vremenskim ograničenjem od 10 s
ponovi do 3 puta pri pogreškama 5xx / mrežnim pogreškama
recordWebhookDelivery(id, status, success)
-> disableWebhooksWithHighFailures(10)
Slanje je za pozivatelja tipa „pokreni i zaboravi”: Promise.allSettled zanemaruje
pogreške pojedinačnih webhookova kako jedan neispravan primatelj ne bi mogao blokirati ostale.
Potpisivanje HMAC-om
Kada webhook ima secret, OmniRoute potpisuje JSON tijelo i šalje:
Content-Type: application/json
User-Agent: OmniRoute-Webhook/1.0
X-Webhook-Event: <događaj>
X-Webhook-Timestamp: <ISO-8601>
X-Webhook-Signature: sha256=<heksadecimalni HMAC-SHA256(tajna, tijelo)>
Nazivi zaglavlja koriste prefiks
X-Webhook-*(neX-OmniRoute-*). Vrijednost potpisa jesha256=<hex>— provjerite cijeli prefiks.
Ako se createWebhook pozove bez tajne, DB modul generira jednu
(whsec_<48 hex>) pa su svi webhookovi prema zadanim postavkama potpisani.
Provjera na primatelju
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(rawBody: string, signature: string, secret: string) {
const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(signature);
return a.length === b.length && timingSafeEqual(a, b);
}
Uvijek provjeravajte prema sirovom tijelu zahtjeva, prije bilo kakvog parsiranja JSON-a.
Pravila ponovnih pokušaja i neuspjeha
deliverWebhook(url, payload, secret, maxRetries = 3):
- Vremensko ograničenje od 10 sekundi po pokušaju (
AbortController). - HTTP 2xx smatra se uspjehom.
- HTTP 3xx/4xx smatra se konačnim statusom bez ponovnog pokušaja — bilježi se kao isporučeno
uz
success = res.ok. - Za HTTP 5xx i mrežne pogreške pokušaj se ponavlja uz eksponencijalno odgađanje:
2^attempt * 1000 ms(1 s, 2 s, 4 s). - Nakon
maxRetries, isporuka se bilježi kao neuspješna. - Svaka isporuka ažurira
last_triggered_at,last_statuste poništava ili povećavafailure_count. - Dispečer poziva
disableWebhooksWithHighFailures(10)nakon svakog slanja svim primateljima, pa se svaki webhook sfailure_count >= 10automatski onemogućuje.
Baza podataka
Tablica webhooks (migracija 011_webhooks.sql):
| Stupac | Vrsta | Napomene |
|---|---|---|
id |
TEXT PK | UUID |
url |
TEXT | Odredišni URL |
events |
TEXT | JSON polje; zadano ["*"] |
secret |
TEXT | HMAC tajna (automatski generirana ako nije navedena) |
enabled |
INT | 0/1; zadano 1 |
description |
TEXT | Neobavezna oznaka čitljiva ljudima |
created_at |
TEXT | datetime('now') |
last_triggered_at |
TEXT | Ažurira se pri svakom pokušaju isporuke |
last_status |
INT | HTTP status posljednjeg pokušaja (0 = mreža) |
failure_count |
INT | Vraća se na 0 pri uspjehu, +1 pri neuspjehu |
Povijest isporuka pohranjuje se u namjenskoj tablici webhook_deliveries
(migracija 069_webhook_deliveries.sql, zapisuje se putem
src/lib/db/webhookDeliveries.ts::insertDelivery pri svakom pokušaju), uz
zbirne brojače u retku tablice webhooks. Metapodaci o vrsti (Slack / Discord /
Telegram / prilagođeni transformatori korisnog sadržaja) dodani su migracijom 070_webhooks_kind_metadata.sql.
REST API
Sve krajnje točke zahtijevaju autentifikaciju za upravljanje (requireManagementAuth).
| Krajnja točka | Metoda | Opis |
|---|---|---|
/api/webhooks |
GET | Popis webhookova (tajne su maskirane) |
/api/webhooks |
POST | Stvaranje webhooka |
/api/webhooks/[id] |
GET | Pojedinosti webhooka (cijela tajna) |
/api/webhooks/[id] |
PUT | Ažuriranje polja |
/api/webhooks/[id] |
DELETE | Uklanjanje |
/api/webhooks/[id]/test |
POST | Slanje događaja test.ping (bez ponovnih pokušaja) |
/api/webhooks/[id]/deliveries |
GET | Nedavni pokušaji isporuke za jedan webhook |
/api/webhooks/validate-url |
POST | Prethodna provjera URL-a (zaštita od SSRF-a) |
GET /api/webhooks maskira tajnu u obliku <prvih 10 znakova>... kako bi se izbjeglo njezino
otkrivanje na stranicama s popisima. Upotrijebite GET za [id] kada vam je tajna doista potrebna.
Stvaranje webhooka
curl -X POST http://localhost:20128/api/webhooks \
-H "Cookie: auth_token=..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.slack.com/services/...",
"secret": "whsec_my_shared_secret",
"events": ["quota.exceeded", "request.failed"],
"description": "Slack alerts"
}'
Ako je secret izostavljen, poslužitelj generira tajnu whsec_<hex> i vraća
je u odgovoru.
Testiranje webhooka
curl -X POST http://localhost:20128/api/webhooks/<id>/test \
-H "Cookie: auth_token=..."
Vraća { delivered, status, error }. Ne izvode se ponovni pokušaji — korisno za
brzu provjeru prihvaća li primatelj korisni sadržaj i potpis.
Nadzorna ploča
Stranica nadzorne ploče na /dashboard/webhooks (pogledajte
src/app/(dashboard)/dashboard/webhooks/page.tsx) omogućuje:
- Stvaranje/uređivanje webhookova s izbornikom događaja
- Pokazatelj statusa (aktivan / neaktivan / s pogreškom) na temelju vrijednosti
enabled,failure_countilast_status - Testnu isporuku jednim klikom
- Ručno uključivanje/isključivanje
Primjeri korisnog sadržaja
request.completed
{
"event": "request.completed",
"timestamp": "2026-05-13T20:30:00.123Z",
"data": {
"trace_id": "...",
"api_key_id": "...",
"provider": "openai",
"model": "gpt-5",
"status": 200,
"tokens_in": 142,
"tokens_out": 350,
"cost_usd": 0.0042
}
}
test.ping
{
"event": "test.ping",
"timestamp": "2026-05-13T20:32:00.000Z",
"data": {
"message": "Testna isporuka webhooka iz OmniRoutea",
"webhookId": "<uuid>"
}
}
Strukture polja za događaje koji nisu test.ping definirane su mjestima poziva koja ih
emitiraju; objekt data smatrajte kompatibilnim s budućim verzijama (dodajte polja, nemojte se oslanjati na
njihovu odsutnost).
Najbolje prakse
- Provjerite potpis pri svakoj isporuci u odnosu na neobrađeno tijelo — time se sprječavaju lažirani POST zahtjevi od bilo koga tko pogodi URL vašeg webhooka.
- Odgovorite statusom 2xx unutar ~5 sekundi — dispečer prekida čekanje nakon 10 s. Spori
primatelji trošit će ponovne pokušaje i povećavati
failure_count. - Učinite rukovatelje idempotentnima — ponovni pokušaji i semantika isporuke najmanje jednom znače da su duplikati mogući.
- Pretplaćujte se minimalno — navedite samo događaje koje doista obrađujete;
"*"će povećati troškove na primateljima koje ne kontrolirate. - Pratite
failure_count— krajnje točke automatski se onemogućuju nakon 10 uzastopnih neuspjeha; ponovno ih postavite pozivomPUT /api/webhooks/[id]senabled: truenakon ispravka primatelja. - Povremeno rotirajte tajne — pošaljite novi
secretmetodomPUT, implementirajte novu vrijednost na primatelju i potvrdite je putem testne krajnje točke.
Pogledajte i
- API_REFERENCE.md — cjelovito sučelje API-ja za upravljanje
- RESILIENCE_GUIDE.md — semantika prekidača strujnog kruga / razdoblja čekanja
iza neuspjeha pružatelja prikazanih putem
request.failed - Izvor:
src/lib/webhookDispatcher.ts,src/lib/db/webhooks.ts