المنشورات
انشر منشورًا
تنشر التطبيقات الفعلية فورًا أو تجدول بموعد أو تحفظ مسودة، أما الاختبارية فتحاكي فقط. مع ?dry_run=true يفحص كل شيء ولا يكتب شيئًا.
يعود المنشور إلى منشأة ويُنشر على شبكة أو أكثر، أهدافه. لكل هدف نصه ووسائطه وصيغته وحالته.
نوع المنشور: الآن أو مجدول أو مسودة
حقلان في الجسم يحددان متى يُنشر المنشور، وهل يُنشر:
| الحالة | الجسم | السلوك |
|---|---|---|
| الآن | دون scheduledAt | يُنشر المنشور فورًا. |
| مجدول | scheduledAt: تاريخ وساعة مستقبليان بصيغة ISO 8601 | سيُنشر في scheduledAt. |
| مسودة | "status": "draft"، دون scheduledAt | يُحفظ ولا يُنشر. |
جسم المنشور
| الحقل | المعنى |
|---|---|
establishmentId | المنشأة التي تنشر (GET /v1/establishments) |
targets[] | مدخل لكل شبكة: platform وtext، واختياريًا media وformat وaccountId |
targets[].media[] | وسيط من مكتبة الوسائط بـ id الخاص به، أو url عام بـ https مع type (image أو video) |
targets[].accountId | الحساب المراد استخدامه حين يكون للمنشأة عدة حسابات على هذه الشبكة |
scheduledAt | تاريخ وساعة مستقبليان بصيغة ISO 8601؛ وإن غاب، يُنشر المنشور فورًا |
status | draft لحفظ مسودة لا تُنشر (دون scheduledAt حينئذٍ) |
وسائط هدف
يحدد كل مدخل في targets[].media وسيطًا من مكتبة الوسائط بـ id الخاص به، أو url عامًا بـ https مع type (image أو video). يتطلب Instagram وTikTok صورة أو فيديو. ولإضافة وسيط إلى مكتبة الوسائط، انظر استيراد وسيط.
تكرار منشور
لا يوجد endpoint مخصص لتكرار منشور: اقرأه بـ `GET /v1/posts/{id}`، ثم أعد إرسال محتواه في طلب POST /v1/posts جديد.
قبل إعادة إرساله، أزل الحقول التي تملؤها Sofia بنفسها. على الأقل:
idوcreatedAtالخاصان بالمنشور؛statusللمنشور المقروء (يلخّص حالة الإرسال): حدّد الحالة التي تريدها أو احذفه؛- في كل هدف:
stateوpublishedAtوpermalinkوerror.
أبقِ establishmentId، ولكل هدف platform وaccountId. لا تعيد القراءة نص الأهداف ولا وسائطها: قدّمها من جديد. وأخيرًا حدّد scheduledAt جديدًا (أو احذفه للنشر فورًا، أو أرسل "status": "draft").
منشورك الأول
1. تحقق من الشبكات المرتبطة
يُنشر المنشور عبر الحسابات المرتبطة بالمنشأة. اسردها؛ وإن نقص أحدها، فأنشئ رابط اتصال. انظر الحسابات المرتبطة.
2. أضف وسيطًا
يتطلب Instagram وTikTok صورة أو فيديو. استورد واحدًا من عنوان URL عام بـ https؛ تنزّله Sofia إلى مكتبة الوسائط وتعيد id الخاص به. انظر استيراد وسيط.
3. تحقق بمحاكاة
أضف ?dry_run=true: تحكم Sofia على كل شبكة بقواعدها الفعلية وبالحساب المرتبط، ولا تكتب شيئًا.
curl -X POST 'https://api.sofia-post.com/api/v1/posts?dry_run=true' \
-H "Authorization: Bearer $SOFIA_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"establishmentId": "'$ESTABLISHMENT_ID'",
"targets": [
{ "platform": "instagram", "text": "Tarte tatin du jour", "media": [{ "id": "'$MEDIA_ID'" }] },
{ "platform": "facebook", "text": "Tarte tatin du jour", "media": [{ "id": "'$MEDIA_ID'" }] }
]
}'{
"status": "ready",
"dryRun": true,
"targets": [
{ "platform": "instagram", "accountId": "fecd0904-…", "handle": "sof_ia_officiel", "state": "ready" },
{ "platform": "facebook", "accountId": "a423b3a4-…", "handle": "Sofia post", "state": "ready" }
]
}4. انشر
أرسل الجسم نفسه دون dry_run، مع Idempotency-Key كي لا تنشر المحاولة الجديدة مرتين أبدًا. دون scheduledAt، يُنشر المنشور فورًا؛ ومع scheduledAt مستقبلي يُجدول.
curl -X POST https://api.sofia-post.com/api/v1/posts \
-H "Authorization: Bearer $SOFIA_API_KEY" \
-H 'Content-Type: application/json' \
-H "Idempotency-Key: $(uuidgen)" \
-d @post.json5. تابعه
يرد المنشور publishing، ثم تنتقل كل شبكة إلى published مع رابطها الدائم، أو إلى failed مع سببها. اقرأه بـ `GET /v1/posts/{id}`، أو سجّل webhook لتُنبَّه.
المحاكاة (dry run)
POST /v1/posts?dry_run=true ينفّذ فحوص منشور حقيقي: قواعد كل شبكة، والحساب المرتبط، والوسائط، والتاريخ، وباقتك. لا يحفظ شيئًا ولا يرسل شيئًا.
جاهز
حين تقبل كل شبكة المنشور، يكون الرد 200 مع status: "ready" ولكل هدف الحساب الذي سينشر.
مرفوض
وإلا يكون الرد 422 post_refused، مع تفصيل لكل سبب. يسمّي كل تفصيل شبكته وcode الخاص به، ويبيّن ما يجب تصحيحه.
{
"error": {
"code": "post_refused",
"message": "The post would not be published: x: the text is too long (300 characters, at most 280)",
"details": [
{
"platform": "x",
"code": "caption_too_long",
"max": 280,
"actual": 300,
"message": "x: the text is too long (300 characters, at most 280)"
}
],
"docUrl": "https://www.sofia-post.com/developers/errors#post_refused"
}
}كل سبب مدرج في الأخطاء.
لوضع الاختبار للتطبيقات، انظر وضع الاختبار والمحاكاة. ويحمي Idempotency-Key أيضًا POST /v1/posts: انظر قابلية التكرار الآمن.
التفويضات
Authorizationstringheaderمطلوبمفتاحك الشخصي أو رمز وصول OAuth، يُرسل كـ
Bearer <token>.
معاملات الاستعلام
dry_runstringtrue: ينفّذ كل فحص كان الإرسال سينفذه (قواعد الشبكات والحسابات والوسائط والإنشاء والاشتراك الفعلي) ولا يكتب شيئًا. يعيد 200readyأو 422post_refused.القيم المسموحة:
truefalse
الترويسات
Idempotency-Keystringعند إعادة الطلب بالجسم نفسه يعيد الاستجابة نفسها دون إنشاء منشور ثانٍ. التجربة الجافة لا تستهلك المفتاح.
الجسم
establishmentIdstringمطلوبالمنشأة، في مساحة عمل منحة الرمز (
GET /v1/establishments)targetsobject[]مطلوبشبكة واحدة لكل هدف
عرض الخصائص الفرعية
platformstringمطلوبالشبكة المستهدفة
القيم المسموحة:
instagramfacebookxlinkedintiktoktextstringمطلوبالنص المصاحب المنشور على هذه الشبكة
mediaobject[]الوسائط المرفقة
عرض الخصائص الفرعية
idstringمعرّف وسائط من مكتبة المنشأة (وإلا
urlوtype)urlstringالعنوان العام للوسائط (https في الوضع الفعلي)؛ دون معرّف
typestringنوع الوسائط المعطاة بعنوان
القيم المسموحة:
imagevideo
formatstringالصيغة (
postوreelوstoryوcarousel...)؛ افتراضيًا الصيغة التي تقدمها الشبكةaccountIdstringفي الوضع الفعلي: الحساب المتصل الذي ينشر، عندما تملك المنشأة عدة حسابات على هذه الشبكة (
GET /v1/establishments/:id/accounts)
scheduledAtstring<date-time>موعد الجدولة (ISO 8601)، في المستقبل؛ عند الغياب: النشر فورًا. غير مسموح مع
statusdraftstatusstringdraft: مسودة (في الوضع الفعلي فقط)، تُنشأ بلا موعد ولا يُرسل شيء؛ يجدولهاPATCH /v1/posts/:idالقيم المسموحة:
draft
الاستجابة
تجربة جافة: اجتازت كل الفحوص.
statusstringمطلوبدائمًا
readyالقيم المسموحة:
readydryRunbooleanمطلوبدائمًا
trueالقيم المسموحة:
truetargetsobject[]مطلوبالأهداف المفحوصة
عرض الخصائص الفرعية
platformstringمطلوبشبكة الهدف
statestringمطلوبدائمًا
readyالقيم المسموحة:
readyaccountIdstringفي الوضع الفعلي: الحساب الذي سينشر
handlestringفي الوضع الفعلي: معرّفه المعروض (handle)