OROVA.VN — BIZ AI AGENT

/ Әзірлеушілерге арналған нұсқаулық

API арқылы жариялау кез келген сайтта.

Orova WordPress-те жұмыс істемейтін сайтқа дайын мақалаларды жариялай алуы үшін өз endpoint-іңізді қалай жасауға болады.

Orova дайын мақалаларды WordPress-ке бірден жариялайды. Егер сайтыңыз WordPress емес болса — жеке CMS, headless жүйе, статикалық сайт немесе өз backend-іңіз — шағын API арқылы мақалаларды қабылдап, Orova-ға автоматты жариялауға рұқсат бере аласыз. Сіз бір HTTP endpoint жазасыз; Orova әр мақаланы аяқтаған сайын оны шақырады. Бұл нұсқаулық әзірлеушіге арналған және сұраудың толық келісімін сипаттайды.

/ Шолу

Қалай жұмыс істейді

Orova кілт сөз бойынша мақаланы жазып болғанда, Сіз тіркеген endpoint URL-ге бір HTTP POST сұрауын жібереді. Сұрау денесі JSON пішімінде және бүкіл мақаланы қамтиды. Endpoint-іңіз өз жағыңызда жазбаны жасап, мақаланың соңғы ашық URL-ін қайтарады. Orova бұл URL-ді WordPress жазбасындағыдай жарияланған сілтеме ретінде сақтайды. Мұны WordPress емес сайтта автоматты жариялау қажет болғанда немесе жазбалардың қалай сақталатынын толық бақылағыңыз келгенде қолданыңыз.

/ Баптау

Баптау — алты қадам

  • 1

    Жобаңызда «API арқылы қосу» опциясын қосыңыз. Жобаңызды ашыңыз (Жобалар → жобаңыз → Қосылымдар). WordPress карточкасының жанында API арқылы қосу карточкасы бар. Сол жерге endpoint URL-ін енгізіңіз. Құпия кілт өрісі міндетті емес: бос қалдырсаңыз, Orova кілтті өзі жасайды, немесе сайтыңыз қолданып жүрген кілтті қойыңыз. Сақталғаннан кейін кілт карточкада Көшіру батырмасымен көрсетіледі. Бір жоба тек бір бағытқа жариялайды — API арқылы қоссаңыз, WordPress батырмасы құлыпталады, және керісінше.

  • 2

    POST қабылдайтын endpoint жасаңыз. Өз сайтыңызда немесе серверіңізде JSON денесі бар HTTP POST сұрауын тыңдайтын route жасаңыз. Бұл — жобаның Қосылымдар экранына қайта қоятын URL. Orova әр аяқталған мақала үшін оны бір рет шақырады.

  • 3

    Әр сұрауда Bearer token-ды тексеріңіз. Orova-дан келетін әр сұрауда жобаңызда көрсетілген құпия кілтпен дәл сәйкес «Bearer <secret>» түріндегі Authorization тақырыптамасы бар. Оны сақталған көшірмеңізбен салыстырып, сәйкес келмейтінін қабылдамаңыз — басқалардың сайтыңызға жариялауына дәл осы кедергі болады.

  • 4

    Payload-тан мақала жасаңыз. JSON денесін оқып, CMS-те немесе дерекқорда жазба жасаңыз: мақаланың өзі үшін title, slug және content_html, meta description ретінде excerpt, мұқаба суреті ретінде featured_image_url, ал метадерек ретінде keyword / lang / published_at қолданыңыз.

  • 5

    Мақаланың нақты URL-ін қайтарыңыз. HTTP 200 немесе 201 және { "url": "https://yoursite.com/the-new-article" } JSON денесімен жауап беріңіз. Orova бұл URL-ді мақаланың жарияланған сілтемесі ретінде сақтайды. 2xx емес статус қайтарсаңыз немесе url өрісін қалдырып кетсеңіз, Orova жариялауды сәтсіз деп есептейді.

  • 6

    Оңтайландыру қозғалтқышының жаңарту сұрауларын өңдеңіз. Денеде action = "update" болса, бар жазбаны target_url (немесе slug) бойынша тауып, оның title, content_html және excerpt мәндерін орнында қайта жазыңыз — URL өзгермейді. Сол жазбаға нұсқайтын { "url": ... } мәнімен 200 қайтарыңыз. Мұны әлі өңдемейтін endpoint-тер тек Orova-ның оңтайландыруды сәтсіз деп көрсетуіне әкеледі; жаңа мақалаларды жариялау бұрынғыдай жұмыс істейді.

/ Келісім

Orova жіберетін сұрау

Әр аяқталған мақала осындай бір сұрау түрінде келеді:

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.

/ Анықтамалық

Payload өрістері

Жариялау (жаңа мақала) сұрауының өрістері. Жою және жаңарту сұраулары сол endpoint-ті қолданады, олардың қысқа денелері төмендегі өз бөлімдерінде көрсетілген.

ӨрісТүріСипаттама
titlestringМақала тақырыбы.
slugstringURL-friendly identifier suggested for the post.
content_htmlstringЖариялауға дайын HTML түріндегі мақаланың толық мәтіні.
excerptstringMeta description үшін арналған қысқа түйін.
featured_image_urlstring | nullМұқаба суретінің URL-і, немесе сурет жоқ болса null.
keywordstringМақала жазылған мақсатты SEO кілт сөзі.
langstringLanguage as an ISO code, e.g. "en" or "vi".
published_atstringOrova мақаланы жіберген сәт, UTC бойынша ISO 8601, уақыт белдеуі жұрнағынсыз.
statusstring | undefinedМіндетті емес. "draft" мақаланы жарияламай сақтайды; "publish" немесе мән жоқ болса, жариялайды.
actionstring | undefinedЖаңа мақалаларда болмайды. "delete" жазбаны жоюды сұрайды; "update" (Оңтайландыру қозғалтқышы жібереді) бар жазбаны орнында қайта жазуды сұрайды.
target_urlstringТек action = "update" кезінде: қайта жазылатын жазбаның нақты URL-і. URL өзгермеуі керек.
idnumber | undefinedOnly sent when Orova knows your post id (from `list` or `get`): match on it before `target_url`.

Жіберетін ештеңе болмаса, міндетті емес өрістер денеден мүлдем алынып тасталады — Orova ешқашан null жібермейді, сондықтан оларды сақтықпен оқыңыз. status та міндетті емес: "draft" мақаланы жобалық нұсқа ретінде жасайды, ал "publish" немесе status мүлдем болмаса, бірден жариялайды.

/ Келісім

Сіз қайтаруға тиіс жауап

Жазбаны жасағаннан кейін HTTP 200 немесе 201 статусымен және мына JSON денесімен жауап беріңіз:

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

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

Orova бұл url мәнін мақаланың жарияланған сілтемесі ретінде сақтайды. Endpoint-іңіз 2xx емес статус немесе url өрісі бар JSON нысаны емес дене қайтарса, Orova жариялауды сәтсіз деп есептеп, қайталай алуыңыз үшін мақаланы соған сәйкес белгілейді. 60 секунд ішінде жауап беріңіз — одан кейін Orova сұрауды тоқтатады (бұл жариялауға, жаңартуға және жоюға бірдей қатысты).

/ Мысал

Код мысалы

Node.js пен Express-тегі ең қарапайым қабылдаушы endpoint. Дәл осы қадамдар — token-ды тексеру, action бойынша тармақтау (update / delete), жазбаны жасау немесе өзгерту, URL қайтару — кез келген тілде немесе фреймворкта қолданылады.

// 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);

/ Келісім — жаңарту

Мақалаларды жаңарту (Оңтайландыру)

Orova-ның Оңтайландыру қозғалтқышы жарияланып қойған мақалаларды қайта жазады — деректерді жаңартады, тақырыптарды жақсартады, мазмұнды біріктіреді — содан кейін бар жазбаны орнында, URL-ді өзгертпей қайта жазады. Сұрау сол endpoint URL-ге сол Bearer token-мен POST ретінде барады:

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.

Жазбаны target_url бойынша табыңыз (болмаса slug бойынша), оның тақырыбын, мәтінін және meta description-ын ауыстырып, URL-ді сол күйінде қалдырыңыз, содан кейін { "url": "<same post URL>" } мәнімен 200 қайтарыңыз. 2xx емес кез келген статус немесе url жоқ дене Orova-ның сол оңтайландыруды сәтсіз деп белгілеуіне әкеледі (ол ешқашан қайталама жазба жасамайды). Мұны әлі іске асырмаған endpoint-тер жаңа мақалаларды бұрынғыдай жариялай береді — жаңартуды тек Оңтайландыру экранын қолданған кезде іске асыру керек.

29 тамыздан бастап жаңарту денесінде id (target_url-ден бұрын соны тексеріңіз), жаңа мұқаба суреті үшін featured_image_url және "publish" немесе "draft" мәні бар status болуы мүмкін. Үшеуі де міндетті емес; бос болса, денеден алынып тасталады, ешқашан null ретінде жіберілмейді.

/ Келісім — Визуалды редактор

Мақалаларды оқу (міндетті)

Orova сайтыңыздағы бар мақалаларды оқуы керек — тақырыптардың қайталануын болдырмау, ішкі сілтемелер қосу және ескі жазбаларды оңтайландыру үшін. Сол endpoint URL-ге сол Bearer token-мен тағы екі action қосыңыз: list мақалаларыңызды қайтарады, get біреуін толық қайтарады.

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" }

limit ең көбі 500, ең жаңа мақала бірінші тұрады. get үшін Orova id, target_url және slug мәндерін бірге жібереді — танитыныңыз бойынша, осы ретпен сәйкестендіріңіз. Ештеңе табылмаса, { "ok": false, "err": "not_found" } мәнімен 404 қайтарыңыз. list ішіндегі excerpt міндетті емес (ең көбі 300 таңба). Міндетті: Orova қандай мақалалар бар екенін білу үшін list шақырады (қайталауды болдырмау, ішкі сілтемелер қосу және бүкіл сайтты талдау үшін) және мақаланы оңтайландырғанда оны оқу үшін get шақырады. Сайтыңыз осы екі action-ға жауап бермесе, жаңа мақалаларда ішкі сілтемелер болмайды және ескі мақалаларды оңтайландыру мүмкін болмайды.

/ Келісім — Визуалды редактор

Суреттерді жүктеу (Визуалды редактор)

Визуалды редакторға сурет тастағанда, Orova оны JSON денесінің ішінде base64 түрінде сол endpoint URL-ге жібереді — multipart жоқ, қорғалатын екінші 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
  }

Тек image/* қабылдап, 15 MB-тан асатынын қабылдамаңыз. Файлды сақтап, суреттің абсолютті URL-імен жауап беріңіз: салыстырмалы жол мақала басқа жерде көрсетілгенде бұзылады. Бұл action тек Визуалды редактор үшін қажет.

/ Келісім — жою

Мақалаларды жою

Пайдаланушы Orova ішінде жарияланған мақаланы жойғанда (Мақала жазу немесе Есептер экранынан), Orova сайтыңыздан да оны жоюды сұрайды. Сұрау сол endpoint URL-ге сол Bearer token-мен POST ретінде барады — айырмашылығы тек денеде:

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
  }

Жазбаны url бойынша табыңыз (болмаса slug бойынша), жойыңыз немесе жариялаудан алыңыз, содан кейін 200 және { "deleted": true } мәнімен жауап беріңіз — жай 204 те жарайды. Жазба енді жоқ болса, 404 қайтарыңыз, Orova оны жойылған деп есептейді. { "deleted": false } қайтару Orova-ға жазбаның жойылмағанын білдіреді. Кәдімгі жариялау сұрауларында ешқашан action өрісі болмайды, сондықтан бар endpoint-тер өзгеріссіз жұмыс істей береді — жоюды іске асыру міндетті емес, бірақ ұсынылады.

/ Қауіпсіздік

Қауіпсіздік ескертпелері

  • Bearer token-ды әрқашан тексеріңіз. Endpoint-іңіз — ашық URL, оны кез келген адам шақыра алады. Сұраудың шынымен Orova-дан келгенін дәлелдейтін жалғыз нәрсе — Authorization тақырыптамасы, сондықтан token-ы сақталған құпия кілтпен дәл сәйкес келмейтін әр сұрауды қабылдамаңыз.
  • Endpoint-ті HTTPS арқылы іске қосыңыз. Құпия кілт тақырыптамада жіберіледі. HTTPS оны жолда оқудан сақтайды.
  • Құпия кілтті кодта сақтамаңыз. Оны орта айнымалысында немесе құпиялар менеджерінде сақтаңыз, commit жасайтын файлға ешқашан қатаң жазбаңыз. Кілт жария болып қалса, Жоба → Қосылымдар бөлімінен жаңасын жасаңыз.
  • content_html-ді сенімді белгілеу емес, мазмұн ретінде қарастырыңыз. Оны CMS-тегі кез келген мақала мәтіні сияқты мұқият сақтап, көрсетіңіз.

/ Қорытынды

Келісім осымен бітті

Endpoint жұмыс істеп, жобаңызда тіркелген соң, Orova сайтыңызға автоматты жариялайды — WordPress пайдаланушыларындағыдай. Аяқталған әр мақала серверіңізге түсіп, жазбаға айналады, ал оның ашық URL-і нәтижесін бақылауыңыз үшін Есептер мен Талдауға қайта келеді.

← Нұсқаулықтар кітапханасына оралу

/ Көмек керек пе?

Endpoint-ті қосу қиын болып тұр ма? Жұмыс кеңістігіңіздегі Қолдау бөлімін ашыңыз немесе бізге хабарлама жіберіңіз.