إرسال رسالة واتساب عبر API: أمثلة cURL وNode وPython وPHP
كيف ترسل رسالة واتساب عبر API: أمثلة عملية بلغات cURL وNode.js وPython وPHP لقوالب الرسائل ورسائل الجلسة، مع تتبع الحالات ومعالجة الأخطاء بوضوح.
بقلم OmniChannels.ai Editorial Team · مراجعة BroadNet Messaging Solutions Team
التكامل
الإجابة المختصرة
مع واجهة OmniChannels.ai ترسل كل رسائل واتساب عبر نقطة نهاية واحدة، POST https://api.broadnet.me/whatsapp/message/sendbulk، بصيغة multipart form data مع ترويسة Authorization: Bearer. يحدد الحقل messageType الحمولة: TEMPLATE للقوالب المعتمدة التي تحتاجها لبدء محادثة أو للكتابة خارج نافذة 24 ساعة، وTEXT أو IMAGE أو INTERACTIVE للردود داخلها.
في هذه الصفحة
- كيف أرسل رسالة واتساب عبر الـ API؟
- قالب أم رسالة جلسة: أيهما أرسل؟
- كيف أرسل قالبًا معتمدًا؟
- ما حقول الطلب الأهم؟
- كيف أرسل قالبًا بزر أو رمز OTP؟
- كيف أرد داخل نافذة خدمة العملاء؟
- كيف أتتبع التسليم؟
- ما الأخطاء التي ينبغي معالجتها؟
- مثال تطبيقي: خدمة إشعارات الطلبات
- ما الأخطاء الشائعة؟
- كيف تساعدك OmniChannels.ai؟
أهم النقاط
- تمر كل رسائل واتساب عبر POST /whatsapp/message/sendbulk؛ ويحدد messageType (TEMPLATE وTEXT وIMAGE وINTERACTIVE وغيرها) الحقول المطلوبة.
- الطلب بصيغة multipart/form-data لا JSON، لذا تحتاج Python إلى files= وتحتاج PHP إلى جسم مصفوفة لتجنب الترميز بالعناوين (url-encoding).
- خارج نافذة خدمة العملاء البالغة 24 ساعة لا يمكن إرسال سوى قالب معتمد؛ وداخلها يمكنك إرسال نص حر ووسائط ورسائل تفاعلية.
- يضع الاستدعاء الرسائل في الطابور ويعيد batchId فورًا؛ وتصل حالات كل مستلم إلى webhook ومن نقطة نهاية bulk-insights.
- لا يقبل الـ API مفتاح idempotency، لذا سجّل كل إرسال قبل تنفيذه وافحص الحالة بعد انتهاء المهلة بدل إعادة الإرسال.
هذا الدليل موجّه للمطورين الذين يدمجون إرسال واتساب في تطبيق. يعرض طلبات عاملة بلغات cURL وNode.js وPython وPHP، ويشرح الفرق بين رسائل القوالب ورسائل الجلسة، ويغطي التتبع والأخطاء. وكل نقطة نهاية وحقل مأخوذ من مرجع واتساب API ومواصفة OpenAPI لدينا.
كيف أرسل رسالة واتساب عبر الـ API؟
ترسل طلب POST موثّقًا واحدًا إلى https://api.broadnet.me/whatsapp/message/sendbulk مع حقول النموذج. يختار الحقل messageType نوع الرسالة، وتؤكد الاستجابة أن الرسائل وُضعت في الطابور.
| العنصر | القيمة |
|---|---|
| عنوان الأساس | https://api.broadnet.me (دون بادئة /v1) |
| نقطة النهاية | POST /whatsapp/message/sendbulk |
| المصادقة | Authorization: Bearer $BROADNET_TOKEN |
| نوع المحتوى | multipart/form-data (يضبطه عميل HTTP لديك تلقائيًا) |
| الاستجابة | ملخص دفعة بصيغة JSON مع batchId |
تُصدَر بيانات اعتماد الاختبار بعد طلب وصول قصير، وتذهب رسائل الاختبار إلى أرقامك الموثّقة. راجع البدء السريع وصفحات المصادقة. وأبقِ الرمز على خادمك فقط.
قالب أم رسالة جلسة: أيهما أرسل؟
أرسل قالبًا لبدء محادثة أو للكتابة خارج النافذة، ورسالة جلسة حين يكون العميل قد راسلك خلال آخر 24 ساعة. هذه قاعدة Meta وليست قاعدتنا.
| رسالة قالب | رسالة جلسة | |
|---|---|---|
messageType |
TEMPLATE |
TEXT وIMAGE وVIDEO وAUDIO وDOCUMENT وINTERACTIVE وغيرها |
| متى تُسمح | في أي وقت بعد اعتماد القالب | فقط أثناء فتح نافذة خدمة العملاء |
| تحتاج اعتمادًا | نعم، من Meta | لا |
| الاستخدام المعتاد | تحديثات الطلبات وOTP والتذكيرات والحملات | ردود الدعم وإجابات الأسئلة |
تحتسب Meta رسومًا لكل رسالة مُسلَّمة بحسب الفئة، وقد تغيرت قواعدها لرسائل الخدمة وقوالب تحديثات المعاملات في 1 أكتوبر 2026. يغطي دليل النافذة الآليات، وتغطي صفحة الأسعار والحاسبة التكلفة.
كيف أرسل قالبًا معتمدًا؟
اضبط messageType=TEMPLATE، وسمِّ القالب ورمز لغته، ومرّر قيم المتغيرات. أنشئ batchId=0 لبدء دفعة جديدة.
curl -X POST https://api.broadnet.me/whatsapp/message/sendbulk \
-H "Authorization: Bearer $BROADNET_TOKEN" \
-F batchId=0 \
-F campaignName=order-updates \
-F destinationNo=971500000000 \
-F messageType=TEMPLATE \
-F templateName=order_update \
-F templateLanguage=en_US \
-F bodyTemplateVariables=INV-400
// Node.js 18+ (fetch وFormData مدمجان)
const form = new FormData();
form.append("batchId", "0");
form.append("campaignName", "order-updates");
form.append("destinationNo", "971500000000");
form.append("messageType", "TEMPLATE");
form.append("templateName", "order_update");
form.append("templateLanguage", "en_US");
form.append("bodyTemplateVariables", "INV-400");
const res = await fetch("https://api.broadnet.me/whatsapp/message/sendbulk", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.BROADNET_TOKEN}` }, // يضبط fetch حد multipart
body: form,
});
console.log(await res.json());
import os
import requests
fields = {
"batchId": "0",
"campaignName": "order-updates",
"destinationNo": "971500000000",
"messageType": "TEMPLATE",
"templateName": "order_update",
"templateLanguage": "en_US",
"bodyTemplateVariables": "INV-400",
}
# أرسل كل حقل بوصفه جزء multipart (files=) لا مرمَّزًا بالعناوين (data=).
r = requests.post(
"https://api.broadnet.me/whatsapp/message/sendbulk",
headers={"Authorization": f"Bearer {os.environ['BROADNET_TOKEN']}"},
files={k: (None, v) for k, v in fields.items()},
timeout=30,
)
print(r.json())
<?php
$ch = curl_init("https://api.broadnet.me/whatsapp/message/sendbulk");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BROADNET_TOKEN")],
// المصفوفة (لا النص) تجعل cURL يرسل multipart/form-data.
CURLOPT_POSTFIELDS => [
"batchId" => "0",
"campaignName" => "order-updates",
"destinationNo" => "971500000000",
"messageType" => "TEMPLATE",
"templateName" => "order_update",
"templateLanguage" => "en_US",
"bodyTemplateVariables" => "INV-400",
],
]);
echo curl_exec($ch);
curl_close($ch);
الوجهة هي رمز الدولة مع الرقم، أرقامًا فقط. يعود الاستدعاء فورًا بملخص دفعة:
{
"totalFiles": 1,
"totalSuccess": 1,
"totalFailed": 0,
"totalDuplicates": 0,
"batchId": "2609091405000000001",
"fileResults": [
{
"fileName": "direct",
"totalRecords": 1,
"successCount": 1,
"failedRecipients": [],
"duplicateRecipients": []
}
],
"message": "Messages queued for delivery"
}
خزّن batchId بجانب سجلك الخاص. «في الطابور» لا تعني «مُسلَّمة».
ما حقول الطلب الأهم؟
تعتمد الحقول المطلوبة على messageType. هذه هي الشائعة.
| الحقل | مطلوب | الوصف |
|---|---|---|
messageType |
نعم | TEXT أو IMAGE أو VIDEO أو AUDIO أو DOCUMENT أو STICKER أو LOCATION أو CONTACTS أو TEMPLATE أو INTERACTIVE أو REACTION أو FLOW |
destinationNo أو destinationFiles |
أحدهما | أرقام مفصولة بفواصل أو فواصل منقوطة أو أسطر جديدة؛ أو ملف TXT أو CSV أو XLSX |
batchId |
لا | 0 يبدأ دفعة جديدة |
campaignName |
لا | تسميتك للتقارير |
allowDuplicate |
لا | false يزيل المستلمين المكررين |
templateName وtemplateLanguage |
لـ TEMPLATE |
اسم القالب المعتمد ورمز اللغة، مثل en_US أو ar |
bodyTemplateVariables |
بحسب القالب | قيمة متغير النص الأساسي؛ وتُمرَّر المعاملات المسماة بصيغة JSON |
buttonsTemplateVariable |
بحسب القالب | قيمة الزر الديناميكي: لاحقة الرابط أو رمز القسيمة أو رمز OTP |
content |
لـ TEXT |
نص الرسالة حتى 4,096 حرفًا، أو تعليق للوسائط |
mediaUrl |
بحسب النوع | رابط HTTPS عام للوسائط |
interactivePayload |
لـ INTERACTIVE |
كائن Meta التفاعلي نص JSON |
تستخدم الجدولة scheduled وscheduleTime وgmt، ويخنق delay التسليم. القائمة الكاملة في مرجع واتساب API.
كيف أرسل قالبًا بزر أو رمز OTP؟
أضف قيمة الزر في buttonsTemplateVariable. وفي قالب مصادقة بزر نسخ الرمز، مرّر الرمز في حقلي النص والزر معًا.
curl -X POST https://api.broadnet.me/whatsapp/message/sendbulk \
-H "Authorization: Bearer $BROADNET_TOKEN" \
-F batchId=0 \
-F destinationNo=971500000000 \
-F messageType=TEMPLATE \
-F templateName=login_code \
-F templateLanguage=en_US \
-F bodyTemplateVariables=482913 \
-F buttonsTemplateVariable=482913
هنا login_code عنصر نائب لقالب المصادقة المعتمد الخاص بك. ولأزرار متعددة يقبل buttonsTemplateVariable مصفوفة JSON. ولّد الرمز على خادمك، وخزّنه مجزّأً مع انتهاء صلاحية، ولا تسجله أبدًا. ويغطي دليل OTP التسليم بالنقرة الواحدة وبلا نقرات ونسخ الرمز.
كيف أرد داخل نافذة خدمة العملاء؟
استخدم نوع رسالة جلسة. يحتاج الرد النصي العادي إلى messageType=TEXT وcontent.
curl -X POST https://api.broadnet.me/whatsapp/message/sendbulk \
-H "Authorization: Bearer $BROADNET_TOKEN" \
-F batchId=0 \
-F destinationNo=971500000000 \
-F messageType=TEXT \
-F campaignName=support \
-F "content=Your order has shipped. Reply here if you need anything."
لأزرار الرد، أرسل messageType=INTERACTIVE وinteractivePayload يتبع صيغة الرسالة التفاعلية لدى Meta.
curl -X POST https://api.broadnet.me/whatsapp/message/sendbulk \
-H "Authorization: Bearer $BROADNET_TOKEN" \
-F batchId=0 \
-F destinationNo=971500000000 \
-F messageType=INTERACTIVE \
-F campaignName=support \
-F 'interactivePayload={"type":"button","body":{"text":"Confirm your delivery slot?"},"action":{"buttons":[{"type":"reply","reply":{"id":"slot_ok","title":"Confirm"}},{"type":"reply","reply":{"id":"slot_change","title":"Change"}}]}}'
لتعليم رسالة واردة مقروءة، وإظهار مؤشر الكتابة اختياريًا، استدعِ POST /whatsapp/message/read بصيغة JSON:
curl -X POST https://api.broadnet.me/whatsapp/message/read \
-H "Authorization: Bearer $BROADNET_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "messageId": "wamid.HBgMOTcxNTAwMDAwMDAwFQIAEhgg", "typing": true }'
راجع دليلنا عن الرسائل التفاعلية لإرشادات التصميم.
كيف أتتبع التسليم؟
تُدفع الحالات إلى webhook المضبوط على حسابك ويمكن قراءتها أيضًا لكل دفعة. ينتقل كل مستلم عبر SUBMITTED وSENT وDELIVERED وREAD، أو ينتهي بـ FAILED أو REJECTED مع السبب.
curl "https://api.broadnet.me/whatsapp/message/bulk-insights?batch_Id=2609091405000000001&status=FAILED&page=0&size=50" \
-H "Authorization: Bearer $BROADNET_TOKEN"
batch_Id مطلوب؛ وstatus وdestination وsearch وpage وsize اختيارية، وpage يبدأ من الصفر. استخدم الاستعلام الدوري شبكة أمان للأحداث الفائتة، وابنِ مستقبِلك كما في دليل webhooks. ويمكن أيضًا إيقاف الدفعات مؤقتًا واستئنافها وإلغاؤها بنقاط نهاية الدفعات في المرجع.
ما الأخطاء التي ينبغي معالجتها؟
اقرأ حالة HTTP أولًا، ثم جسم الخطأ. يطلق الـ API الأخطاء في جسم JSON من خمسة حقول، وقد تأتي إخفاقات واتساب الخاصة من Meta.
| الحالة | المعنى | الإجراء |
|---|---|---|
400 |
خطأ تحقق، كحقل ناقص خاص بالنوع أو وجهة غير صالحة | أصلح الطلب؛ ولا تعد المحاولة دون تغيير |
401 / 403 |
رمز مفقود أو غير صالح، أو عملية غير مسموحة | أصلح الرمز أو اطلب منا تفعيل العملية |
404 |
القالب أو المرسل غير موجود | تحقق من اسم القالب ولغته |
413 |
الملف المرفوع كبير جدًا | قلّل حجم الملف |
429 |
حد المعدل | انتظر Retry-After |
502 |
رفضت Meta الاستدعاء؛ ويحمل message رمز خطأ Meta ونصه |
اقرأه؛ ولا تعد المحاولة إلا إن كان عابرًا |
500 و503 و504 |
مشكلة في الخادم أو المنبع | أعد المحاولة بتراجع أسّي وتشويش |
يشرح دليل رموز الأخطاء لدينا رموز Meta الشائعة. ولأنه لا يوجد مفتاح idempotency، اتبع خطوات الحماية من التكرار في الأخطاء والحدود: اكتب سجلًا معلقًا أولًا، وخزّن batchId العائد، وبعد انتهاء المهلة افحص الحالة قبل الإرسال مجددًا.
مثال تطبيقي: خدمة إشعارات الطلبات
ترسل «سوق رفيق» (اسم افتراضي)، وهي متجر تجزئة في الإمارات، قالب order_update عند شحن الطلب.
- تكتب خدمة الطلبات صفًا بالمفتاح
order-8842-shippedوحالتهpending. - تستدعي
sendbulkمع القالب ورقم الطلب فيbodyTemplateVariables. - عند
200تخزّنbatchIdوتعلّم الصفaccepted. - يحدّث معالج webhook الصف إلى
DELIVEREDأوREAD، أوFAILEDمع السبب. - إذا ردّ العميل، تستخدم أداة الدعم رسالة جلسة
TEXTداخل النافذة. - تقرأ مهمة ليلية
bulk-insightsلدفعات الأمس وتطابق أي حالات مفقودة.
ما الأخطاء الشائعة؟
- إرسال JSON. نقطة نهاية إرسال واتساب بصيغة multipart؛ ولن ينجح
Content-Type: application/json. - استخدام
data=في Python بدلfiles=، فيُرمَّز النموذج بالعناوين. - نص حر خارج النافذة، وهذا يفشل. استخدم قالبًا.
- رمز لغة خاطئ، مثل
enبدلen_USالخاص بالقالب. - اعتبار
200تسليمًا. إنها تعني الوضع في الطابور. - إعادة محاولة عمياء بعد انتهاء المهلة، فقد تراسل العميل مرتين.
- الرمز في شيفرة العميل. استدعِ الـ API من خلفيتك فقط.
- الحدود: تختلف تفاصيل الحمولة بحسب القالب. أكّد تخطيط المتغيرات لأول حملة مخصصة مع فريقنا.
كيف تساعدك OmniChannels.ai؟
BroadNet مزوّد حلول أعمال رسمي لدى Meta، ويستخدم الإعداد في واتساب للأعمال API مسار Meta Embedded Signup؛ يجهّز فريقنا التسجيل معك، وتبقى الاعتمادات لدى Meta. واجهة REST موثّقة بمواصفة OpenAPI 3.1 وSDK بلغة TypeScript هو @broadnet/cpaas-sdk، وتُوحَّد حالات التسليم عبر القنوات. ابدأ من وثائق واتساب API أو البدء السريع.
الأسئلة الشائعة
هل أرسل رسائل واتساب بصيغة JSON أم form data؟
form data. تقبل نقطة نهاية إرسال واتساب، POST /whatsapp/message/sendbulk، الصيغة multipart/form-data، وكل حقل جزء في النموذج. أما الإرسال الفردي لـ SMS فيستخدم JSON، وهذا مصدر ارتباك شائع. في Python أرسل الحقول عبر files= لا data=، وفي PHP مرّر مصفوفة بوصفها الجسم ليبني cURL الصيغة multipart.
هل يمكنني إرسال رسالة واتساب دون قالب؟
فقط داخل نافذة خدمة العملاء. عندما يراسلك عميل تُفتح نافذة 24 ساعة ويمكنك الرد بنص أو وسائط أو رسائل تفاعلية. وخارجها، أو لبدء محادثة، يجب إرسال قالب معتمد. تطبّق الواجهة قواعد Meta، وسيفشل الإرسال الحر إلى نافذة مغلقة.
كيف أعرف هل سُلّمت الرسالة؟
يؤكد استدعاء الإرسال فقط أن الرسائل وُضعت في الطابور ويعيد batchId. وتنتقل حالات كل مستلم عبر SUBMITTED وSENT وDELIVERED وREAD، أو تنتهي بـ FAILED أو REJECTED. تُدفع إلى webhook الخاص بك، ويمكنك أيضًا قراءتها لكل دفعة من نقطة نهاية bulk-insights.
هل يمكنني الإرسال إلى مستلمين كثيرين في طلب واحد؟
نعم. يقبل destinationNo عدة أرقام مفصولة بفواصل أو فواصل منقوطة أو أسطر جديدة، ويقبل destinationFiles ملف TXT أو CSV أو XLSX. ولقالب بمتغيرات مختلفة لكل مستلم، ارفع ملفًا مخصصًا بصف لكل مستلم. اضبط allowDuplicate على false لإزالة الأرقام المكررة.
هل يوجد مفتاح idempotency لمنع الإرسال المزدوج؟
لا. لا يقبل الـ API مفتاح idempotency. وإذا انتهت مهلة طلب، لا يمكنك أن تعرف من جانب العميل هل قُبل. سجّل كل إرسال في قاعدة بياناتك قبل الاستدعاء، وخزّن batchId العائد، وافحص الحالة أو قائمة الدفعات قبل أي إعادة محاولة.
هل أحتاج إلى موافقة اشتراك قبل الإرسال؟
نعم. تشترط سياسة Meta أن يكون كل مستلم قد وافق على تلقي رسائل من نشاطك، ويجب اعتماد القوالب قبل استخدامها. لا تتحقق الواجهة من الموافقة نيابةً عنك. التقط الموافقة من المصدر، واحتفظ بالدليل، واكبت من يلغي اشتراكه.
المصادر
تابع القراءة
مزيد من الأدلةالتكامل
دليل webhooks واتساب: الأحداث والأمان وإعادة المحاولة
كيف تعمل webhooks واتساب: أحداث الرسائل والحالات، ومعالج موثوق، والتحقق من توقيع Meta، وإعادة المحاولة، وعدم التكرار، والاسترداد عند فقدان الأحداث.
10 دقائق للقراءة
التكامل
إرسال SMS عبر API: أمثلة بلغات Python وNode.js وPHP وcURL
إرسال SMS عبر API بلغات Python وNode.js وPHP وcURL: إرسال فردي وجماعي، ودعم Unicode والعربية، وحساب الأجزاء، وwebhooks حالة التسليم ومعالجة الأخطاء.
10 دقائق للقراءة
واتساب
رمز OTP عبر واتساب أم SMS: التكلفة والتسليم والبديل
مقارنة رمز OTP عبر واتساب وSMS: نموذج التكلفة والتسليم وتجربة المستخدم وقوالب المصادقة والرجوع من واتساب إلى SMS وضوابط مكافحة الاحتيال الفعّالة.
10 دقائق للقراءة
