Automatizálás

Webhookok

A Posty szól a rendszerednek, ha egy bejegyzés kiment vagy elbukott. Események, a törzs alakja és az aláírás ellenőrzése.

Mire való

A webhook a fordított irány: nem te kérdezed le a Postyt, hanem mi szólunk a rendszerednek, amikor történik valami. Kiment egy bejegyzés, elbukott egy közzététel, lecsatlakozott egy csatorna.

A funkció a Pro csomagtól érhető el, a bal oldali menü Automatizálások pontja alatt, a Webhookok fülön. A csomag határozza meg, hány webhookod lehet.

Webhook létrehozása

  1. 1
    Webhook hozzáadása
    Adj neki nevet, és add meg annak a végpontodnak a címét, ami fogadja a kéréseket. HTTPS-cím kell.
  2. 2
    Válaszd ki az eseményeket
    Kiválaszthatsz néhányat, vagy hagyhatod üresen. Az üres lista mindent jelent, a később hozzáadott eseményeket is.
  3. 3
    Válaszd ki a csatornákat
    A webhook szűkíthető meghatározott csatornákra, ha csak azok érdekelnek.
  4. 4
    Mentsd el, és jegyezd fel az aláíró titkot
    A titok whsec_ előtaggal kezdődik. A webhook szerkesztő ablakában bármikor megnézhető és újragenerálható.
Az üres eseménylista mindent jelent

Ha nem választasz eseményt, minden eseményt megkapsz, beleértve azokat is, amiket később veszünk fel. Ha kiválasztasz hatot, pontosan azt a hatot kapod, és egy hetedik, később hozzáadott esemény nem érkezik meg ehhez a webhookhoz.

Az események

EseményMikor
post.publishedEgy bejegyzés kiment egy csatornára.
post.failedEgy bejegyzés hibaállapotba került: a platform visszautasította, a token érvénytelenné vált, a csatorna offline vagy letiltott volt, vagy a csomag kerete nem engedte.
channel.disconnectedA hozzáférés megszűnt, és a csatorna offline lett. A csatorna sora addig nem publikál semmit, amíg újra be nem kötöd.
channel.refresh_neededA token megújítása félúton elakadt. A csatorna nincs offline, de kézzel be kell fejezni a bekötést.
channel.disabledA csatorna le van tiltva: vagy te kapcsoltad ki, vagy a számlázási egyeztetés tiltotta le csomagváltás után.
channel.enabledEgy felfüggesztett csatorna újra bekapcsolt.

Nincs channel.connected esemény: a bekötés több lépésből álló folyamat, aminek a köztes állapotairól nem érdemes jelenteni.

Minden kézbesítés visz egy X-Posty-Event fejlécet is, de a törzsben lévő event mezőre ágazz el: a fejléc nincs benne az aláírásban, a mező igen.

A kérés törzse

A törzs mindig JSON tömb, minden eseménynél. Ne feltételezd, hogy a hossza mindig egy.

post.published

[
  {
    "id": "cm6tcts4f0005qcwit25cis26",
    "content": "Ez az első bejegyzés Instagramra",
    "publishDate": "2026-09-15T09:00:00.000Z",
    "releaseURL": "https://instagram.com/p/...",
    "state": "PUBLISHED",
    "integration": {
      "id": "cm6s4uyou0001i2r47pxix6z1",
      "name": "Posty",
      "providerIdentifier": "instagram",
      "picture": "https://uploads.posty.hu/...jpeg",
      "type": "social"
    },
    "event": "post.published"
  }
]

A publishDate UTC, mint minden időbélyeg a Postyban.

post.failed

Ugyanaz az objektum, kiegészítve az error mezővel. A state értéke ERROR, a releaseURL pedig null, mert nem történt közzététel. Az error a platform saját mondata, ha van ilyen, egyébként null.

channel események

[
  {
    "event": "channel.disconnected",
    "reason": "token_revoked",
    "detail": "— access was removed in the account's Meta settings",
    "integration": {
      "id": "cm6s4uyou0001i2r47pxix6z1",
      "name": "Posty",
      "providerIdentifier": "instagram",
      "picture": "https://uploads.posty.hu/...jpeg",
      "type": "social"
    }
  }
]

A reason zárt halmaz: token_revoked, refresh_failed, manual, plan_limit. Erre ágazz el. A detail szabad szöveg angolul vagy null: ember olvassa, ne a kódod.

Az aláírás ellenőrzése

Minden kézbesítés alá van írva, az X-Posty-Signature fejlécben:

X-Posty-Signature: t=1770000000,v1=10bd17b41e83eee170010df01daeeaa0edf2f939afa6e97f41e1fa7bd27e6191
  • t: Unix idő másodpercben, UTC, az aláírás pillanatában.
  • v1: kisbetűs hexadecimális HMAC-SHA256(titok, "<t>.<nyers törzs>").
  • A kulcs a webhook saját aláíró titka, whsec_ előtaggal.

Ez szándékosan ugyanaz az alak, mint a Stripe aláírása, így a meglévő Stripe-ellenőrző könyvtárak működnek vele: csak a fejléc nevét és a titkot kell átírni.

A nyers törzsre írj alá, ne az újraszerializáltra

A JSON.stringify nem kanonikus: a kulcsok sorrendje, az unicode-escapelés és a számok formázása implementációnként eltér. Egy fogadó rendszer, amely előbb feldolgozza a törzset, majd újra sztringgé alakítja, más lenyomatot számol, és visszautasít egy tökéletesen jó kézbesítést. A törzset a feldolgozás előtt olvasd ki nyersen.

Ellenőrzés lépésről lépésre

  • Olvasd ki a nyers törzset és az X-Posty-Signature fejlécet.
  • Bontsd a fejlécet vesszőnél, majd minden részt az első egyenlőségjelnél: így kapod a t és a v1 értéket.
  • Utasítsd vissza, ha a t és a mostani idő különbsége nagyobb a tűréshatárnál. Mi 300 másodperces tűréshatárral számolunk, ez a visszajátszás elleni védelem.
  • Számold ki a HMAC-SHA256(titok, t + "." + nyersTörzs) értéket kisbetűs hexadecimálisan.
  • Hasonlítsd össze a v1 értékkel, állandó idejű összehasonlítással.
Node.js
const crypto = require('crypto');

function verify(secret, rawBody, header, toleranceSeconds = 300) {
  const parts = Object.fromEntries(
    header.split(',').map((p) => {
      const at = p.indexOf('=');
      return [p.slice(0, at).trim(), p.slice(at + 1).trim()];
    })
  );

  const t = Number(parts.t);
  if (!Number.isFinite(t)) return false;
  if (Math.abs(Math.floor(Date.now() / 1000) - t) > toleranceSeconds) return false;

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${t}.${rawBody}`)
    .digest('hex');

  return (
    expected.length === parts.v1.length &&
    crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1))
  );
}

Egy elkapott kézbesítés kézi ellenőrzéséhez ugyanez shellből:

printf '%s' "$T.$RAW_BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex

A v1 nem véletlenül van verziózva: ha a séma valaha változik, a kézbesítések egy átmeneti ideig a régi és az új elemet is viszik. Arra az elemnévre illeszkedj, amit értesz, és a többit hagyd figyelmen kívül, ne feltételezd, hogy a fejlécnek pontosan két része van.

Amit a fogadó rendszernek tudnia kell

  • Ágazz el a törzsben lévő event mezőre, mielőtt bármit kiolvasnál, és hagyd figyelmen kívül a nem ismert eseményeket: több lesz belőlük.
  • Kulcsolj a bejegyzés id mezőjére, vagy az integration.id és az esemény párosára, és kezeld a megismételt kézbesítést idempotensen.
  • Csatornánként egy kézbesítést várj, nem bejegyzéscsoportonként egyet, és ne feltételezd a sorrendet.
  • Hibás aláírásnál utasítsd vissza a kérést, és naplózd. Ez az egyetlen módja annak, hogy egy hamisított POST látható legyen.

Ha nem eseményekre, hanem lekérdezésre van szükséged, a Értesítések végpont ugyanezeket az eseményeket adja vissza listaként.

Hiányzik valami erről az oldalról? Írj a [email protected] címre, vagy használd a Segítség oldal űrlapját.