Універсальний вебхук для автопублікації SEO-блогу
Webhook пов’язує чотири дії Blogent з наявною CMS. Поверніть повний результат дії з endpoint після завершення операції CMS.
Blogent читає наявний архів статей, створює заплановані матеріали та оновлює опубліковані статті через один захищений JSON endpoint.
Дії та сталі ідентифікатори
- Shopify, HubSpot, Webflow і Framer використовують підключений нативний адаптер. WordPress, OpenCart, Strapi та Lovable — встановлений конектор Blogent; v0 і Replit адаптують його до наявного застосунку. Wix, Make, n8n та власні endpoint реалізують синхронний контракт; Zapier, Albato й ApiX-Drive — callback завершення.
inventory: передайтеcursor: nullіlimit; відповідь —{articles: [snapshot], next_cursor: string|null}. Продовжуйте з отриманим курсором до null.read: передайтеtargetта/абоcontent_id; відповідь —{article_snapshot: snapshot}. Явний нативнийtargetє визначальним; логічнийcontent_idBlogent може відрізнятися від ID у CMS.- Snapshot містить
identity, title, alias, date, article, target, revision, urlsі необов’язкові дані зображення/автора.articleмістить повний текст та SEO-поля кожної мови. Невідома первинна дата може бути null, недоступні URL — порожньою мапою. create: передайте статтю, унікальнийoperation_id, логічнийcontent_id, порожній target та null expected_revision. Після повної публікації поверніть{posted:true,target,revision,urls}.update: передайте наявні target ID та актуальнуexpected_revision. Збережіть ID, URL/alias, первинну дату, автора й ресурси. Перевірте ревізію атомарно перед записом.
{
"inventory_request": {"contract_version":"2.0","action":"inventory","cursor":null,"limit":10},
"inventory_response": {"articles":[],"next_cursor":null},
"read_request": {"contract_version":"2.0","action":"read","content_id":"logical-content-id","target":{"en":"native-42"}},
"read_response": {"article_snapshot":{"identity":"native-42","title":"Article","alias":"article","date":null,"article":{"en":{"title":"Article","alias":"article","text":"<p>Body</p>","preview":"Summary","meta_title":"Article","meta_description":"Description"}},"target":{"en":"native-42"},"revision":"storage-revision","urls":{}}},
"update_identity_fields": {"contract_version":"2.0","action":"update","operation_id":"new-operation-uuid","content_id":"logical-content-id","target":{"en":"native-42"},"expected_revision":"storage-revision"},
"write_response": {"posted":true,"target":{"en":"native-42"},"revision":"new-storage-revision","urls":{}},
"callback_body": {"contract_version":"2.0","request_id":"received-request-uuid","action":"inventory","result":{"articles":[],"next_cursor":null}}
}
Callback завершення для асинхронних сценаріїв
- Оберіть Zapier, Albato або ApiX-Drive у Blogent. Кожна дія містить
request_id, точнийcallback_urlі окремийcallback_token. Передавайте ці значення через усі кроки сценарію. - Розгалужуйте сценарій за
action. Inventory/read читають CMS; create/update використовують постійний журнал операцій, транзакції та перевірку ревізії. - Після завершення надішліть POST JSON на отриманий callback URL із заголовком
Authorization: Bearer <callback_token>. Тіло:{contract_version:"2.0",request_id,action,result}. Result має формат синхронної відповіді відповідної дії. - У разі помилки передайте
result:{posted:false,message:"причина",status:409}із відповідним кодом 4xx/5xx. Часткова публікація не може повертати posted:true. - Callback прив’язаний до запиту, дії та конфігурації. Ідентичний повтор приймається; змінений результат повертає 409, хибний токен — 401, прострочений запит — 410. Запит діє годину; Blogent може повторити його до п’яти разів із проміжком щонайменше дві хвилини. Дедуплікуйте request_id та operation_id.
- Тест відновлюється після callback: inventory → create → read → update тієї самої реальної статті. Приймання в чергу залишає стан очікування. Перевірка відбувається через захищену інтеграцію без обходу публічних сторінок.
HTML-теги, для яких потрібні стилі
h1, h2, h3, h4
p, ul, ol, li, a, strong, img
table, thead, tbody, tr, th, td
details, summary
Для <a> переконайтеся, що підтримуються атрибути rel і target.
.tldr - для першого p (можна виділяти більшим шрифтом)
.faq-section - обгортка для <details> для FAQ
Що потрібно
- HTTPS endpoint для POST JSON із
contract_version: "2.0"та заголовком авторизації. - Реалізуйте чотири дії:
inventory,read,createіupdate. Додайте наявні статті за явними ID і зв’язками мов. - Потрібні постійне сховище, журнал операцій і транзакційне блокування або compare-and-swap. Блокування лише в пам’яті процесу недостатньо.
- Перед підтвердженням створення збережіть тимчасові зображення у постійному сховищі; під час оновлення залишайте наявні ресурси.
- Поверніть кінцевий результат синхронно або налаштуйте захищений callback для Zapier, Albato й ApiX-Drive. Приймання в чергу не означає публікацію.
JSON‑навантаження
{
"contract_version": "2.0",
"action": "create",
"operation_id": "8f8c0380-17c8-4e9f-9bc0-fdb5bef60d30",
"content_id": "8f8c0380-17c8-4e9f-9bc0-fdb5bef60d30",
"target": {},
"expected_revision": null,
"image": null,
"image_category": "desert-tours",
"alias": "string-for-url",
"date": "2026-09-13 12:00:00",
"rubric": "category-slug",
"params": "key:value|value;key2:value;",
"author": {
"id": 7,
"identifiers": {"lovable": "cms-author-42"},
"name": "Olena Kovalenko",
"gender": "female",
"age": 37,
"position": "Head of Customer Success",
"description": "Works with customer onboarding and retention strategy."
},
"article": {
"en": {
"title": "text",
"alias": "string-for-url-en",
"preview": "html",
"meta_title": "text",
"meta_description": "text",
"reading_time_minutes": 7,
"toc": [
{
"title": "Main section",
"id": "main-section",
"children": [
{
"title": "Nested point",
"id": "nested-point",
"children": []
}
]
}
],
"text": "html"
}
}
}
Поля
contract_version—2.0;actionзадає inventory, read, create або update.operation_idвизначає одну зміну. Збережіть хеш усього запиту та кінцеву відповідь; ідентичний повтор повертає цю відповідь.content_id— логічний ID Blogent;targetпов’язує кожну мову з визначальним ID у CMS.expected_revision— null для створення та актуальна ревізія snapshot для оновлення.alias, мовні alias таdateзадаються при створенні; оновлення зберігає початкові значення CMS.articleмістить title, alias, preview HTML, text HTML, meta_title, meta_description, reading_time_minutes і toc для кожної мови.- Необов’язкові
image,image_category,rubric,paramsтаauthorвикористовують явні мапінги CMS. Визначальним є лише ID автора поточної платформи.
Якщо потрібно підбирати товари, передайте атрибути в полі params (формат key=value1|value2;). Збережіть значення у CMS, щоб фільтрувати каталог або відображати рекомендації.
У налаштуваннях webhook додайте власну пару заголовок/значення та перевіряйте її до парсингу body. Рекомендовано: X-Blogent-Token і випадковий секрет щонайменше з 32 символів, що зберігається лише в серверних secrets. Blogent додає точну налаштовану пару до кожного запиту.
Ідемпотентність і правила доставки
- Перевірте всі мови перед записом. Зміни та журнал операцій мають фіксуватися атомарно; завантаження ресурсів саме по собі не є публікацією.
- Спершу перевіряйте збережену відповідь операції. Ідентичний повтор повертає її; змінене використання operation_id повертає 409.
- Перевіряйте expected_revision під транзакційним блокуванням або compare-and-swap. Ручні зміни в CMS також мають змінювати ревізію.
- При оновленні зберігайте ID, URL, alias, первинну дату, автора та ресурси. Не створюйте іншу статтю замість оновлення.
- Очищуйте HTML, зберігайте підтримувані атрибути посилань та копіюйте потрібні зображення створення в постійне сховище через обмежені HTTPS-запити.
- Синхронний endpoint має завершити дію в межах 60 секунд очікування. Надсилання в асинхронну платформу очікує до 25 секунд, після чого потрібен захищений callback.
HTTP-відповіді та повторні спроби
200 {posted:true,target,revision,urls}підтверджує повну публікацію create/update з ID усіх мов і новою ревізією.- Inventory/read повертають визначені об’єкти результатів. Загальні success:true, порожня відповідь або 202 не є кінцевим результатом.
- 400/422 — некоректні дані; 401/403 — авторизація; 409 — змінений повтор операції або застаріла ревізія. Повертайте стислу причину без секретів.
- 429/5xx — тимчасова помилка. Повторюйте ту саму операцію й тіло; не створюйте новий ID статті після неоднозначної відповіді.
- Для Zapier, Albato й ApiX-Drive кінцевий результат надходить у callback. Історія сценарію та ручна візуальна перевірка не замінюють callback.
Checklist приймання endpoint
- Відхиляйте неправильну авторизацію та некоректні дії до запису.
- Отримуйте наявні статті, повні snapshot і всі сторінки inventory без вигаданих ID чи дат.
- Створіть і оновіть одну реальну тестову статтю зі збереженням ID, alias, дати, автора та ресурсів.
- Перевірте повтор після перезапуску, відхилення зміненої операції та застарілої ревізії після ручної зміни.
- Конкурентні записи та помилка будь-якої мови/зображення не повинні давати успішну відповідь.
- Перевірте callback усіх дій: неправильні токени, змінені повтори та завершення строку дії. Обхід публічних сторінок не потрібний.
Шорткоди
Blogent може автоматично вставляти шорткод у тіло статті, щоб показувати маркетингові або інтерактивні блоки прямо всередині контенту.
- У дашборді SEO Blog ви вказуєте один шорткод для блогу, наприклад
[contact-form]або[products_slider category="chairs"]. - Під час генерації статті Blogent вставляє цей шорткод у середині матеріалу в природному місці, не ламаючи структуру тексту.
- Ваш сайт або CMS мають вміти обробити цей шорткод і замінити його на готовий блок: форму, CTA, промокод, слайдер товарів, банер тощо.
- Якщо шорткод потребує параметрів, передавайте їх у тому форматі, який очікує ваш сайт або плагін.
- Маркетинговий призив до дії:
[cta] - Промокод зі знижкою:
[promo_code] - Форма зворотного звʼязку:
[contact-form] - Слайдер товарів:
[products_slider] - Добірка рекомендованих товарів:
[featured_products] - Банер або інформаційний віджет:
[info_banner]
Назви та параметри шорткодів залежать від вашого сайту. Якщо на сайті немає підтримки шорткодів, розробнику потрібно додати відповідну обробку або плагін.
Безпечний каркас PHP receiver
Каркас навмисно повертає помилку до підключення нативного адаптера CMS. Реалізуйте чотири дії, постійний журнал операцій та атомарні перевірки ревізії в handleBlogentV2(). Для асинхронного сценарію передайте той самий результат через захищений callback.
declare(strict_types=1);
function respond(int $status, array $body): never
{
http_response_code($status);
header('Content-Type: application/json; charset=utf-8');
echo json_encode($body, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES);
exit;
}
/** Implement against the existing CMS, with authenticated inventory/read and
* transactional create/update. Persist operation_id + canonical request hash +
* complete result in the same commit as all locales. Replay before checking the
* revision; compare expected_revision under a row lock/CAS. Preserve native IDs,
* URLs, aliases, original dates, authors and assets on update. Throw on partial
* failure. Return each action's final result, never a queue acknowledgment.
*/
function handleBlogentV2(array $command): array
{
throw new LogicException('Connect the native CMS adapter before deployment.');
}
if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') respond(405, ['posted' => false, 'message' => 'POST required']);
$secret = getenv('BLOGENT_WEBHOOK_TOKEN');
$token = $_SERVER['HTTP_X_BLOGENT_TOKEN'] ?? '';
if (!is_string($secret) || strlen($secret) < 32 || !is_string($token) || !hash_equals($secret, $token)) {
respond(401, ['posted' => false, 'message' => 'Unauthorized']);
}
if (!str_starts_with(strtolower($_SERVER['CONTENT_TYPE'] ?? ''), 'application/json')) {
respond(415, ['posted' => false, 'message' => 'JSON required']);
}
$raw = file_get_contents('php://input');
if (!is_string($raw) || strlen($raw) > 4 * 1024 * 1024) respond(413, ['posted' => false, 'message' => 'Payload too large']);
try {
$command = json_decode($raw, true, flags: JSON_THROW_ON_ERROR);
if (!is_array($command) || ($command['contract_version'] ?? null) !== '2.0'
|| !in_array($command['action'] ?? null, ['inventory', 'read', 'create', 'update'], true)) {
throw new InvalidArgumentException('Unsupported Blogent action');
}
// The adapter must validate action-specific fields and result completeness.
$result = handleBlogentV2($command);
respond(200, $result);
} catch (InvalidArgumentException | JsonException $error) {
respond(422, ['posted' => false, 'message' => $error->getMessage()]);
} catch (Throwable $error) {
respond(500, ['posted' => false, 'message' => 'Integration action failed']);
}
Webhook tester
Перевірте inventory, create, read та update однієї реальної тестової статті. Асинхронні інтеграції очікують callback завершення.
Що ви отримуєте після підключення Webhook
- Читайте наявний архів і повні snapshot перед плануванням нових статей.
- Оновлюйте статті зі збереженням ID, URL, первинних дат, авторів і ресурсів.
- Безпечно повторюйте ідентичні операції та відхиляйте застарілі ревізії чи змінені повтори.
Вимоги та сумісність
- Дії
- Реалізуйте inventory, read, create та update для наявної CMS із явними мовними мапінгами.
- Конкурентність
- Транзакційний адаптер із постійним журналом operation_id та атомарною перевіркою expected_revision. Окремих no-code upsert недостатньо.
- Завершення
- Синхронно поверніть кінцевий JSON. Для запису потрібні posted:true, усі target ID та ревізія.
Часті запитання про інтеграцію з Webhook
Чи підтверджує приймання webhook публікацію?
Ні. Blogent очікує кінцевий результат дії. Загальне підтвердження, запис в історії або частковий мовний результат не завершують операцію.
Що робить тест з’єднання?
Inventory, create, захищене read та update тієї самої реальної статті. Він очікує callback без обходу публічної сторінки.
Як захищені повтори та редагування?
CMS постійно зберігає ID операції, хеш запиту й відповідь. Ідентичний повтор повертає її; змінений повтор або застаріла ревізія дає 409. Ручні зміни також мають змінювати ревізію.
Переведіть SEO-блог на автопілот
Створіть блог, підключіть Webhook — і Blogent плануватиме, писатиме, перелінковуватиме та публікуватиме статті автоматично.