OROVA.VN — BIZ AI AGENT

/ Útmutató fejlesztőknek

Közzététel API-n keresztül bármely weboldalra.

Hogyan építsen saját végpontot, hogy az Orova WordPress nélküli webhelyre is közzétehesse a kész cikkeket.

Az Orova alapból WordPressre teszi közzé a kész cikkeket. Ha weboldala nem WordPress — egyedi CMS, headless rendszer, statikus oldal vagy saját backend —, akkor is hagyhatja, hogy az Orova automatikusan publikáljon, ha egy kis API-n keresztül fogadja a cikkeket. Ön megír egy HTTP-végpontot; az Orova minden kész cikknél meghívja. Ez az útmutató fejlesztőknek szól, és a kérés teljes szerződését leírja.

/ Áttekintés

Hogyan működik

Amikor az Orova befejez egy cikket egy kulcsszóra, egyetlen HTTP POST kérést küld a megadott végpont URL-re. A kérés törzse JSON, és a teljes cikket tartalmazza. A végpont létrehozza a bejegyzést az Ön oldalán, és visszaküldi a cikk végleges, nyilvános URL-jét. Az Orova ezt az URL-t menti közzétett linkként, ugyanúgy, mint egy WordPress-bejegyzésnél. Akkor használja, ha nem WordPress alapú webhelyen szeretne automatikus közzétételt, vagy ha teljes mértékben maga szeretné kezelni a bejegyzések tárolását.

/ Beállítás

Beállítás — hat lépés

  • 1

    Kapcsolja be az „Összekapcsolás API-n keresztül” lehetőséget a projektben. Nyissa meg a projektjét (Projektek → az Ön projektje → Kapcsolatok). A WordPress kártya mellett található az Összekapcsolás API-n keresztül kártya. Adja meg itt a végpontja URL-jét. A titkos kulcs mezője opcionális: ha üresen hagyja, az Orova generál egyet, vagy beillesztheti a webhelye által már használt kulcsot. Mentés után a kulcs a kártyán jelenik meg egy Másolás gombbal. Egy projekt csak egy helyre publikál — az API-s kapcsolat zárolja a WordPress gombot, és fordítva.

  • 2

    Építsen egy POST kérést fogadó végpontot. A saját webhelyén vagy szerverén hozzon létre egy útvonalat, amely JSON törzsű HTTP POST kéréseket fogad. Ezt az URL-t illeszti vissza a projekt Kapcsolatok képernyőjére. Az Orova minden elkészült cikknél egyszer hívja meg.

  • 3

    Ellenőrizze a Bearer tokent minden kérésnél. Az Orova minden kérése „Bearer <secret>” formájú Authorization fejlécet visz, pontosan a projektben látható titkos kulccsal. Vesse össze a tárolt példánnyal, és utasítson el minden nem egyező kérést — csak ez akadályozza meg, hogy bárki más publikáljon a webhelyére.

  • 4

    Hozza létre a cikket a payloadból. Olvassa be a JSON törzset, és hozzon létre egy bejegyzést a CMS-ében vagy adatbázisában: a cikkhez használja a title, slug és content_html mezőket, az excerptet metaleírásként, a featured_image_url-t borítóképként, a keyword / lang / published_at mezőket pedig metaadatként.

  • 5

    Adja vissza a cikk élő URL-jét. Válaszoljon HTTP 200-zal vagy 201-gyel és ezzel a JSON törzzsel: { "url": "https://yoursite.com/the-new-article" }. Az Orova ezt az URL-t tárolja a cikk közzétett linkjeként. Ha nem 2xx állapotkódot ad vissza, vagy hiányzik az url mező, az Orova sikertelennek tekinti a közzétételt.

  • 6

    Kezelje az Optimalizálás motor frissítési kéréseit. Ha a törzsben action = "update" szerepel, keresse meg a meglévő bejegyzést a target_url (vagy a slug) alapján, és helyben írja felül a title, content_html és excerpt mezőket — az URL maradjon változatlan. Válaszoljon 200-zal és egy ugyanarra a bejegyzésre mutató { "url": ... } értékkel. Ha a végpont ezt még nem kezeli, az Orova csak sikertelennek jelzi az optimalizálást; az új cikkek közzététele továbbra is működik.

/ Szerződés

Az Orova által küldött kérés

Minden elkészült cikk egy ilyen formájú kérésként érkezik:

POST <your endpoint URL>

Headers:
  Content-Type: application/json
  Authorization: Bearer <secret>     # the secret key shown in Project -> Connections
  User-Agent: Orova-SEO

Body (JSON):
  {
    "title": "...",                  # article headline
    "slug": "...",                   # URL-friendly identifier
    "content_html": "...",           # full article HTML
    "excerpt": "...",                # meta description
    "featured_image_url": "..." | null,
    "keyword": "...",                # target keyword
    "lang": "en",                    # ISO language code
    "published_at": "2026-05-17T09:00:00.482913",  # ISO 8601, UTC, no offset suffix
    "status": "draft"                # optional: "draft" keeps it unpublished
  }
  # Optional fields are left out of the body when empty — never sent as null.

/ Referencia

A payload mezői

Egy közzétételi (új cikk) kérés mezői. A törlési és frissítési kérések ugyanezt a végpontot használják, rövidebb törzzsel — lásd lent a saját fejezetüket.

MezőTípusLeírás
titlestringA cikk címe.
slugstringURL-friendly identifier suggested for the post.
content_htmlstringA cikk teljes törzse közzétételre kész HTML-ként.
excerptstringRövid összefoglaló, metaleírásnak szánva.
featured_image_urlstring | nullA borítókép URL-je, vagy null, ha nincs kép.
keywordstringA cél SEO-kulcsszó, amelyre a cikk készült.
langstringLanguage as an ISO code, e.g. "en" or "vi".
published_atstringAz időpont, amikor az Orova elküldte a cikket, ISO 8601 formátumban, UTC szerint, időzóna-utótag nélkül.
statusstring | undefinedOpcionális. A "draft" piszkozatként tartja a cikket; a "publish" vagy az érték hiánya azonnal közzéteszi.
actionstring | undefinedÚj cikkeknél nincs jelen. A "delete" egy bejegyzés eltávolítását kéri; az "update" (az Optimalizálás motor küldi) egy meglévő bejegyzés helyben történő felülírását kéri.
target_urlstringCsak action = "update" esetén: a felülírandó bejegyzés élő URL-je. Az URL maradjon változatlan.
idnumber | undefinedOnly sent when Orova knows your post id (from `list` or `get`): match on it before `target_url`.

Az opcionális mezők teljesen kimaradnak a törzsből, ha nincs mit küldeni — az Orova soha nem küld null értéket, ezért olvassa őket óvatosan. A status is opcionális: a "draft" piszkozatként hozza létre a cikket, a "publish" vagy a status hiánya pedig azonnal közzéteszi.

/ Szerződés

A visszaadandó válasz

Miután létrehozta a bejegyzést, válaszoljon HTTP 200 vagy 201 állapotkóddal és ezzel a JSON törzzsel:

HTTP 200 (or 201)
Content-Type: application/json

{
  "url": "https://yoursite.com/published-article"
}

Az Orova ezt az url-t tárolja a cikk közzétett linkjeként. Ha a végpont nem 2xx állapotkódot ad vissza, vagy a törzs nem url mezőt tartalmazó JSON objektum, az Orova sikertelennek tekinti a közzétételt, és ennek megfelelően jelöli a cikket, hogy újra próbálhassa. Válaszoljon 60 másodperc alatt — utána az Orova megszakítja a kérést (ez a közzétételre, a frissítésre és a törlésre egyaránt vonatkozik).

/ Példa

Kódpélda

Minimális fogadó végpont Node.js-ben, Expresszel. Ugyanezek a lépések — a token ellenőrzése, elágazás az action alapján (update / delete), a bejegyzés létrehozása vagy módosítása, az URL visszaadása — bármely nyelvben vagy keretrendszerben érvényesek.

// Node.js / Express — a minimal receiving endpoint
import express from "express";

const app = express();
app.use(express.json({ limit: "5mb" }));

// The secret Orova generated for this project.
const OROVA_SECRET = process.env.OROVA_SECRET;

app.post("/orova/publish", async (req, res) => {
  // 1. Verify the Bearer token.
  const auth = req.get("authorization") || "";
  if (auth !== "Bearer " + OROVA_SECRET) {
    return res.status(401).json({ error: "unauthorized" });
  }

  // 2. Required: list your articles (duplicate check, internal links). action = "list".
  if (req.body.action === "list") {
    const posts = await listPosts(req.body.limit || 500); // newest first, 500 max
    // each post: { id, title, slug, link, date, modified, status, author, excerpt? }
    return res.status(200).json({ ok: true, posts });
  }

  // 3. Required: read one article in full (used when optimizing it). action = "get".
  if (req.body.action === "get") {
    const post = await findPost(req.body.id, req.body.target_url, req.body.slug);
    if (!post) return res.status(404).json({ ok: false, err: "not_found" });
    return res.status(200).json({ ok: true, post });
  }

  // 4. Visual Editor: store an image, answer with its absolute URL.
  if (req.body.action === "upload_image") {
    const { filename, mime, data_base64 } = req.body;
    if (!String(mime || "").startsWith("image/")) {
      return res.status(422).json({ error: "image files only" });
    }
    const bytes = Buffer.from(data_base64, "base64");
    if (bytes.length > 15 * 1024 * 1024) {
      return res.status(413).json({ error: "image too large" });
    }
    return res.status(200).json({ ok: true, url: await saveImage(filename, bytes) });
  }

  // 5. Delete requests: body carries action = "delete".
  if (req.body.action === "delete") {
    const removed = await deletePostByUrl(req.body.url, req.body.slug);
    if (!removed) return res.status(404).json({ deleted: true }); // already gone
    return res.status(200).json({ deleted: true });
  }

  // 6. Update requests: action = "update". Optional fields may be absent.
  if (req.body.action === "update") {
    const updated = await updatePost(req.body.id, req.body.target_url, {
      title: req.body.title,
      html: req.body.content_html,
      metaDescription: req.body.excerpt,
      coverImage: req.body.featured_image_url,  // optional
      status: req.body.status,                  // optional: "publish" | "draft"
    });
    if (!updated) return res.status(404).json({ error: "post not found" });
    return res.status(200).json({ url: updated.url });
  }

  // 7. New article: read the payload Orova sent.
  const {
    title, slug, content_html, excerpt,
    featured_image_url, keyword, lang, published_at, status,
  } = req.body;

  // 8. Create the article in your own CMS or database.
  const post = await createPost({
    title,
    slug,
    html: content_html,
    metaDescription: excerpt,
    coverImage: featured_image_url,
    keyword,
    lang,
    publishedAt: published_at,
    draft: status === "draft",   // status is optional; absent means publish now
  });

  // 9. Return 200/201 with the live URL.
  return res.status(201).json({
    url: "https://yoursite.com/" + post.slug,
  });
});

app.listen(3000);

/ Szerződés — frissítés

Cikkek frissítése (Optimalizálás)

Az Orova Optimalizálás motorja átírja a már élő cikkeket — frissített tények, jobb címek, összevont tartalom —, majd helyben, az URL megtartásával felülírja a meglévő bejegyzést. A kérés ugyanarra a végpont URL-re megy, POST kérésként, ugyanazzal a Bearer tokennel:

POST <your endpoint URL>

Headers:
  Content-Type: application/json
  Authorization: Bearer <secret>
  User-Agent: Orova-SEO

Body (JSON):
  {
    "action": "update",          # always the literal string "update"
    "id": 123,                   # optional: post id, match on this first
    "target_url": "...",         # public URL of the post to overwrite (match next)
    "title": "...",              # new headline
    "slug": "...",               # slug fallback for matching, may be empty
    "content_html": "...",       # full new article body as HTML
    "excerpt": "...",            # new meta description
    "featured_image_url": "...", # optional: new cover image
    "status": "publish"          # optional: "publish" or "draft"
  }
  # Optional fields are left out of the body when empty — never sent as null.

Keresse meg a bejegyzést a target_url alapján (ha nincs, a slug alapján), cserélje le a címét, törzsét és metaleírását, az URL-t hagyja változatlanul, majd válaszoljon 200-zal és { "url": "<same post URL>" } értékkel. Bármely nem 2xx állapotkód vagy url nélküli törzs esetén az Orova sikertelennek jelöli az optimalizálást (soha nem hoz létre duplikált bejegyzést). Azok a végpontok, amelyek ezt még nem valósították meg, változatlanul publikálják az új cikkeket — a frissítést csak akkor kell megvalósítani, ha az Optimalizálás képernyőt használja.

Augusztus 29. óta a frissítési törzs tartalmazhat id mezőt is (először ez alapján keressen, csak utána a target_url alapján), featured_image_url mezőt új borítóképhez, valamint "publish" vagy "draft" értékű status mezőt. Mindhárom opcionális; ha üresek, kimaradnak a törzsből, soha nem küldjük őket null értékként.

/ Szerződés — Visual Editor

Cikkek olvasása (kötelező)

Az Orovának olvasnia kell a webhelyén már meglévő cikkeket — hogy elkerülje az ismétlődő témákat, belső linkeket szúrjon be és optimalizálja a régebbi bejegyzéseket. Adjon hozzá két további actiont ugyanazon a végpont URL-en, ugyanazzal a Bearer tokennel: a list a cikkeket adja vissza, a get egyet közülük teljes egészében.

POST <your endpoint URL>     # same endpoint, same Bearer secret

Body (JSON):
  {
    "action": "list",            # always the literal string "list"
    "limit": 500                 # newest article first, 500 maximum
  }

Response — HTTP 200:
  {
    "ok": true,
    "posts": [
      {
        "id": 123,               # your own post id, reused by "get" and "update"
        "title": "...",
        "slug": "...",
        "link": "https://yoursite.com/the-article",
        "date": "2026-08-29",    # published date, YYYY-MM-DD
        "modified": "2026-08-29",
        "status": "publish",     # "publish" or "draft"
        "author": "...",
        "excerpt": "..."         # optional: short summary, 300 characters max
      }
    ]
  }
  # Required: Orova reads this list to avoid duplicate topics,
  # add internal links and analyze the whole site.
POST <your endpoint URL>

Body (JSON):
  {
    "action": "get",             # always the literal string "get"
    "id": 123,                   # match on this first
    "target_url": "...",         # then the public URL
    "slug": "..."                # then the slug
  }

Response — HTTP 200:
  {
    "ok": true,
    "post": {
      "id": 123,
      "title": "...",
      "slug": "...",
      "link": "https://yoursite.com/the-article",
      "content_html": "...",     # full article body as HTML
      "excerpt": "...",
      "featured_image_url": "...",
      "status": "publish"        # "publish" or "draft"
    }
  }

No such post — HTTP 404:
  { "ok": false, "err": "not_found" }

A limit legfeljebb 500, és a legújabb cikk áll elöl. A get esetén az Orova egyszerre küldi az id, target_url és slug értéket — azzal keressen, amelyiket felismeri, ebben a sorrendben. Ha nincs találat, válaszoljon 404-gyel és { "ok": false, "err": "not_found" } értékkel. A list válaszában az excerpt opcionális (legfeljebb 300 karakter). Kötelező: az Orova a list hívással tudja meg, mely cikkek léteznek már (az ismétlődés elkerülésére, belső linkekhez és a teljes webhely elemzéséhez), a get hívással pedig beolvassa a cikket optimalizáláskor. Ha webhelye nem válaszol erre a két actionre, az új cikkek nem kapnak belső linkeket, a régebbi cikkek pedig nem optimalizálhatók.

/ Szerződés — Visual Editor

Képfeltöltés (Visual Editor)

Amikor képet húz a Visual Editorba, az Orova ugyanarra a végpont URL-re küldi base64-ként a JSON törzsben — multipart nélkül, nincs második védendő URL.

POST <your endpoint URL>

Body (JSON):
  {
    "action": "upload_image",    # always the literal string "upload_image"
    "filename": "cover.png",     # original file name, extension included
    "mime": "image/png",         # image/* only
    "data_base64": "iVBORw0KGgo..."   # file bytes, base64, 15 MB maximum
  }

Response — HTTP 200 (or 201):
  {
    "ok": true,
    "url": "https://yoursite.com/uploads/cover.png"   # absolute URL
  }

Csak image/* típust fogadjon el, és utasítson el mindent, ami 15 MB fölött van. Tárolja a fájlt, majd válaszoljon a kép abszolút URL-jével: a relatív útvonal tönkreteszi a cikket, amint máshol jelenik meg. Erre az actionre csak a Visual Editorhoz van szükség.

/ Szerződés — törlés

Cikkek törlése

Amikor egy felhasználó eltávolít egy közzétett cikket az Orovában (az Írás vagy a Jelentések képernyőn), az Orova a webhelyét is megkéri a törlésére. A kérés ugyanarra a végpont URL-re megy, POST kérésként, ugyanazzal a Bearer tokennel — csak a törzs más:

POST <your endpoint URL>

Headers:
  Content-Type: application/json
  Authorization: Bearer <secret>
  User-Agent: Orova-SEO

Body (JSON):
  {
    "action": "delete",          # always the literal string "delete"
    "url": "...",                # public URL of the article to remove (match on this first)
    "slug": "...",               # slug fallback, may be empty
    "keyword": "..."             # the article's target keyword, for your logs
  }

Keresse meg a bejegyzést az url alapján (ha nincs, a slug alapján), törölje vagy vonja vissza a közzétételét, majd válaszoljon 200-zal és { "deleted": true } értékkel — egy üres 204 is megfelel. Ha a bejegyzés már nem létezik, válaszoljon 404-gyel, és az Orova már töröltnek tekinti. A { "deleted": false } válasz azt jelzi az Orovának, hogy a bejegyzést nem távolította el. A szokásos közzétételi kérések soha nem tartalmaznak action mezőt, így a meglévő végpontok változatlanul működnek — a törlés megvalósítása opcionális, de ajánlott.

/ Biztonság

Biztonsági tudnivalók

  • Mindig ellenőrizze a Bearer tokent. A végpontja nyilvános URL — bárki meghívhatja. Az Authorization fejléc az egyetlen bizonyíték arra, hogy a kérés valóban az Orovától jön, ezért utasítson el minden kérést, amelynek tokenje nem egyezik pontosan a tárolt titkos kulccsal.
  • A végpontot HTTPS-en szolgálja ki. A titkos kulcs fejlécben utazik. A HTTPS megakadályozza, hogy útközben elolvassák.
  • Ne tartsa a titkos kulcsot a kódban. Tárolja környezeti változóban vagy titokkezelőben, soha ne írja be fixen egy commitolt fájlba. Ha valaha kiszivárog, generáljon újat a Projekt → Kapcsolatok menüben.
  • A content_html tartalom, nem megbízható markup. Ugyanolyan körültekintően tárolja és jelenítse meg, mint bármely más cikktörzset a CMS-ében.

/ Összegzés

Ennyi a teljes szerződés

Ha a végpont élő és be van jegyezve a projektben, az Orova automatikusan publikál a webhelyére — pontosan úgy, mint a WordPress-felhasználóknál. Minden elkészült cikk a szerverére érkezik, bejegyzés lesz belőle, a nyilvános URL-je pedig visszakerül a Jelentésekbe és az Elemzésbe, így követheti a teljesítményét.

← Vissza az útmutatótárba

/ Segítség kell?

Elakadt a végpont bekötésével? Nyissa meg a Támogatás részt a munkaterületén, vagy küldjön nekünk üzenetet.