هل الواجهة البرمجية مناسبة لموقعك؟
تربط واجهة النشر البرمجية مساحة عمل Beulog بموقعك أو نظام إدارة المحتوى لديك. يجلب خادم موقعك المقالات المعتمدة، ثم يمنح موقعك كل مقال عنوانًا مستقلًا وتصميمًا وبيانات للبحث. اطلب من مطوّرك أو مزوّد موقعك إعداد الاتصال على الخادم، ويمكنك تجهيز مساحة العمل ومراجعة المحتوى بنفسك.
- اختر الواجهة البرمجية لموقع مخصّص أو إطار عمل مثل Next.js أو نظام إدارة محتوى خاص بك.
- في WordPress، تتولى الإضافة الجاهزة استيراد المقالات. اتبع دليل WordPress.
- المدونة المضمّنة خيار عرض أبسط عندما لا يتيح موقعك سوى إضافة كتلة HTML. تستخدم صفحات إطار Beulog المضمّن توجيه noindex. لنشر المقالات كصفحات أصلية قابلة للزحف على نطاقك، استخدم الواجهة البرمجية أو إضافة WordPress.
جهّز مساحة العمل والمفتاح
- تحقّق من حسابك واختر مساحة العمل الصحيحة. أكمل التحقق من البريد الإلكتروني، ثم اختر مساحة العمل من لوحة التحكم. ينتمي مفتاح النشر إلى مساحة العمل التي أنشأته فيها، ولا يمنح الوصول إلى جميع مساحات حسابك.
- أدخل بيانات الموقع النهائية. في «إعدادات مساحة العمل»، أدخل عنوان موقعك الآمن HTTPS في «الموقع الإلكتروني»، والمسار الفعلي للمقالات في «نمط روابط المقالات»، مثل /blog/{slug}. أضف «اسم الناشر أو العلامة التجارية» و«رابط شعار الناشر» إن توفر. استخدم «اسم الكاتب (اختياري)» و«رابط صفحة الكاتب (اختياري)» للكاتب الذي يُنسب إليه المحتوى فعلًا؛ وترك الاسم فارغًا ينسبه إلى العلامة التجارية.
- أنشئ مفتاح نشر. افتح «الربط والنشر ← موقعك الخاص ← مفاتيح النشر ← إنشاء مفتاح». اختر اسمًا واضحًا خاصًا بهذا الموقع. أبقِ «قراءة المقالات المنشورة» مفعّلة، واترك «الوصول إلى المسودات أيضًا» و«إنشاء مقالات جديدة» غير محدّدتين للموقع العام المعتاد.
- احفظ المفتاح بأمان على الخادم. انسخ المفتاح عند ظهوره؛ لن يُعرض كاملًا مرة أخرى. احفظه في متغيرات بيئة الخادم أو مخزن الأسرار لدى مزوّد الاستضافة. استخدم اسمًا مثل BEULOG_PUBLISHING_KEY، واحفظ معرّف مساحة العمل المتوقع بعد اختبار الاتصال.
- راجع مقالًا تجريبيًا وانشره. راجع العنوان والوصف ووصف الصورة والمصادر والمؤلف واللغة والعنوان النهائي قبل تغيير الحالة إلى منشور. لا تظهر المسودة في الاستجابة الافتراضية للمقالات العامة.
اختبر الاتصال
تستخدم جميع المسارات أدناه عنوان HTTPS الأساسي https://beulog.com/api/v1. استخدم ترويسة Authorization: Bearer للمصادقة. تبدأ مفاتيح النشر الفعلية بـ ab_live_. تحتوي الأمثلة على قيم بديلة وليست مفاتيح صالحة؛ شغّلها على الخادم أو في الطرفية لديك بعد استبدال القيم.
# Run on your server or in your own terminal.
# Replace the placeholder with a read-only publishing key.
export BEULOG_PUBLISHING_KEY='REPLACE_WITH_YOUR_READ_ONLY_KEY'
curl --fail-with-body --silent --show-error --max-time 30 \
'https://beulog.com/api/v1/connection' \
--header "Authorization: Bearer $BEULOG_PUBLISHING_KEY" \
--header 'Accept: application/json'{
"api_version": "1.2",
"workspace": {
"id": "00000000-0000-4000-8000-000000000001",
"name": "Example publication",
"language": "en"
},
"scopes": ["articles:read"],
"analytics": null
}تحقّق من workspace.id وworkspace.name قبل الاستيراد. قارن المعرّف بمساحة العمل التي يتوقعها موقعك، وتوقف إذا اختلف. يحدّد api_version إصدار استجابة الواجهة، بينما يحدّد schema_version داخل المقال إصدار صيغة المحتوى المصدّر.
إذا كانت التحليلات مفعّلة، يحتوي analytics على معرّف الموقع العام ومتطلب الموافقة ونطاقات المواقع المسموح بها فقط؛ وإلا تكون قيمته null. إعدادات نطاقات المواقع للتضمين والتحليلات منفصلة عن مصادقة الواجهة على الخادم، ولا تحل محل مفتاح النشر.
المسارات والصلاحيات
| الصلاحية | ما الذي تسمح به |
|---|---|
articles:read | قراءة المقالات المنشورة واختبار الاتصال وقراءة سجل المزامنة. استخدم هذه الصلاحية وحدها للموقع العام. |
drafts:read | صلاحية إضافية لتضمين المسودات عند استخدام drafts=true. لا تحل محل articles:read. أبقِ المعاينات خاصة. |
articles:generate | قراءة أسعار الإنشاء وبدء المهام ومتابعة حالتها. تستطيع هذه الصلاحية إنفاق الرصيد؛ خصّص لها مفتاحًا ومهمة منفصلين على الخادم. |
| الطريقة والمسار | الصلاحية المطلوبة | الاستجابة والغرض |
|---|---|---|
GET /connection | articles:read | هوية مساحة العمل والصلاحيات وapi_version وإعدادات التحليلات العامة إن توفرت. |
GET /articles | articles:read | مصفوفة data بصفحات من المقالات المنشورة المصدّرة كاملة. يتطلب drafts=true صلاحية drafts:read إضافية. |
GET /articles/{id} | articles:read | مقال واحد بمعرّف UUID، ويظل داخل data: [article]. تتطلب قراءة المسودة drafts=true وصلاحية drafts:read. المقال المفقود أو غير المتاح يعيد 404. |
GET /sync | articles:read | سجل مختصر لمعرّفات المقالات المنشورة وعناوينها ورموز تغيّرها، مع نقطة مزامنة وإصدار الإعدادات. |
GET /pricing | articles:generate | الحدود الحالية لحجز الرصيد لمهام article وarticle_with_image وresearch. |
POST /generate | articles:generate | إضافة مهمة إنشاء إلى الطابور. يتطلب جسم JSON وترويسة Idempotency-Key. يعيد معرّف المهمة وحالتها وبيانات الرصيد. |
GET /jobs/{id} | articles:generate | حالة المهمة ومرحلتها وخطؤها وarticle_id وcost وreserved_credits وsettled_at. |
لا توفر مسارات النشر هذه عملية لتعديل المقال أو حذفه أو upsert. يجري التحرير والنشر داخل Beulog، ويتولى تكاملك إدراج النسخة في قاعدة بيانات موقعك أو تحديثها. تجلب الواجهة المقال بمعرّف UUID وليس بالاسم المختصر slug. احتفظ بربط محلي بين slug والمعرّف لمسارات موقعك.
اجلب المقالات واتبع جميع الصفحات
تحتوي القائمة الافتراضية على المقالات المنشورة في مساحة عمل المفتاح، بالأحدث أولًا حسب وقت الإنشاء والمعرّف. تعني القائمة الفارغة الناجحة عدم وجود مقالات منشورة مطابقة، ولا تعني فشل المفتاح. لا تستبدل خطأ الواجهة بصمت بقائمة فارغة.
| المعامل | القيمة المقبولة والسلوك |
|---|---|
limit | عدد صحيح من 1 إلى 100؛ الافتراضي 20. |
cursor | انسخ pagination.next_cursor كما هو وشفّره للرابط. الحد الأقصى 1000 محرف. استخدم مساحة العمل ومرشح المسودات نفسيهما. توقف عندما تصبح next_cursor مساوية لـ null. |
offset | موضع بدء بالطريقة القديمة، عدد صحيح من 0 إلى 100000؛ الافتراضي 0. يُفضّل استخدام المؤشر cursor. لا تجمعه مع offset غير صفري. |
drafts=true | يضمّن المسودات مع المقالات المنشورة، ويتطلب articles:read وdrafts:read معًا. حذفه يبقي السلوك الافتراضي الذي يقتصر على المنشور. |
curl --fail-with-body --silent --show-error --max-time 30 \
'https://beulog.com/api/v1/articles?limit=20' \
--header "Authorization: Bearer $BEULOG_PUBLISHING_KEY" \
--header 'Accept: application/json'
# For the next page, use the exact pagination.next_cursor value.
BEULOG_NEXT_CURSOR='REPLACE_WITH_NEXT_CURSOR'
curl --fail-with-body --silent --show-error --max-time 30 --get \
'https://beulog.com/api/v1/articles' \
--data-urlencode 'limit=20' \
--data-urlencode "cursor=$BEULOG_NEXT_CURSOR" \
--header "Authorization: Bearer $BEULOG_PUBLISHING_KEY" \
--header 'Accept: application/json'تحتوي الاستجابة على data وpagination. اقرأ عناصر data، ثم اتبع pagination.next_cursor حتى تصبح null. تشير has_more إلى وجود صفحة أخرى، وتخص next_offset طريقة offset القديمة فقط. لا تفك المؤشرات أو تعدّلها أو تنشئها بنفسك. أعد بدء القائمة من الصفحة الأولى إذا رُفض مؤشرها.
BEULOG_ARTICLE_ID='REPLACE_WITH_ARTICLE_UUID'
curl --fail-with-body --silent --show-error --max-time 30 \
"https://beulog.com/api/v1/articles/$BEULOG_ARTICLE_ID" \
--header "Authorization: Bearer $BEULOG_PUBLISHING_KEY" \
--header 'Accept: application/json'استبدل المعرّف بمعرّف UUID لمقال من data. اقرأ data[0] في استجابة التفاصيل الناجحة؛ لا تعيد الواجهة كائن المقال مباشرة. لا يتاح المقال المسودة أو مقال مساحة عمل أخرى لمفتاح يقتصر على المنشور.
ماذا تتضمن استجابة المقال؟
| الحقل | كيفية استخدامه |
|---|---|
id, slug, title, status | استخدم id كهوية مصدر ثابتة، وslug لربط عنوان الصفحة، وstatus لضمان عرض المنشور فقط للعامة. احفظ معرّف مساحة العمل المتصلة مع المقال. |
revision | رمز تغيّر غير قابل للتفسير للتصدير. قارنه بإصدار التصدير السابق لتجاوز المحتوى الذي لم يتغير. يشمل المحتوى المصدّر وإعدادات النشر؛ رقم نسخة المقال وحده غير كافٍ. |
html | جزء HTML دلالي لجسم المقال يتضمن عنصر article وعنوان H1 والأقسام والروابط والنص البديل للصورة والمراجع واللغة واتجاه القراءة. ليس مستند HTML كاملًا. |
head_html | عنوان ووصف وتوجيهات robots ورابط canonical عند توفره وبيانات المشاركة وJSON-LD، جاهزة لرأس مستند يُعرض من الخادم. استخدمه أو استخدم تحويل البيانات عبر إطار العمل. |
seo | حقول منظّمة للعنوان والوصف وcanonical وrobots واللغة وopenGraph وtwitter لإطار العمل لديك. قد يكون canonical مساويًا لـ null إذا لم يُضبط العنوان النهائي. |
json_ld | بيانات منظّمة تُنشأ من المقال وإعدادات مساحة العمل. حافظ على تطابق المؤلف والناشر واللغة والتواريخ والصور والمراجع والرابط مع الصفحة المرئية. |
content | محتوى منظّم قابل للتحرير يشمل imageAlt وimageCaption والأقسام والنقاط الأساسية والأسئلة الشائعة. استخدمه لبناء تخطيط خاص بدل html الجاهز. |
image_url, image_width, image_height | رابط الغلاف وأبعاده عند توفرها. حافظ على الأبعاد الصحيحة والنص البديل عند استبدال مكوّن الصورة، ولا تخترع قيمًا مفقودة. |
publishing_checks, reading_minutes, schema_version | فحوص التصدير ووقت القراءة التقديري وإصدار صيغة المحتوى. تساعد الفحوص في المراجعة، ولا تمنح اعتمادًا لموقعك أو تضمن ترتيب البحث. |
استورد باستخدام عميل TypeScript
نزّل العميل وضعه في وحدة تعمل على الخادم فقط. يستخدم fetch وAbortSignal.timeout الأصليين؛ استخدم بيئة خادم حديثة تدعمهما. يرفض العميل العمل داخل المتصفح. مرّر https://beulog.com إلى المُنشئ، فهو يضيف /api/v1 بنفسه.
// Server file. Save the downloaded client as ./beulog-client.ts.
import { BeulogClient, type PublishedArticle } from "./beulog-client";
// Implement this adapter using your site's database or CMS.
// Upsert means update the same article, or insert it if it is new.
type ArticleStore = {
upsert(workspaceId: string, article: PublishedArticle): Promise<void>;
};
export async function importPublishedArticles(store: ArticleStore) {
const key = process.env.BEULOG_PUBLISHING_KEY;
const expectedWorkspaceId = process.env.BEULOG_WORKSPACE_ID;
if (!key || !expectedWorkspaceId) {
throw new Error("Configure the server key and expected workspace ID.");
}
const client = new BeulogClient("https://beulog.com", key);
const connection = await client.connection();
if (connection.workspace.id !== expectedWorkspaceId) {
throw new Error("The key belongs to a different workspace.");
}
let imported = 0;
for await (const article of client.articles()) {
await store.upsert(connection.workspace.id, article);
imported += 1;
}
return { workspaceId: connection.workspace.id, imported };
}يتبع client.articles() صفحات المؤشر ويعيد المقالات المنشورة تباعًا. يعيد client.article(id) العنصر data[0]. ويوفر العميل أيضًا connection() وpricing() وgenerate() وjob(). لقراءة المسودات أو سجل المزامنة أو استخدام طلبات ETag الشرطية، استخدم مسارات HTTP الموثّقة مباشرة؛ لا يوفّر العميل هذه الخيارات.
اجعل تكرار الاستيراد آمنًا: استخدم مفتاحًا فريدًا مثل (workspace_id, article_id)، وحدّث السجل الموجود عندما يتغير إصدار تصديره، ثم حدّث الصفحة المعروضة وخريطة الموقع بعد نجاح التحديث. حدّد كذلك كيفية الحفاظ على التعديلات التي تُجرى مباشرة في موقعك.
حافظ على تحديث موقعك
للتحديثات الدورية، يقدم /sync سجلًا صغيرًا لاكتشاف التغييرات. يعيد المعرّفات والعناوين وإصدارات السجل، دون HTML المقالات. اجلب المقال كاملًا عندما يكون إصدار السجل جديدًا أو متغيرًا فقط. شغّل ذلك في مهمة مجدولة على الخادم، وليس مع كل زيارة.
| المعامل | القيمة المقبولة والسلوك |
|---|---|
limit | عدد صحيح من 1 إلى 100؛ الافتراضي 50. |
since | نقطة المزامنة المحفوظة سابقًا، بنص التاريخ والوقت ISO نفسه الذي أعادته الواجهة. احذفه في أول فحص كامل. |
settings_revision | احفظه مع checkpoint وأرسله مع since. إذا تغيرت إعدادات النشر أو غابت القيمة أو اختلفت، تبدأ الواجهة فحصًا كاملًا. |
cursor | قيمة pagination.next_cursor كما وردت في هذا الفحص، مع تشفيرها للرابط؛ حدها 2000 محرف. تحفظ الحد الزمني للفحص. تعني استجابة 400 ضرورة إعادة بدء الفحص. |
- ابدأ دون since/settings_revision، أو حمّل القيمتين من آخر فحص اكتمل بالكامل. تحقّق من مطابقة workspace_id لمساحة العمل المتوقعة.
- لكل عنصر، قارن إصدار السجل بإصدار السجل المحفوظ للمقال. اجلب العناصر المتغيرة من GET /articles/{id}، ثم أدرج التصدير الكامل أو حدّثه في مخزنك المحلي.
- احفظ المقال المحلي وإصدار السجل الذي عالجته معًا، وبعد نجاح الاستيراد فقط. احفظ إصدار التصدير وإصدار السجل في حقلين منفصلين؛ فهما رمزان مختلفان ولا تصح مقارنتهما ببعضهما.
- واصل باستخدام pagination.next_cursor حتى تصبح null. احتفظ بنقطة المزامنة السابقة إذا فشلت صفحة أو عملية استيراد. يجب أن يكون تكرار معالجة المقالات السابقة آمنًا.
- بعد نجاح جميع الصفحات وعمليات الاستيراد، احفظ checkpoint وsettings_revision اللذين أعادتهما الواجهة كزوج واحد. إذا كنت تستخدم طابورًا دائمًا، فلا تتقدم إلا بعد حفظ عمل جميع الصفحات فيه مع إمكانية إعادة المحاولة. لا تستخدم الوقت الحالي لجهازك كنقطة مزامنة تالية.
# First scan: no since or settings_revision.
curl --fail-with-body --silent --show-error --max-time 30 \
'https://beulog.com/api/v1/sync?limit=50' \
--header "Authorization: Bearer $BEULOG_PUBLISHING_KEY" \
--header 'Accept: application/json'
# Only after every page was processed successfully, save the returned
# checkpoint and settings_revision. Use both for the next scan.
BEULOG_SYNC_CHECKPOINT='REPLACE_WITH_SAVED_CHECKPOINT'
BEULOG_SETTINGS_REVISION='REPLACE_WITH_SAVED_SETTINGS_REVISION'
curl --fail-with-body --silent --show-error --max-time 30 --get \
'https://beulog.com/api/v1/sync' \
--data-urlencode 'limit=50' \
--data-urlencode "since=$BEULOG_SYNC_CHECKPOINT" \
--data-urlencode "settings_revision=$BEULOG_SETTINGS_REVISION" \
--header "Authorization: Bearer $BEULOG_PUBLISHING_KEY" \
--header 'Accept: application/json'يتداخل السجل عمدًا مع نقطة المزامنة السابقة بخمس دقائق لتقليل احتمال فقد التحديثات قرب اعتماد عمليات قاعدة البيانات. ظهور المعرّفات مجددًا أمر متوقع؛ امنع التكرار اعتمادًا على معرّف المصدر وإصدار السجل. يبطل تغيير الإعدادات المؤشر الجاري؛ أعد البدء من آخر زوج محفوظ للنقطة والإعدادات، واسمح بالفحص الكامل الناتج، وحدّث السجلات بأمان.
اعرض المقال وبيانات الصفحة
امنح كل مقال عنوانًا دائمًا وعامًا على موقعك. اعرض المقال ضمن استجابة الخادم أو عند بناء الموقع، بحيث يتوفر النص والروابط والبيانات دون طلب مصادق عليه من المتصفح. توصي Google بالعرض من الخادم أو العرض المسبق لأنه يفيد الزوار وبرامج الزحف، وبعضها لا ينفّذ JavaScript. إرشادات Google لتهيئة مواقع JavaScript للبحث.
اختر طريقة واحدة لبيانات الصفحة
- قالب خادم تقليدي: أدرج head_html في رأس المستند وhtml في جسمه. أبقِ ترويستي charset وviewport الخاصتين بالقالب. لا تحوّل الأجزاء الجاهزة إلى نص ظاهر، ولا تضع head_html داخل جسم المقال.
- بيانات إطار العمل: حوّل seo إلى واجهة بيانات الصفحة في إطار العمل واعرض json_ld مرة واحدة. اعرض html في جسم الصفحة. لا تدرج head_html أيضًا، لأنه يحتوي أصلًا على العنوان والترويسات وcanonical وJSON-LD.
// Server-side Next.js App Router metadata helper.
// Save the downloaded client at the import path used below.
import type { Metadata } from "next";
import type { PublishedArticle } from "./beulog-client";
export function articleMetadata(article: PublishedArticle): Metadata {
const imageAlt = typeof article.content.imageAlt === "string"
? article.content.imageAlt
: article.title;
const locale = article.seo.openGraph.locale;
return {
title: { absolute: article.seo.title },
description: article.seo.description,
robots: article.seo.robots,
alternates: article.seo.canonical
? { canonical: article.seo.canonical }
: undefined,
openGraph: {
type: "article",
title: article.seo.title,
description: article.seo.description,
url: article.seo.canonical ?? undefined,
locale: typeof locale === "string" ? locale : undefined,
images: article.image_url
? [{ url: article.image_url, alt: imageAlt }]
: [],
},
twitter: {
card: article.image_url ? "summary_large_image" : "summary",
title: article.seo.title,
description: article.seo.description,
images: article.image_url
? [{ url: article.image_url, alt: imageAlt }]
: [],
},
};
}// A Server Component; article comes from your server-side import.
import type { PublishedArticle } from "./beulog-client";
export function ArticleBody({ article }: { article: PublishedArticle }) {
const jsonLd = JSON.stringify(article.json_ld).replace(/</g, "\u003c");
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: jsonLd }}
/>
<div dangerouslySetInnerHTML={{ __html: article.html }} />
</>
);
}اضبط لغة المستند من seo.language، واستخدم الاتجاه من اليمين إلى اليسار للعربية. حافظ على سمتي lang وdir داخل المقال. إذا بنيت العرض من content، فأعد إنشاء عناوين ميسّرة وروابط فعلية ونصوص بديلة وصفية للصور وجداول ومراجع. أضف تنقّل موقعك وخطوة تالية مفيدة حول المقال دون عنوان H1 ثانٍ للمقال نفسه.
هيّئ صفحات موقعك للاكتشاف
- طابق canonical مع الصفحة الفعلية. يُنشئ الموقع الإلكتروني مع نمط عنوان المقال رابط canonical الافتراضي، وتتجاوزه قيمة رابط المقال المنشور داخل المقال. تحقّق من أنه عنوان HTTPS النهائي للمقال على نطاقك، وليس رابط الواجهة أو الإطار المضمّن. صحّح canonical المفقود أو الخاطئ قبل الإطلاق، وتجنّب تعارضه مع قالبك أو إضافة SEO.
- استخدم بيانات دقيقة للصفحة والمشاركة. راجع عنوان SEO ووصف SEO في محرر المقال. احتفظ بعنوان واحد ووصف مفيد وبيانات صورة متّسقة في Open Graph وTwitter. قد تختار محركات البحث عنوانًا أو مقتطفًا مختلفًا؛ البيانات وصف للصفحة وليست وعدًا بترتيبها.
- اجعل الصور مفيدة وسريعة. استخدم imageAlt لوصف الصورة المرئية، وحافظ على العرض والارتفاع المعروفين. وفّر صورًا مضغوطة ومتجاوبة عبر نظام الصور لديك عند الحاجة. حمّل غلاف المقال الظاهر بسرعة، وأجّل تحميل الصور البعيدة أسفل الصفحة. يجب أن يحافظ التخطيط المخصّص على المعنى والنص البديل الميسّر.
- اجعل البيانات المنظّمة صادقة. استخدم المؤلف الحقيقي أو الجهة المنسوب إليها المحتوى، وملفًا متاحًا للمؤلف إن توفر. اضبط علامتك وموقعك بوصفهما الناشر؛ Beulog مزوّد البرنامج، وليس تلقائيًا ناشر مقالات موقعك. طابق اللغة ورابط المقال والتواريخ والصور مع ما يراه القارئ. حافظ على الاستشهادات المفيدة بالمصادر. لا تضف تقييمات أو مؤلفين أو ادعاءات مختلقة، ولا تتوقع أن تؤدي الشيفرة وحدها إلى نتائج بحث محسّنة.
- اجعل اكتشاف المقالات سهلًا. اربط المقالات بفهرس مدونة أصلي وصفحات ذات صلة باستخدام روابط عادية بنص واضح. ضمّن في خريطة الموقع عناوين المقالات المنشورة الحالية والأساسية فقط. إذا نشرت ترجمات فعلية، فاستخدم عناوين منفصلة للغات وhreflang متبادلًا؛ ولا تُشر إلى ترجمة غير موجودة.
- أبقِ الصفحات العامة متاحة. ينبغي أن تعيد الصفحات المنشورة المخصصة للبحث محتوى مفيدًا مع HTTP 200، دون تسجيل دخول أو noindex غير مقصود. راجع robots.txt وقواعد الاستضافة وشبكة التوزيع. أتح صفحات المقالات لبرامج الزحف دون كشف مفتاح الواجهة السري. احمِ معاينات المسودات بصلاحيات وصول خاصة وnoindex.
تعتمد AI Overviews وAI Mode في Google على أسس SEO نفسها؛ ولا تشترط Google مخطط AI منفصلًا أو ملفًا خاصًا للذكاء الاصطناعي. يجب أن تكون الصفحة المؤهلة مفهرسة وقابلة للعرض بمقتطف بحث. يساعد المحتوى الأصلي المفيد والصفحات الأصلية المتاحة على الاكتشاف، لكن استخدام الواجهة أو بيانات الصفحة لا يضمن ترتيبًا أو استشهادًا من الذكاء الاصطناعي. إرشادات Google لميزات الذكاء الاصطناعي.
اتبع قائمة المراجعة الكاملة للنشر وGoogle وبحث الذكاء الاصطناعي. تغطي صلاحيات الزحف لمحركات البحث ومزوّدي الذكاء الاصطناعي، وفحوص Search Console وتجربة الصفحة ومراجعة المحتوى.
Google: عناوين canonical · Google: البيانات المنظّمة للمقالات
تعامل مع إلغاء النشر والمقالات المفقودة
يلغي إلغاء نشر المقال أو حذفه داخل Beulog ظهوره في الطلبات الجديدة التي تقتصر على المنشور. لكنه لا يحذف نسخة سبق استيرادها إلى موقعك. حدّد سرعة انعكاس الإزالة المطلوبة في موقعك ونفّذ هذه السياسة بوضوح.
- للتحقق المباشر من مقال معروف، اطلب GET /articles/{id} بمفتاح يقتصر على المنشور. تعني 404 أنه غير متاح عبر مساحة العمل والمفتاح هذين؛ أخفِ نسخته العامة وفق سياستك. لا تثبت 401 أو403 أو429 أو المهلة أو أخطاء 5xx أنه حُذف.
- للمطابقة الدورية، أكمل فحصًا جديدًا لجميع المقالات المنشورة وقارن المعرّفات بالمقالات المستوردة من مساحة العمل المتحقق منها نفسها. لا تتصرف بناءً على الغياب إلا بعد نجاح جميع الصفحات. لا تزل محتوى جماعيًا بعد فحص ناقص أو خطأ اتصال. إذا كانت الإزالة ذات أثر مهم، فتحقّق من المعرّفات المفقودة منفردة قبل تغيير حالتها العامة.
- للصفحة العامة المفقودة فعلًا، أعد حالة 404 أو410 حقيقية وأزلها من خريطة الموقع والروابط الداخلية. استخدم إعادة توجيه دائمة فقط عند وجود بديل مناسب فعلًا؛ ولا توجّه كل مقال محذوف إلى الصفحة الرئيسية.
- امسح أو حدّث مخازن الصفحات وشبكة التوزيع والبناء لديك بعد التعديلات والإزالة. حدّد سياسة لتغيير slug تتضمن إعادة توجيه دائمة من العنوان القديم عندما ينتقل المقال نفسه. تعامل مع فشل الشبكة وفق سياسة الانقطاع، ولا تعرضه كمقال فارغ ناجح.
في Next.js، استخدم notFound() للمورد الذي تأكد فقده، وتحقق من حالة HTTP النهائية في الإنتاج. أعد خطأ خدمة مؤقتًا مناسبًا عند انقطاع المصدر. تجنّب إرسال محتوى الصفحة قبل التحقق من المورد إذا كان ذلك سيحوّل الصفحة المفقودة إلى استجابة متدفقة بحالة 200.
الأخطاء وإعادة المحاولة ومعرّفات الطلبات
تستخدم أخطاء الواجهة جسم JSON يتضمن error وcode. تتضمن الاستجابات X-Request-Id لتشخيص المشكلات؛ سجّل الحالة والرمز والمسار ومعرّف الطلب على الخادم دون تسجيل المفتاح. احتفظ بمعرّف الطلب عند التواصل مع الدعم. تحدّد استجابات v1 الإصدار أيضًا عبر X-API-Version.
| الحالة / الرمز | الإجراء المناسب |
|---|---|
400 invalid_request | راجع معرّفات UUID وحدود الاستعلام وJSON وIdempotency-Key. أعد بدء فحص المؤشر المرفوض؛ ولا تكرر الطلب غير الصالح نفسه. |
401 unauthorized | راجع مفتاح Bearer ومساحة العمل والتحقق من الحساب واحتمال إلغاء المفتاح. لا تكشف المفتاح أثناء التشخيص. |
402 insufficient_credits | رصيد الإنشاء غير كافٍ. راجع الرصيد قبل المحاولة مجددًا؛ قراءة المقالات المنشورة لا تبدأ مهمة إنشاء. |
403 forbidden | راجع الصلاحية المطلوبة وقيود الحساب. تتطلب قراءة المسودات drafts:read مع articles:read، ويتطلب الإنشاء articles:generate. |
404 not_found | راجع المسار ومعرّف UUID. للمقال، تحقّق من مساحة العمل واستمرار النشر. عالج غياب المقال المؤكد على موقعك. |
409 conflict | في الإنشاء، قد يتجاوز الحجز الحالي maxCredits. أعد قراءة /pricing واعتمد حد إنفاق جديدًا بقرار واضح بدل رفعه تلقائيًا. |
429 rate_limited | التزم بـ Retry-After وخفّض المعدل واستخدم عددًا محدودًا من المحاولات. الحدود 120 طلب واجهة في الدقيقة لكل مفتاح و20 طلب إنشاء في الساعة لكل حساب. |
500 / 502 / 503 / 504 | تعامل مع أعطال الخدمة والشبكة كمؤقتة. أعد المحاولة بتأخير وحد أقصى، واحتفظ بنقطة المزامنة السابقة الآمنة، وأرسل تنبيهًا إذا استمر الفشل. لا تفسّرها كإلغاء نشر. |
يجري العميل الجاهز حتى ثلاث محاولات HTTP عند 429 و502 و503 و504، باستخدام Retry-After الرقمي أو تأخير تصاعدي قصير بحد أقصى 60 ثانية. ويرمي BeulogError مع status وcode وrequestId بعد الاستجابة غير الناجحة. تحتاج أخطاء الشبكة والمهل إلى معالجة إعادة محاولة محدودة لديك. يجب أن تعيد محاولة الإنشاء باستخدام Idempotency-Key الأصلي نفسه.
التخزين المؤقت والطلبات الشرطية
تستخدم الاستجابات المصادق عليها Cache-Control: no-store وتتغير بحسب Authorization. اجعل مخزن المحتوى المحلي المقصود خاصًا بالتكامل وافصله بحسب مساحة العمل. توفر استجابات GET قيمة ETag؛ ويمكن لعميل HTTP مباشر إرسالها كما هي في If-None-Match. عند 304، أعد استخدام الاستجابة المحفوظة ولا تحاول قراءة جسم JSON. لا ينفّذ عميل TypeScript المتاح هذا المسار الشرطي.
اختياري: أنشئ مقالًا مع ضبط الإنفاق
لا تتطلب قراءة المقالات وعرضها صلاحية الإنشاء. إذا أردت سير عمل على الخادم ينشئ المقالات أيضًا، فأنشئ مفتاحًا منفصلًا مع تفعيل إنشاء مقالات جديدة. لا تعطِه للزوار؛ فهو يستطيع حجز رصيد حسابك وإنفاقه.
| الحقل | القيمة المقبولة والسلوك |
|---|---|
topic | نص بحد أقصى 1500 محرف؛ الافتراضي نص فارغ. حدّد موضوعًا واضحًا للمهمة المقصودة. |
image | قيمة منطقية؛ الافتراضي true. استخدم false لطلب مقال دون صورة مولّدة. |
autoPublish | قيمة منطقية؛ الافتراضي false. أبقِها false للمراجعة التحريرية قبل إتاحة المقال للتكاملات العامة. |
kind | article أوresearch؛ الافتراضي article. تنشئ دالة generate() في العميل مهام مقالات؛ استخدم HTTP مباشرة لمهام البحث. |
maxCredits | عدد صحيح اختياري من 1 إلى 1000000. إذا تجاوز الحجز هذا السقف، تعاد 409 دون حجز رصيد. استخدم /pricing الحالي وحد الإنفاق الذي اعتمدته. |
researchId | معرّف UUID اختياري لملخص بحث موجود في مساحة العمل نفسها. استخدم HTTP مباشرة؛ لا يوفّر العميل هذا الحقل. |
أرسل ترويسة Idempotency-Key بطول من 1 إلى 128 محرفًا. احفظ قيمة فريدة لكل مهمة مقصودة قبل إرسالها، وأعد استخدامها عند المحاولة بالمفتاح البرمجي نفسه. يعيد المفتاح والقيمة نفسيهما المهمة الموجودة بدل حجز الرصيد مجددًا، ولا يطبّقان مدخلات معدّلة عليها. تحتاج المهمة الجديدة المقصودة إلى قيمة جديدة.
// Separate server task. This key can spend account credits.
import { BeulogClient } from "./beulog-client";
export async function queueReviewedArticle() {
const key = process.env.BEULOG_GENERATION_KEY;
// Persist one unique ID per intended job BEFORE submitting it.
// Reuse that same ID if the request times out or is retried.
const requestId = process.env.BEULOG_GENERATION_REQUEST_ID;
if (!key || !requestId) {
throw new Error("Configure the generation key and stable request ID.");
}
const client = new BeulogClient("https://beulog.com", key);
const pricing = await client.pricing();
return client.generate({
topic: "A practical guide to choosing a content calendar",
image: false,
autoPublish: false,
maxCredits: pricing.article,
}, requestId);
}
export async function checkGenerationJob(jobId: string) {
const key = process.env.BEULOG_GENERATION_KEY;
if (!key) throw new Error("Configure the generation key.");
return new BeulogClient("https://beulog.com", key).job(jobId);
}- اقرأ /pricing قبل الإرسال. قيم article وarticle_with_image وresearch حدود حجز قصوى وليست تأكيدًا للتكلفة النهائية.
- احفظ معرّف المهمة من POST /generate. افحص GET /jobs/{id} بمفتاح الإنشاء على فترات مثل كل 10 إلى 30 ثانية، مع مهلة إجمالية وتأخير عند الفشل؛ ولا تفحص في حلقة متواصلة بلا انتظار.
- استمر عندما تكون status هي queued أوrunning. توقف عند completed أوfailed. عند الفشل، سجّل الخطأ ومعرّف الطلب، ولا ترسل تلقائيًا مهمة جديدة قابلة للإنفاق. عند الاكتمال، يحدّد article_id نتيجة مهمة المقال.
- عند autoPublish:false، راجع المسودة داخل Beulog وانشرها عندما تصبح جاهزة. لا يستطيع المفتاح المعتاد المقتصر على المنشور جلبها قبل ذلك. تتطلب المعاينة الخاصة articles:read مع drafts:read والمسار المباشر بمعامل ?drafts=true.
- يمثل reserved_credits الرصيد المحجوز؛ وتمثل cost الحجز أثناء الانتظار والتكلفة النهائية بعد الاكتمال؛ وتسجّل settled_at التسوية. يُعاد الرصيد المحجوز غير المستخدم بعد النجاح، وتُرد تكلفة المهام الفاشلة كاملة.
راجع التكامل قبل إطلاقه
- يعيد الاتصال مساحة العمل المقصودة المتحقق منها والصلاحيات المطلوبة فقط، ولا يظهر مفتاح النشر في مصدر الصفحة أو طلبات المتصفح أو الحزم العامة.
- يظهر المقال التجريبي المنشور مرة واحدة في عنوانه الأصلي النهائي. ويتوفر نصه وعنوان H1 واحد للمقال والنص البديل للصورة والمراجع واللغة والبيانات في استجابة الخادم.
- تتضمن الصفحة canonical المقصود دون noindex غير متعمّد أو تكرار للبيانات والمخطط، وتعمل صور المشاركة. اختبر البيانات المنظّمة بأداة النتائج المنسّقة من Google وافحص العنوان الفعلي في Search Console.
- يعمل استيراد أكثر من صفحة مقالات بصورة صحيحة، ولا ينشئ تكرار الاستيراد نسخًا مكررة. ويحدّث تعديل المقال أو إعدادات النشر النسخة المحلية وبياناتها.
- تبقى المسودة خاصة. ويتبع إلغاء نشر المقال التجريبي سياسة الإزالة وتحديث التخزين المؤقت لديك. ويعيد العنوان المفقود فعلًا 404 أو410، ولا يظهر انقطاع الواجهة كصفحة فارغة ناجحة.
- تظهر إعادة بدء المؤشرات وحدود المعدل والمفاتيح غير الصالحة أو الملغاة والمهل ومهام الإنشاء الفاشلة في مراقبة الخادم مع معرّفات الطلبات ودون أسرار.
فتح أداة اختبار النتائج المنسّقة · فتح Google Search Console · تابع إلى دليل SEO للنشر