Webhooks omvandlar vilket uppströmssystem som helst till en utgivare. Signera en payload, POST:a den, och motorn mappar den till innehåll och bygger om — ingen nyckelutväxling i förfrågningssökvägen, eftersom signaturen är autentiseringen.
Slutpunkten
POST https://your-host/webhooks/{integration} {integration} är en slug som du väljer när du skapar integrationen — inte namnet på en mapper. Var och en har sin egen slug, sin egen hemlighet och en mapper bakom sig, så en webbplats kan ha flera: newsroom, docs-sync, partner-feed. Slugs består av gemener, siffror och bindestreck.
php bin/fastsite webhook:create newsroom --site=blog --mapper=autoseo Det skriver ut den fullständiga URL:en och signeringshemligheten en gång. Du kan göra samma sak från instrumentpanelen, REST API:et eller MCP-verktyget create_webhook — webhooks är webbplatsspecifika, så alla medlemmar av en webbplats kan hantera dem utan att vara administratör.
Signera en förfrågan
Den råa kroppen läses ordagrant och verifieras innan något annat körs. Två huvuden krävs:
X-Fastsite-Signature: t=<unix>,v1=<hmac_sha256("<t>.<body>", secret)>— den signerade strängen är tidsstämpeln, en bokstavlig punkt och de exakta bytes du skickar. Jämförs i konstant tid, inom ett fönster på ±300 sekunder.X-Delivery-Id— unikt per leverans. Det är uppspelningsskyddet: ett upprepat id accepteras med200och ignoreras tyst i stället för att bearbetas två gånger.
Signera de bytes du faktiskt sänder. Att re-serialisera JSON mellan signering och sändning är den vanliga orsaken till att en signatur inte kan verifieras.
Ett genomarbetat exempel
# body.json is the exact bytes you sign and send
SECRET="whsec_…"
BODY=$(cat body.json)
TS=$(date +%s)
SIG=$(printf '%s.%s' "$TS" "$BODY" | \
openssl dgst -sha256 -hmac "$SECRET" | awk '{print $2}')
curl -X POST https://your-host/webhooks/newsroom \
-H "X-Fastsite-Signature: t=$TS,v1=$SIG" \
-H "X-Delivery-Id: $(uuidgen)" \
-H "Content-Type: application/json" \
--data-binary @body.json Vad som returneras
| Kod | Betydelse |
|---|---|
| 202 | Accepterad. Registrerad och köad. |
| 200 | Duplikat leverans-id — redan sett, ingenting gjort. |
| 400 | Saknar X-Delivery-Id. |
| 401 | Saknar eller ogiltig signatur. |
| 404 | Ingen sådan integration, eller så är den inaktiverad. |
Slutpunkten svarar på millisekunder eftersom den bara registrerar och köar. Mappningen, bygget och publiceringen sker i kön efteråt, med nya försök och fördröjning.
Webhooks publicerar; API:et gör det inte
Det här är den enda verkliga skillnaden mellan de två inmatningsvägarna. Att skapa innehåll via REST eller MCP lagrar det och väntar på att du ska publicera. En webhook-leverans kör sin mapper och kedjar sedan ett bygge och en publicering automatiskt — ett uppströmssystem som pushar en artikel förväntar sig att den är live, inte i utkastläge.
Inbyggda mappers
Mappers är kod, inte konfigurationssträngar. Var och en tar en generisk payload och omvandlar den till en motoråtgärd.
| Mapper | Payload | Gör |
|---|---|---|
autoseo | {id, title, body_html, slug?, excerpt?, featured_image_url?, author?, seo_title?, seo_description?, status?, published_at?} | Idempotent artikelinmatning, nycklad på id. |
create_post | {title, body_html, slug?, excerpt?, status?, author?, source_ref?} | Mappar en payload till ett inlägg. |
create_page | Samma som ovan | Mappar en payload till en sida. |
import_media | {url, alt?, decorative?} | Hämtar en fil via URL (SSRF-skyddad) till biblioteket. |
upsert_component | {handle, type, source_code, css?} | Skapar eller uppdaterar en komponent. |
autoseo är den man ska välja för en artikelpipeline. Den är idempotent på payloadens id, så att återleverera uppdaterar det befintliga inlägget i stället för att skapa ett till. Den adopterar även bilder: den utvalda bilden och alla externa <img>-taggar i kroppen hämtas till ditt mediebibliotek och skrivs om till lokala referenser, med alt-text härledd från titeln när källan saknar sådan. Om en bild inte kan hämtas utelämnas den bilden och artikeln publiceras ändå — ett trasigt CDN uppströms ska inte kosta dig nyheten.
För innehållsmappers är status som standard published. Skicka source_ref om du vill att återleverans ska uppdatera i stället för att duplicera.
När något går fel
Varje leverans registreras med sina huvuden, kropp och utfall, så ett misslyckande är granskningsbart snarare än förlorat.
php bin/fastsite webhook:list
php bin/fastsite webhook:deliveries --limit=20
php bin/fastsite webhook:replay <delivery-id> En payload som mappern inte kan använda — ett saknat id, ingen title, felformaterat JSON — markeras som skipped och provas inte igen, eftersom ett nytt försök inte löser problemet. Allt annat som kastar ett fel markeras som failed och provas igen med fördröjning. Replay kör om en lagrad leverans från dess registrerade bytes, så du kan åtgärda en mapper eller en autentiseringsuppgift och bearbeta om utan att be avsändaren försöka igen.
Hemligheter lagras krypterade och kan visas igen från instrumentpanelen för att konfigurera en avsändare. Föredrar du att hämta i stället för att bli pushad? REST API:et och MCP-servern täcker samma operationer.