تحويل المقالات إلى صوت (ATS)
حوّل مقالاً كاملاً إلى صوت مسرود وتفريغ نصي، ويُسلَّم بشكل غير متزامن إلى رابط الاستدعاء (callback URL) الخاص بك.
تستقبل نقطة نهاية 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@moknah.io.