Ugrás a tartalomra
Dokumentáció

Kézbesítési webhook: cikkek fogadása a saját webhelyén

Az aláírt webhook, amely az AutoPSEO cikkeit a webhelyére küldi: fejlécek, az egyes események és hasznos adataik, a küldendő válaszok, az újrapróbálkozások, a várakozó parancsok és az IndexNow.

Tulajdon → Tartalom → Hol jelennek meg a cikkek19 perc olvasás

Az AutoPSEO minden cikket, amelyet közzétesz, frissít vagy levesz, aláírt HTTPS POST-kérésként elküld a saját webhelyére. A webhelye eltárolja a cikket, és a saját sablonjaival jeleníti meg, így a tartalom az Ön rendszerében marad, és akkor is működik tovább, ha egyszer elhagyja az AutoPSEO-t. Ez az oldal a fogadót építő fejlesztőnek szóló referencia: az aláírás, az összes esemény a hasznos adatával, a válaszok, amelyeket az AutoPSEO olvas, az újrapróbálkozások, a várakozó parancsok és az IndexNow.

A webhook beállítása

  1. Nyissa meg a tulajdon Tartalom oldalát, és lépjen a Hol jelennek meg a cikkek részhez.
  2. Töltse ki a Webhook címe a webhelyén mezőt. Nyilvános gazdanévre mutató https:// URL-nek kell lennie: az IP-címeket és a localhost címet elutasítja a rendszer. Az AutoPSEO nem követ átirányításokat, ezért a végleges címet adja meg.
  3. Töltse ki a Webhelye címe mezőt, például https://example.com. Az egyes tartalomtípusok útvonala ez alá tartozik, így egy /answers típusú cikk a https://example.com/answers/<slug> címen érhető el.
  4. Válassza a Mentés és teszt küldése lehetőséget. Az AutoPSEO létrehoz egy aláíró titkot (whsec_, utána 48 hexadecimális karakter), és pingeli a megadott címet. Az aláírást ellenőrző fogadó ezen az első pingen elbukik, mert még nincs meg a titok.
  5. Jelenítse meg az Aláíró titkot a Megjelenítés vagy a Másolás gombbal, tárolja titokként a webhelyén, majd válassza a Teszt küldése lehetőséget.
  6. Olvassa el a Mit kezel a webhelye részt: minden parancs mellett a Csatlakoztatva, Nincs csatlakoztatva, Bejelentve, nem tesztelt vagy Nem tesztelt állapot látható.

Az új tulajdonokon a cikkeket kezdetben az AutoPSEO üzemelteti a saját címén (lásd: Üzemeltetés), és az üzemeltetés és a webhook egymás mellett is működhet. Amint a webhelye megjeleníti a cikkeket, válassza az Üzemeltetés leállítása az AutoPSEO-n lehetőséget: minden élő cikk átkerül a webhelye címére, és article.published eseményként elmegy a webhookjára. A gombhoz olyan webhook kell, amely válaszolt az utolsó tesztre, valamint meg kell adni a webhelye címét. Amíg az üzemeltetés ki van kapcsolva, a webhook nem távolítható el.

Az Új titok azonnal lecseréli az aláíró titkot, és a régi azonnal megszűnik érvényesíteni. A titok létrehozása után rögtön tegye be az újat a webhelyére.

Az AutoPSEO csak olyan webhookhoz sorol be kézbesítéseket, amelynek utolsó pingjére 2xx válasz érkezett. A sikertelen ping (mentéskor, a Teszt küldése gombnál vagy egy webhelybejárás elején) hibásnak jelöli a webhookot, és a hibás állapot alatt közzétett cikkek nem kerülnek sorba hozzá. Hagyja, hogy a ping mindig válaszoljon, és egy kiesés elhárítása után válassza a Teszt küldése lehetőséget.

Fejlécek és aláírás

Minden kérés POST, JSON törzzsel és a következő fejlécekkel:

FejlécÉrték
Content-Typeapplication/json
User-AgentAutoPSEO-Webhook/1
X-AutoPSEO-EventAz esemény neve, a törzsben is szerepel event néven
X-AutoPSEO-DeliveryA kézbesítés azonosítója, a törzsben is szerepel id néven. Ugyanaz egy kézbesítés minden újrapróbálkozásánál
X-AutoPSEO-TimestampUnix-idő másodpercben, amikor ezt a kísérletet aláírták
X-AutoPSEO-Signaturesha256=, majd a <timestamp>.<nyers törzs> hexadecimális HMAC-SHA256 értéke

A kérés ellenőrzése:

  1. Vegye az időbélyeg-fejlécet, egy pontot, majd a kérés nyers törzsét pontosan úgy, ahogy megérkezett, a JSON-elemzés előtt.
  2. Számítson HMAC-SHA256 értéket erre a karakterláncra. A kulcs a teljes aláíró titok, úgy, ahogy az alkalmazás mutatja, a whsec_ előtaggal együtt, UTF-8 bájtokként.
  3. Kódolja hexadecimálisan az eredményt, és hasonlítsa össze az X-AutoPSEO-Signature sha256= utáni részével, állandó idejű összehasonlítással. Ha eltérnek, utasítsa el a kérést.

Minden kísérletet új, saját időbélyeggel írnak alá, ezért elutasíthatja azokat a kéréseket, amelyek időbélyege messze esik az Ön óráján látott időtől (az öt perc gyakori ablak), anélkül, hogy az újrapróbálkozások megsérülnének. Magát a HMAC-ot az RFC 2104 határozza meg.

Minden törzs tartalmazza az id, event, occurredAt (ISO 8601, UTC) és site: { propertyId, domain } mezőket.

Események

EseményFajtaMikor küldi az AutoPSEO
pingEllenőrzésA webhook mentésekor, a Teszt küldése gombnál és minden webhelybejárás elején
testEllenőrzésSikeres ping után azonnal, parancsonként egy
article.publishedKézbesítésEgy cikk először válik élővé; minden élő cikk, amikor leállítja az üzemeltetést
article.updatedKézbesítésÚj változat válik élővé (frissítés, optimalizálás, visszaállítás, újbóli közzététel levétel után, nyelvek hozzáadása), vagy borítókép került hozzá
article.unpublishedKézbesítésEgy cikket levettek, vagy egy másik oldalba olvasztottak
path.addKézbesítésEgy típusos tartalomtípus új értékét jóváhagyták
path.removeKézbesítésValaki kérte egy érték útvonalának levételét
path.checkHívásMielőtt az AutoPSEO olyan címre tervez oldalt, ahol a webhelyén nincs oldal, vagy új értéket javasol
site.exportHívásWebhelybejáráskor, a napi témaszinkronizáláskor, és mielőtt az AutoPSEO módosít egy élő cikket
articles.adoptedHívásMiután egy bejárás beimportálta a webhelye által exportált cikkeket
site.handoverHívásAmikor valaki tartalomtípusok írását átadja az AutoPSEO-nak, vagy visszaveszi

A kézbesítések egy kimenő postaládán (outbox) keresztül mennek: ugyanabban az adatbázis-kötegben rögzítik őket, mint a változást, azonnal elküldik, újrapróbálják, és várhatnak a webhelyére. A hívások egyszerű kérés-válasz párok: az AutoPSEO a választ azonnal elolvassa. Hogy a path-parancsokat mikor küldi, azt a Típusos oldalak és új útvonalak írja le.

A cikk hasznos adata

Az article.published és az article.updated a teljes cikket tartalmazza, minden nyelvvel együtt:

{
  "id": "0f6d2c1e-7a51-4c1b-9d0e-5b8f3a2e9c41",
  "event": "article.published",
  "occurredAt": "2026-10-12T08:30:00.000Z",
  "site": { "propertyId": "prop_123", "domain": "example.com" },
  "article": {
    "id": "a4c09e2b-6f1d-4e57-8b3a-1d2e3f4a5b6c",
    "slug": "plan-a-content-calendar",
    "path": "/answers/plan-a-content-calendar",
    "type": { "key": "answers", "name": "Answers", "path": "/answers" },
    "lang": "en",
    "langs": ["en", "de"],
    "rev": 1,
    "url": "https://example.com/answers/plan-a-content-calendar",
    "datePublished": "2026-10-12",
    "dateModified": "2026-10-12",
    "contentHash": "9f2c4e1a7b3d5f6081a2c3d4",
    "writer": "platform",
    "category": "Planning",
    "copy": {
      "title": "How to plan a content calendar",
      "metaDescription": "A content calendar in five steps, with a template.",
      "h1": "How to plan a content calendar",
      "directAnswer": "List your topics, give each a date and an owner, then review the plan weekly.",
      "keyTakeaways": ["Plan a quarter at a time.", "Give every piece one owner."],
      "sections": [{ "heading": "Start from your topics", "bodyHtml": "<p>Begin with the searches you want to win.</p>" }],
      "faq": [{ "q": "How far ahead should I plan?", "a": "One quarter is enough for most teams." }],
      "sources": [{ "title": "Creating helpful content", "url": "https://developers.google.com/search/docs/fundamentals/creating-helpful-content" }]
    },
    "translations": { "de": { "title": "Einen Redaktionsplan erstellen", "h1": "Einen Redaktionsplan erstellen" } },
    "cover": {
      "url": "https://app.autopseo.com/media/covers/prop_123/<sha256>.jpg",
      "sha256": "<sha256>",
      "contentType": "image/jpeg",
      "width": 1536,
      "height": 1024
    }
  }
}

A német bejegyzés itt le van rövidítve; minden fordítás ugyanolyan szerkezetű, mint a copy.

MezőJelentése
idA cikk AutoPSEO-azonosítója. Sosem változik, ezért biztonságos kulcs
slugA cím utolsó része. Típusos oldalakon / jellel összefűzött szegmensekből áll, például google/software-engineer
pathA webhelyéhez viszonyított cím: a típus útvonala plusz a slug. Az oldal létrejötte után rögzített
type{ key, name, path }. A key stabil; a path az, ahol a típus cikkei élnek (a webhely gyökerénél üres)
lang, langsAz elsődleges nyelv és a változat összes nyelve
revA változat sorszáma
urlA teljes cím, ahogy az AutoPSEO ismeri: az üzemeltetés kikapcsolása után a webhelyéé, vagy az url, amelyet a fogadója legutóbb válaszként adott
datePublished, dateModifiedYYYY-MM-DD. A közzétételi dátum a későbbi változatokon át változatlan marad
contentHashA változat ujjlenyomata
writerKi írta a változatot: platform (AutoPSEO), mcp (az Ön saját MI-je), user, import (a webhelye saját szövege) vagy aggregate (listaoldal)
copyA cikk az elsődleges nyelvén
translationsA többi nyelv, nyelvkóddal kulcsolva
categoryA webhelye kategóriája a cikkhez, ha a formátuma kategóriákat tart nyilván
topic{ externalId, keyword }, ha a cikk egy, a webhelye által átadott témára készült, így lezárhatja a témát
partsTípusos oldalakon az egyes részek értéke: { "company": "google", "role": "software-engineer" }
kind"list" listaoldalon. A szövege { title, h1, items: [{ from, text }] }, ahol a from annak az oldalnak az útvonala, amelyből az elem származik, a parts pedig megnevezi az általa összegyűjtött értéket
coverAz AutoPSEO által a cikkhez készített borítókép. Egyszer töltse le, és tartsa meg a saját másolatát; a cím sosem változik, mert a fájlnév a kép SHA-256 értéke
basedOnAz article.updated eseményen: az oldala azon változata, amelyből ez a változat készült (lásd az ütközésekről szóló részt)
redirectToAz article.unpublished eseményen összeolvasztás után: hová vezet most a régi cím. Válaszoljon rá 301-gyel, és ne tegyen oda újat

Az article.unpublished ugyanazokat az article mezőket hordozza, kivéve a copy, translations, category és cover mezőket.

A copy belseje

MezőJelentése
title, metaDescription, h1Az oldal címe, a meta description és a főcím
directAnswerA rövid válasz, amely elsőként jelenik meg
keyTakeawaysKarakterláncok listája
sections[{ heading, bodyHtml }]
faq[{ q, a }]
sources[{ title, url, lastVerified? }]
questionOpcionális: a keresők kérdése a saját szavaikkal, ha a formátuma kéri
categoryOpcionális: a webhelye egyik kategóriája
listsOpcionális: kulcs szerinti egyszerű szöveges listák azokhoz a tartalomtípusokhoz, amelyek kérik őket (egy interjúútmutató mintakérdései)

Az AutoPSEO által írt cikkekben a bodyHtml csak a p, ul, li, strong, em, a és code elemeket használja, a hivatkozásokon pedig csak a href marad meg. A webhelye saját szövegéből átvett szöveg megtartja az Ön HTML-jét. Ha a sablonjai megkívánják, futtassa át a saját szanitizálóján is.

Mit válaszoljon a fogadó

Bármely 2xx befejez egy kézbesítést. Az AutoPSEO a válasz törzséből egy opcionális JSON-objektumot is beolvas; tartsa 64 KB alatt, mert a nagyobb válasz hibának számít.

MezőHatása
urlAz https:// cím, ahol a cikk most él. Az AutoPSEO ezt rögzíti a cikk URL-jeként
versionAz oldala verziója, legfeljebb 128 karakteres átlátszatlan karakterlánc. A következő frissítéskor basedOn néven tér vissza
urlsAz https:// címek, amelyeket ez a kézbesítés módosított, az IndexNow számára (minden nyelv, vagy azok a címek, amelyeket már nem szolgál ki). Az [] azt jelenti, hogy semmi sem változott
cover"wanted", ha nincs borítóképe a cikkhez, és a kézbesítés sem hozott. Az AutoPSEO készít egyet, és article.updated eseményben elküldi

A hibaválaszok különböző dolgokat jelentenek:

Az Ön válaszaHogyan érti az AutoPSEOMi történik
4xx { "error": "unknown_event" } tartalommal, vagy 501Ezt a parancsot még nem kezeliA kézbesítés újrapróbálkozás nélkül várakozik
409 { "error": "conflict" } tartalommalA frissítés olyan verzióból készült, amellyel az oldala már nem rendelkezikA kézbesítés újrapróbálkozás nélkül sikertelen lesz, és a cikket a következő módosítása előtt újra beolvassa a webhelyéről
A 408-tól és 429-től eltérő 4xx { "error": "<code>", "details": [] } tartalommal path.add vagy path.remove eseténElutasítás az Ön indoklásávalRögzítve; lásd: Típusos oldalak és új útvonalak
Minden más: nincs válasz 10 másodpercen belül, hálózati hiba, átirányítás, 408, 429, 5xx vagy más 4xxÁtmeneti hibaNövekvő várakozással újrapróbálja

Újrapróbálkozások és felülírt kézbesítések

A kézbesítést a változás mentése után azonnal elküldi a rendszer, egy ötpercenkénti ütemezés pedig a esedékes kézbesítéseket küldi, a legrégebbitől kezdve. Átmeneti hiba után az AutoPSEO a kísérletek között 1 percet, majd 5 percet, 15 percet, 1 órát, 3 órát, 6 órát és 12 órát vár. A nyolcadik sikertelen kísérlet sikertelennek jelöli a kézbesítést, és a Tartalom oldal piros jelvénnyel számolja a webhook mellett.

Ha ugyanahhoz a cikkhez létezik újabb kézbesítés, a még függő régebbit felülírtnak jelöli a rendszer, és sosem küldi el. Minden kézbesítés a teljes cikket hordozza, így a legújabb elég a webhelyének. Az ugyanarra az értékre vonatkozó path-parancsok ugyanígy működnek.

A fogadója ugyanazt a kézbesítést kétszer is láthatja, például ha eltárolta a cikket, de a 10 másodperces időkorlát után válaszolt. Szűrje a duplikátumokat az X-AutoPSEO-Delivery alapján, vagy tegye minden írását idempotenssé úgy, hogy az article.id alapján tárol. Az article.updated olyan cikkhez is érkezhet, amelyet egy article.unpublished után törölt, mert a levett cikk újbóli közzététele frissítést küld: kezelje a frissítéseket "létrehozás vagy csere" műveletként.

Parancsok, amelyeket a webhelye még nem kezel

Egy webhely a protokollt parancsonként is megvalósíthatja. Az AutoPSEO minden parancs állapotát nyilvántartja, és háromféleképpen értesül róla:

  • Tesztek. Minden sikeres ping után az AutoPSEO parancsonként egy test eseményt küld. A törzs { id, event: "test", occurredAt, site, test: { event: "<command>", ... } }, ahol a test egy, a valódi parancshoz hasonló mintát tartalmaz egy <type path>/autopseo-connection-test címről, amely egyetlen webhelyen sem létezik. Ellenőrizze úgy, mintha valódi lenne, ne módosítson semmit, és válaszoljon 2xx-szel: { "test": "<command>", "ok": true } a Csatlakoztatva állapothoz, { "test": "<command>", "ok": false, "error": "unknown_event" } a Nincs csatlakoztatva állapothoz. Az ok: false és más hibakód, például egy olyan cím levétele, amellyel nem rendelkezik, szintén csatlakoztatottnak számít. A minta a test alatt van, sosem a legfelső szinten, így az a fogadó, amely nem tud a tesztekről, nem talál benne cikket.
  • Valódi kézbesítések és hívások. A 2xx csatlakoztatottnak jelöli a parancsot; az unknown_event nem csatlakoztatottnak.
  • A ping válasza. Az autopseo.events mezőben felsorolt parancsok Bejelentve, nem tesztelt állapotban látszanak, amíg egy teszt vagy kézbesítés többet nem mond.

A nem csatlakoztatott parancshoz tartozó kézbesítés várakozik. A Tartalom oldal felsorolja, mi vár, például "A webhelye még nem vesz le cikkeket", és minden kézzel elvégzett teendőhöz van egy Megtörtént a webhelyen gomb; az AutoPSEO ezután sosem küldi el azt. Amikor egy későbbi teszt vagy kézbesítés csatlakoztatottnak találja a parancsot, minden, ami rá várt, elmegy.

A ping válasza

A ping eseményre válaszoljon 2xx-szel. Az a webhely, amely csak fogadja a cikkeket, nem igényel többet. Ha közölni szeretné az AutoPSEO-val, mit tud még a webhelye, vegyen fel egy autopseo objektumot:

{
  "ok": true,
  "autopseo": {
    "version": 1,
    "events": ["article.published", "article.updated", "article.unpublished"],
    "covers": true,
    "indexNow": { "key": "3f1c9a7e5b2d4f60", "keyLocation": "https://example.com/3f1c9a7e5b2d4f60.txt" },
    "export": ["articles", "topics", "profile"],
    "adopt": true,
    "handover": true,
    "types": ["answers"],
    "writer": "site"
  }
}
MezőJelentése
version1. Az objektumot figyelmen kívül hagyja, ha a verzió nem legalább 1
eventsA kezelt parancsok, bejelentettként jelennek meg a tesztelésig
coverstrue, ha az oldalai minden cikkhez borítóképet mutatnak. Az AutoPSEO írója ekkor írás közben elkészíti a borítót, így az első kézbesítés már tartalmazza, és a saját MI-jétől is kér egyet. Lásd: Borítóképek
indexNow{ key, keyLocation? }: az Ön által kiszolgált IndexNow-kulcs (8–128 betű, számjegy és kötőjel), és ha a kulcsfájl nem a /<key>.txt címen van, annak https:// helye
exportMit ad át a site.export: articles, topics, profile
adoptElfogadja az articles.adopted eseményt, így egy teljes bejárás átveheti a meglévő cikkeit
handoverElfogadja a site.handover eseményt
typesAz elfogadott tartalomtípus-kulcsok (legfeljebb 50)
writerKi írja ma az új cikkeit: site vagy autopseo

IndexNow a kiszolgált címekhez

Ha a ping válasza indexNow mezőt jelent be, az AutoPSEO az Ön által elfogadott kézbesítések után pingeli az IndexNow-t az api.indexnow.org címen, a webhelye pedig maga semmit sem pingel.

  • A válasza által felsorolt urls címeket küldi. urls nélkül a válasz url mezőjét küldi, ennek hiányában a cikk URL-jét. Az urls: [] semmit sem küld.
  • Csak a saját gazdagépén lévő címek kerülnek be, ahogy az IndexNow protokoll megköveteli: a keyLocation gazdagépe, ennek hiányában a webhelye címének gazdagépe.
  • Minden kézbesítési kör webhelyenként egy pinget küld, legfeljebb 10 000 címmel.
  • A 200 és a 202 elfogadott. A 429, az 5xx vagy a válasz hiánya megtartja a címeket, és egy óra múlva újrapróbálja, minden alkalommal megduplázva a várakozást legfeljebb egy napig (hosszabban, ha a Retry-After azt kéri), a későbbi kézbesítések által hozzáadott címekkel együtt. A 403 (érvénytelen kulcs) vagy a 422 (a címek nem a gazdagépen vannak) rögzítésre kerül, és a címek elvetésre kerülnek.
  • A Tartalom oldal az utolsó pinget mutatja: mikor volt, hány cím, a HTTP-állapot és a következő próbálkozás.
  • Amíg az AutoPSEO is üzemelteti a cikkeket, az üzemeltetett oldalakat az AutoPSEO saját kulcsával pingeli, és az Öné nem kerül használatra.

Az Indexelés alatti IndexNow eszköz különálló, kézi beküldő; lásd: IndexNow.

Ütközések: a webhelye szövege az eredeti

A válasza version értéke (vagy az exportjában szereplő cikk version értéke) az, amit az AutoPSEO az oldala állapotának hisz. Minden article.updated ezt basedOn néven hordozza. Ha az oldal azóta megváltozott a webhelyén, például egy szerkesztő javítása után, válaszoljon 409 kóddal és { "error": "conflict" } tartalommal, és ne tároljon semmit. A kézbesítés újrapróbálkozás nélkül sikertelen lesz.

Mielőtt egy élő cikk sorban álló módosítását megírná, az AutoPSEO újra beolvassa a cikket a webhelyéről a site.export és a paths segítségével, ha a webhelye kezeli a site.export parancsot. Ha az Ön verziója közben továbblépett, az Ön szövege lesz a cikk következő változata (a író: import), és az ezt követő frissítés az Ön aktuális verzióját hordozza basedOn néven.

path.add és path.remove

Ez a két kézbesítés egy típusos tartalomtípus egy értékére vonatkozik, például egy cégre az /interviews/{company}/{role} útvonalban. article helyett egy path objektumot hordoznak:

{
  "id": "7c1e9d2a-3b4f-4e8a-9c0d-1e2f3a4b5c6d",
  "event": "path.add",
  "occurredAt": "2026-10-12T08:30:00.000Z",
  "site": { "propertyId": "prop_123", "domain": "example.com" },
  "path": {
    "path": "/interviews/jane-street",
    "type": { "key": "interviews", "name": "Interviews", "path": "/interviews" },
    "part": "company",
    "value": {
      "value": "jane-street",
      "name": "Jane Street",
      "aliases": [],
      "url": "https://<its own site>/",
      "sameAs": ["https://<its careers page>/"],
      "description": "<what it is, in a few words>",
      "facts": [
        { "text": "<one sentence, as the source states it>", "source": "https://<the page that says it>", "lastVerified": "2026-10-01", "tier": "official" }
      ]
    },
    "takes": { "role": ["software-engineer"] }
  }
}
MezőJelentése
pathAz érték saját címe a webhelyén
typeA tartalomtípus { key, name, path } alakban
partA cím azon része, amelyet az érték kitölt
value{ value, name }, path.add esetén emellett az AutoPSEO írója által összegyűjtött aliases, url, sameAs, description és facts. Minden tény tartalmaz text, source, lastVerified mezőt és official vagy reported értékű tier mezőt
takespath.add esetén: a többi rész értékei, amelyekkel együtt keresnek rá
redirectTopath.remove esetén: hová vezessenek innentől az érték címei, 301-gyel

Ha elfogadta a parancsot, válaszoljon 2xx-szel; path.add esetén megadhatja az url mezőt, ahol az érték most él, path.remove esetén pedig az urls mezőt azokkal a címekkel, amelyeket már nem szolgál ki, és amelyek az IndexNow-hoz kerülnek. Az elutasításhoz válaszoljon 4xx-szel és { "error": "<code>", "details": ["<why>"] } tartalommal. path.add esetén az invalid_value az indoklásával együtt visszaküldi az értéket az írónak (a harmadik elutasítás végleges), bármely más kód pedig véglegesen elutasítja. path.remove esetén a not_found késznek számít, bármely más kód, például a 409 in_use, mindent úgy hagy, ahogy volt. Egy várakozó path-parancs Megtörtént a webhelyen jelölése a webhelye igenlő válaszának számít.

Hívások: kérések, amelyeknek az AutoPSEO a válaszát olvassa

A hívásokat ugyanúgy írják alá, mint a kézbesítéseket. A hívás alapértelmezés szerint legfeljebb 60 másodpercet vár, az újraolvasásoknál és a path-ellenőrzéseknél 30 másodpercet, és legfeljebb 24 MB-os válaszokat olvas. Minden, a 2xx-től eltérő válasz sikertelenné teszi a hívást.

site.export

A kérés tartalmazza az export: { what, cursor, limit } mezőt, továbbá a témákhoz since (ISO-idő) vagy újraolvasáshoz paths mezőt. Válaszoljon { "items": [], "next": "<cursor>" } alakban; az AutoPSEO addig kér újra, a cursor értékét a next értékére állítva, amíg az üres vagy null nem lesz.

  • A what: "articles" teljes webhelybejáráskor fut, oldalanként 10 elemmel, ha az export mezőben bejelentette az articles értéket és adopt: true értéket is. A 400-as válasz azt jelenti: "nem támogatott". A paths: ["/answers/x"] és limit: 1 megadásával egyetlen cikket olvas újra; csak azt a cikket adja vissza.
  • A what: "topics" minden bejáráskor és a napi szinkronizáláskor fut, oldalanként 50 elemmel; a napi szinkronizálás since mezőt küld, az utolsó lekérés idejével.
  • A what: "profile" minden bejáráskor fut. Válaszoljon { "profile": { types, languages, rules, categories, format } } alakban, mindegyik elem opcionális: a types [{ key, name, path }] alakban, a rules pedig brandTerms, synonyms, noise, onTopic és offTopic mezőkkel.

Egy exportált cikkhez kell externalId, slug (bármely írásrendszer betűi és számjegyei, valamint kötőjelek, legfeljebb 200 karakter, a szegmenseket / fűzi össze), a slug-gal végződő path, és legalább title, h1 és egy szakasz a copy mezőben. Opcionális mezők: lang (alapértelmezés en), type (tartalomtípus-kulcs), url, keyword, category, datePublished, dateModified, version, translations, owner (az AutoPSEO cikkazonosítója, átvétel után) és maintenance: { kind: "refresh" or "optimize", reason }, amely sorba állítja az adott feladatot. Minden exportált cikkből kezelt cikk lesz, az Ön szövegével első változatként, és semmi sem megy vissza. Az ismételt exportálás biztonságos, és az AutoPSEO által levett cikk sosem tér vissza exporton keresztül.

A téma eleme { keyword, status?, volume?, source?, externalId?, type?, reason? }, ahol a status értéke queued, planned vagy rejected.

articles.adopted

Az importálás után az AutoPSEO arra kéri, hogy engedje kezelnie az új cikkeket: { "articles": [{ "externalId", "articleId", "slug", "path" }] }. Válaszoljon { "adopted": ["<externalId>"], "refused": [{ "externalId": "<id>", "reason": "<why>" }] } alakban. Az a cikk, amelyet nem erősít meg, ismét eltávolításra kerül az AutoPSEO-ból, kivéve ha az AutoPSEO már írt hozzá változatot.

site.handover

{ "handover": { "types": ["answers"], "writer": "autopseo" } }, akkor küldi, amikor valaki a tulajdon Webhelye oldalán a Az AutoPSEO írja őket vagy az Írás visszaadása a webhelynek lehetőséget választja. Válaszoljon { "ok": true, "writer": "autopseo" } alakban. Az AutoPSEO-nak történő átadás után a webhelye az általa jóváhagyott témákat átadja az AutoPSEO-nak ahelyett, hogy maga írná meg őket.

path.check

{ "paths": [{ "path": "/interviews/google/data-engineer" }, { "path": "/interviews/jane-street", "new": { "part": "company", "value": "jane-street", "name": "Jane Street" } }] }. Útvonalanként egy eredménnyel válaszoljon: { "results": [{ "path": "/interviews/google/data-engineer", "ok": true }, { "path": "/interviews/jane-street", "ok": false, "error": "not_allowed", "details": ["We only list companies with a careers page."] }] }. Az elutasítást az indoklásával együtt megőrzi, és nem kérdezi újra; a kihagyott útvonalat később ismét megkérdezi.

Egy minimális fogadó

Egy Cloudflare Worker, amely a Web Crypto API segítségével ellenőrzi az aláírást, kezeli a három cikkparancsot, a többit pedig unknown_event válasszal elutasítja. A cikkeket egy ARTICLES néven kötött KV-névtérben tárolja, az aláíró titkot pedig egy AUTOPSEO_SECRET nevű Worker-titokban.

const HANDLED = ["article.published", "article.updated", "article.unpublished"];
const MAX_SKEW_SECONDS = 300;
const SITE = "https://example.com";

const json = (data, status = 200) =>
  new Response(JSON.stringify(data), { status, headers: { "content-type": "application/json" } });

function hexToBytes(hex) {
  if (!/^[0-9a-f]{64}$/.test(hex)) return null;
  const out = new Uint8Array(32);
  for (let i = 0; i < 32; i++) out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
  return out;
}

async function verified(request, body, secret) {
  const timestamp = request.headers.get("X-AutoPSEO-Timestamp") || "";
  const signature = (request.headers.get("X-AutoPSEO-Signature") || "").replace(/^sha256=/, "");
  if (!/^\d+$/.test(timestamp)) return false;
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > MAX_SKEW_SECONDS) return false;
  const bytes = hexToBytes(signature);
  if (!bytes) return false;
  const enc = new TextEncoder();
  const key = await crypto.subtle.importKey("raw", enc.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["verify"]);
  // verify() compares in constant time.
  return crypto.subtle.verify("HMAC", key, bytes, enc.encode(`${timestamp}.${body}`));
}

export default {
  async fetch(request, env) {
    if (request.method !== "POST") return new Response("Method not allowed", { status: 405 });
    const body = await request.text();
    if (!(await verified(request, body, env.AUTOPSEO_SECRET))) return json({ error: "bad_signature" }, 401);
    let msg;
    try {
      msg = JSON.parse(body);
    } catch {
      return json({ error: "bad_json" }, 400);
    }

    if (msg.event === "ping") return json({ ok: true, autopseo: { version: 1, events: HANDLED } });

    if (msg.event === "test") {
      const command = msg.test && msg.test.event;
      // Check the sample as you would the real command, and store nothing.
      return HANDLED.includes(command)
        ? json({ test: command, ok: true })
        : json({ test: command, ok: false, error: "unknown_event" });
    }

    if (msg.event === "article.published" || msg.event === "article.updated") {
      const a = msg.article;
      const stored = JSON.parse((await env.ARTICLES.get(a.id)) || "null");
      if (a.basedOn && stored && stored.version && stored.version !== a.basedOn) {
        return json({ error: "conflict", details: ["The page changed on the site."] }, 409);
      }
      // Any change to the page, here or in your own editor, gets a new version.
      const version = crypto.randomUUID();
      await env.ARTICLES.put(a.id, JSON.stringify({ ...a, version }));
      return json({ url: SITE + a.path, version });
    }

    if (msg.event === "article.unpublished") {
      const a = msg.article;
      if (a.redirectTo) await env.ARTICLES.put(a.id, JSON.stringify({ path: a.path, redirectTo: a.redirectTo }));
      else await env.ARTICLES.delete(a.id);
      return json({ ok: true });
    }

    return json({ error: "unknown_event" }, 400);
  },
};

Node.js-en ugyanígy ellenőrizhet a createHmac és a timingSafeEqual segítségével, a keretrendszere által kapott nyers törzsön:

import { createHmac, timingSafeEqual } from "node:crypto";

export function verifyAutopseo(rawBody, headers, secret) {
  const timestamp = String(headers["x-autopseo-timestamp"] || "");
  const given = String(headers["x-autopseo-signature"] || "");
  if (!/^\d+$/.test(timestamp) || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
  const expected = "sha256=" + createHmac("sha256", secret).update(timestamp + ".").update(rawBody).digest("hex");
  return given.length === expected.length && timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}

Következő lépés: hogy mi jut el a webhookhoz, azt az írás és jóváhagyás és a karbantartás dönti el; a teljes folyamatot a tartalommotor áttekintése mutatja be.

Tedd autopilotára az SEO-tartalmaidat

Kösd össze a Search Console-t és a webhelyedet. Az AutoPSEO átvizsgálja, és azonnal megtervezi az első témákat. Nem kell bankkártya.