Reference webhook payloadu a podpisu
Každá webhook integrace ve FluoTestu odešle při odeslání kvízu HTTP POST požadavek s JSON tělem. Tato stránka popisuje formát požadavku, výchozí pole payloadu, alternativní tvar payloadu používaný s mapováním polí a systém podpisu.
Naposledy aktualizováno
Jak vypadá payload webhooku ve FluoTestu?
Ve výchozím stavu jde o plochý JSON objekt s identifikátory odpovědi, kontaktními údaji, skóre, úrovní nebo výsledkem, celým objektem odpovědí a časem odeslání. Pokud je nastaven podpisový klíč, požadavky obsahují hlavičku X-FluoTest-Signature (HMAC-SHA256 z těla požadavku).
Konfigurace
Webhook integrace se konfiguruje cílovou URL adresou a volitelným podpisovým klíčem. Není potřeba žádné OAuth ani propojení účtu třetí strany.
Formát požadavku
Každý webhook požadavek se odesílá s touto metodou a hlavičkami:
| Hlavička | Hodnota | Poznámky |
|---|---|---|
| Method | POST | Vždy POST požadavek. |
| Content-Type | application/json | Tělo je kódováno jako JSON. |
| User-Agent | FluoTest-Webhook/1.0 | Identifikuje požadavek jako pocházející z FluoTestu. |
| X-FluoTest-Event | submission.created | Jediný v současnosti odesílaný typ události. |
| X-FluoTest-Signature | sha256=<hex> | Přítomna pouze pokud je pro webhook nastaven podpisový klíč. |
Výchozí pole payloadu
Bez nastaveného mapování polí je tělo požadavku plochý JSON objekt:
{
"submission_id": "8f2b1c3a-...",
"test_id": "3a9d7e10-...",
"test_name": "Lead Fit Quiz",
"email": "[email protected]",
"first_name": "Jane",
"last_name": "Doe",
"company": "Acme Inc",
"contact_type": "email",
"respondent_name": "Jane Doe",
"total_score": 82,
"max_score": 100,
"score_percent": 82,
"tier": "High fit",
"scores": null,
"outcome": null,
"outcomes": null,
"disqualified": false,
"answers": {
"sections": [
{
"section_title": "Section 1",
"questions": [
{
"question_id": "q1",
"question_text": "What's your role?",
"question_type": "multiple_choice",
"answer": "Founder"
}
]
}
]
},
"submitted_at": "2026-07-10T14:32:00.000Z"
}| Pole | Typ | Popis |
|---|---|---|
| submission_id | string | Unikátní ID odpovědi. |
| test_id | string | ID kvízu. |
| test_name | string | Název kvízu. |
| string | null | E-mail respondenta, pokud byl sesbírán. | |
| first_name | string | null | Křestní jméno respondenta, pokud bylo sesbíráno. |
| last_name | string | null | Příjmení respondenta, pokud bylo sesbíráno. |
| company | string | null | Název společnosti, pokud byl sesbírán. |
| contact_type | string | null | Jaký kontaktní způsob byl sesbírán: „email“, „phone“, nebo null. |
| respondent_name | string | null | Celé jméno, pokud byla zodpovězena otázka na jméno. |
| total_score | number | Celkové skóre respondenta. |
| max_score | number | Maximální možné skóre. |
| score_percent | number | Skóre vyjádřené v procentech. |
| tier | string | null | Popisek odpovídající bodovací úrovně (kvízy s jedním skóre). |
| scores | object | null | Skóre po kategoriích u kvízů s více skóre; jinak null. |
| outcome | string | null | Klíč odpovídajícího primárního výsledku (pouze Pro systém výsledků). |
| outcomes | string[] | null | Klíče všech odpovídajících výsledků. |
| disqualified | boolean | Zda byl respondent diskvalifikován. |
| answers | object | Vnořené sekce/otázky/odpovědi — viz níže. |
| submitted_at | string | Časové razítko odeslání ve formátu ISO 8601. |
Odeslání jen některých polí
Webhook lze nastavit tak, aby odesílal jen vybranou podmnožinu výše uvedených polí. submission_id a test_id jsou vždy zahrnuty bez ohledu na tento výběr, takže každý payload lze dohledat ke zdroji.
Režim mapovaného payloadu
Pokud je pro webhook nastaveno mapování polí (viz Mapování polí a opakování synchronizací), tvar payloadu se změní: mapovaná pole vytvořená pravidly mapování nahradí plochou strukturu, spolu s případnými štítky, a celý výchozí payload je beze změny zahrnut pod klíčem raw.
{
"mapped": { "email": "[email protected]", "score": 82 },
"tags": ["High fit"],
"raw": { "submission_id": "8f2b1c3a-...", "...": "..." }
}Ověření podpisu
Pokud je nastaven podpisový klíč, každý požadavek obsahuje hlavičku X-FluoTest-Signature: hexadecimální HMAC-SHA256 otisk přesného těla požadavku, vypočtený se sdíleným klíčem a s prefixem sha256=. Na přijímací straně spočítejte stejný otisk z nezměněného těla požadavku a porovnejte ho s hlavičkou, abyste ověřili, že požadavek pochází z FluoTestu a nebyl cestou pozměněn.
const crypto = require("crypto");
function isValidSignature(rawBody, header, secret) {
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return header === expected;
}Doručení, opakování a selhání
Webhook požadavek má časový limit 10 sekund. Odpověď mimo rozsah 2xx je považována za neúspěšné doručení. Neúspěšná doručení se automaticky opakují — viz Mapování polí a opakování synchronizací pro harmonogram opakování a způsob zaznamenávání selhání.
Často kladené otázky
Co spouští webhook ve FluoTestu?
Webhook se spustí jednou při každém odeslání kvízu, s typem události submission.created. V současnosti neexistuje žádný jiný typ události.
Jak ověřím hlavičku X-FluoTest-Signature?
Spočítejte HMAC-SHA256 otisk nezměněného těla požadavku pomocí podpisového klíče nastaveného pro webhook, zakódujte ho hexadecimálně, přidejte prefix sha256= a porovnejte ho s hodnotou hlavičky pomocí porovnání v konstantním čase.
Co se stane, když je můj endpoint nedostupný nebo vrátí chybu?
Doručení se označí jako neúspěšné a automaticky se opakuje s prodlevou, až 3 další pokusy, pokud selhání není považováno za trvalé.
Můžu si vybrat, která pole se v payloadu odešlou?
Ano. Webhook lze nastavit s konkrétním seznamem polí; do každého požadavku se zahrnou jen tato pole plus submission_id a test_id.
Související