دليل المستخدم مرجع الواجهة البرمجية (API)

تحويل المقالات إلى صوت (ATS)

حوّل مقالاً كاملاً إلى صوت مسرود وتفريغ نصي، ويُسلَّم بشكل غير متزامن إلى رابط الاستدعاء (callback URL) الخاص بك.

POST https://api.moknah.io/process-text

تستقبل نقطة نهاية ATS (تحويل المقالات إلى صوت) نص المقال وتولّد سرداً صوتياً MP3 مع ملف تفريغ نصي متزامن (.srt). يتم التوليد بشكل غير متزامن: يعود الطلب فوراً بالرمز 202 Accepted، وتُسلَّم الملفات النهائية إلى callbackURL الذي تحدده. وهي الخدمة نفسها التي تشغّل إضافة ATS لووردبريس.

غير متزامن بطبيعته

لا تنتظر استجابة HTTP للحصول على الصوت. تردّ نقطة النهاية بالرمز 202 فوراً، وترسل النتيجة إلى callbackURL الخاص بك عند اكتمال التوليد.

المصادقة

أرسل مفتاح API الخاص بشركتك كرمز Bearer في ترويسة Authorization.

Authorization: Bearer your_api_key

محتوى الطلب (Request Body)

أرسل جسم طلب JSON يحتوي على نص المقال الخام وكائن postData يصف الطلب.

Parameter إجراء مطلوب النوع الوصف
text مطلوب نص (string) نص المقال الكامل المراد تحويله إلى كلام.
postData مطلوب كائن (object) بيانات الطلب الوصفية. انظر الحقول أدناه.

كائن postData

الحقل إجراء مطلوب النوع افتراضي الوصف
name مطلوب نص (string) عنوان المقال. يُستخدم عنواناً لطلب الصوت المُولَّد.
articleId مطلوب نص (string) معرّفك الفريد للمقال. يعمل كمفتاح للـ idempotency (انظر قسم Idempotency أدناه) ويُعاد إرساله في الاستدعاء.
voiceId مطلوب نص (string) الصوت المستخدم في السرد. استخدم معرّفاً من قائمة الأصوات.
callbackURL مطلوب نص (رابط URL) رابط HTTPS سترسل إليه مكنة روابط الصوت والتفريغ النصي النهائية. تُحفظ آخر قيمة للشركة.
preprocessType اختياري نص (string) "0" وضع تحضير النص، يُرسَل كنص (string). استخدم ”0” لعدم المعالجة (سرد النص حرفيًّا) أو ”2” للمعالجة المسبقة بالذكاء الاصطناعي (سرد أنقى؛ يُضاعِف تكلفة الأحرف). يجب أن يكون نصًّا في JSON — أمّا الرقم المجرّد مثل 0 أو 2 فيُرفَض أثناء معالجة النص.
regenerate اختياري قيمة منطقية (boolean) false عند ضبطها على true، تفرض توليداً جديداً حتى لو سبق توليد هذا الـ articleId.

مثال على الطلب

curl -X POST "https://api.moknah.io/process-text" \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "الذكاء الاصطناعي يتطور بسرعة كبيرة في كل المجالات.",
    "postData": {
        "name": "AI is evolving fast",
        "articleId": "post-123",
        "voiceId": "12",
        "callbackURL": "https://your-site.com/wp-json/ats/v1/callback",
        "preprocessType": "0",
        "regenerate": false
    }
  }'
import requests

response = requests.post(
    "https://api.moknah.io/process-text",
    headers={
        "Authorization": "Bearer your_api_key",
        "Content-Type": "application/json"
    },
    json={
        "text": "الذكاء الاصطناعي يتطور بسرعة كبيرة في كل المجالات.",
        "postData": {
            "name": "AI is evolving fast",
            "articleId": "post-123",
            "voiceId": "12",
            "callbackURL": "https://your-site.com/wp-json/ats/v1/callback",
            "preprocessType": "0",
            "regenerate": False
        }
    }
)

# 202 Accepted — the audio is delivered to your callbackURL
print(response.status_code, response.text)
const response = await fetch(
    'https://api.moknah.io/process-text',
    {
        method: 'POST',
        headers: {
            'Authorization': 'Bearer your_api_key',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            text: 'الذكاء الاصطناعي يتطور بسرعة كبيرة في كل المجالات.',
            postData: {
                name: 'AI is evolving fast',
                articleId: 'post-123',
                voiceId: '12',
                callbackURL: 'https://your-site.com/wp-json/ats/v1/callback',
                preprocessType: '0',
                regenerate: false
            }
        })
    }
);

// 202 Accepted — result arrives at your callbackURL

الاستجابة الفورية

إذا قُبل الطلب، تستجيب نقطة النهاية فوراً:

Processing started. Results will be sent to the callback URL.

حمولة الاستدعاء (Callback)

عند انتهاء التوليد، ترسل مكنة طلب POST إلى callbackURL الخاص بك بجسم JSON التالي:

{
    "articleId": "post-123",
    "response": {
        "audioFile": "https://api-storage.moknah.io/.../******.mp3",
        "srtFile": "https://api-storage.moknah.io/.../******.srt",
        "signature": "<hmac-sha256-hex>"
    }
}
الحقل الوصف
articleId نفس الـ articleId الذي أرسلته في الطلب.
response.audioFile الرابط العام لملف السرد الصوتي MP3 المُولَّد، أو null إذا فشل التوليد.
response.srtFile الرابط العام لملف التفريغ النصي المتزامن (.srt)، أو null إذا فشل التوليد.
response.signature توقيع HMAC-SHA256 يمكنك استخدامه للتحقق من أصالة الحمولة (انظر أدناه).
التعامل مع حالات فشل التوليد

يُرسَل الاستدعاء (callback) أيضًا عندما لا يُنتِج التوليد أيّ صوت. في تلك الحالة تكون response.audioFile وresponse.srtFile بقيمة null (ويظلّ التوقيع محسوبًا على articleId|null|null). عامِل أيّ استدعاء تكون فيه audioFile أو srtFile بقيمة null على أنّه فشل: لا تَعُدّ المقال مكتمِلًا، وأعِد إرساله مع ضبط regenerate على true.

التحقق من التوقيع

التوقيع هو HMAC-SHA256 (بصيغة hex) للنص articleId|audioFile|srtFile، باستخدام مفتاح هو ملخّص SHA-256 (hex) لمفتاح API الخاص بك. أعد حسابه لديك وقارنه للتأكد من أن الاستدعاء صادر من مكنة ولم يُعبَث به.

import crypto from 'crypto';

const keyHash = crypto.createHash('sha256').update(API_KEY).digest('hex');
const payload = `${articleId}|${audioFile}|${srtFile}`;
const expected = crypto.createHmac('sha256', keyHash).update(payload).digest('hex');

const isValid = expected === signature;
import hashlib, hmac

key_hash = hashlib.sha256(API_KEY.encode()).hexdigest()
payload = f"{article_id}|{audio_file}|{srt_file}"
expected = hmac.new(key_hash.encode(), payload.encode(), hashlib.sha256).hexdigest()

is_valid = hmac.compare_digest(expected, signature)

Idempotency وإعادة التوليد

  • تُفهرَس الطلبات حسب articleId لكل شركة. وأي articleId جديد يبدأ توليداً جديداً.
  • إذا كان المقال قيد التوليد حالياً، تُرفض الطلبات المكررة بالرمز 409 ALREADY_PROCESSING.
  • إذا سبق توليد المقال وكانت regenerate تساوي false، يُعاد تسليم الصوت الموجود إلى callbackURL دون إعادة التوليد (ودون إعادة الخصم).
  • اضبط regenerate على true لفرض توليد جديد تماماً لـ articleId موجود.
  • إذا فشلت محاولة سابقة، فقد تكون النتيجة المخزَّنة لذلك الـ articleId فارغة. وعندئذٍ قد يُعيد طلبٌ لاحق بقيمة regenerate تساوي false تسليمَ تلك النتيجة الفارغة، لذا أعِد الإرسال مع regenerate تساوي true (أو استخدم articleId جديدًا) للتعافي.

التزامن والإنتاجية

يُسرَد كلُّ مقال بتوليد جُمَله بالتوازي عبر مزوّد تحويل النص إلى كلام، وهو يفرض حدًّا للتزامن مشتركًا عبر حسابك بالكامل. وقد يؤدّي إرسال عدد كبير من المقالات في وقت واحد إلى تجاوز هذا الحدّ وفشل جُمَل مفردة — ومن ثَمّ مقالات كاملة.

  • عند سرد صفحة متعدّدة الأجزاء، أبقِ عددًا قليلًا من المقالات قيد المعالجة في آنٍ واحد (نحو ثلاثة) بدلًا من إرسالها كلّها دفعةً واحدة.
  • أعِد محاولة أيّ مقال فاشل مع ضبط regenerate على true؛ أمّا المقالات المُولَّدة مسبقًا فهي مُخزَّنة ولا حاجة لإعادة إرسالها.
  • كما أنّ نقطة النهاية /process-text محدودة المعدّل لكلّ عميل؛ والدفعات التي تتجاوز الحدّ تتلقّى 429 Too Many Requests، لذا باعِد بين طلباتك أو أرسِلها على دفعات.

الفوترة

تُحتسب تكلفة الأحرف بعدد الأحرف في text مضروباً في معامل المعالجة المسبقة (1 افتراضياً، و2 عندما تكون preprocessType تساوي 2). تُخصم الأرصدة فقط عند تنفيذ التوليد فعلياً. وإعادة تسليم مقال مُولَّد مسبقاً مجانية، وإذا فشل التوليد أو التسليم تُعاد الأرصدة المخصومة تلقائياً.

أخطاء

الحالة الكود الوصف
401 AUTH_FAILED ترويسة Authorization مفقودة أو مفتاح API غير صالح.
422 VALIDATION_ERROR النص مفقود، أو حقول postData غير صالحة/مفقودة.
400 INVALID_VOICE_ID معرّف الصوت voiceId المُقدَّم غير موجود.
409 ALREADY_PROCESSING هذا المقال قيد التوليد بالفعل. أعد المحاولة بعد اكتماله.
422 PROCESSING_ERROR فشل التوليد. تُعاد أي أرصدة مخصومة.
422 REFUND_FAILED فشلت المعالجة ولم يكتمل الاسترداد التلقائي. تواصل مع api@moknah.io.
دعم واجهة برمجة التطبيقات (API)

للأسئلة أو المشكلات المتعلقة بواجهة برمجة التطبيقات، اتصل بنا على api@moknah.io.