API الرسائل
API الإرسال إلى عدة أرقام
أرسل رسالة WhatsApp نفسها إلى عدة أرقام هواتف ومجموعات في طلب واحد. استخدمه لعمليات البث الصغيرة مثل النشرات الإخبارية والعروض والإعلانات.
https://wbiztool.com/api/v1/send_msg/multi/النص (Body): JSON أو حقول نموذج
ينشئ Wbiztool رسالة لكل مستلم ويُرجع msg_id لكل منها، حتى تتمكن من التحقق من حالتها كلٌّ على حدة.
مثال سريع#
curl -X POST https://wbiztool.com/api/v1/send_msg/multi/ \
-H "Content-Type: application/json" \
-d '{
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"whatsapp_client": 678,
"msg_type": 0,
"country_code": "91",
"phone": "9876543210,9812345670,Sales Team Mumbai",
"msg": "Our Diwali sale starts tomorrow. Get 20% off on all orders!"
}'import requests
response = requests.post(
"https://wbiztool.com/api/v1/send_msg/multi/",
json={
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"whatsapp_client": 678,
"msg_type": 0,
"country_code": "91",
"phone": ",".join(["9876543210", "9812345670", "Sales Team Mumbai"]),
"msg": "Our Diwali sale starts tomorrow. Get 20% off on all orders!",
},
timeout=60,
)
result = response.json() # read the body even when the HTTP code is 400
if result.get("status") == 1:
for item in result["messages"]:
print(item["contact"], "->", item["msg_id"])
else:
print("Failed:", result.get("message", "no message in response"))// Node.js 18+ (built-in fetch). Save as .mjs to use top-level await.
const response = await fetch("https://wbiztool.com/api/v1/send_msg/multi/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: 12345,
api_key: "YOUR_API_KEY",
whatsapp_client: 678,
msg_type: 0,
country_code: "91",
phone: ["9876543210", "9812345670", "Sales Team Mumbai"].join(","),
msg: "Our Diwali sale starts tomorrow. Get 20% off on all orders!",
}),
});
const result = await response.json(); // read the body even when the HTTP code is 400
if (result.status === 1) {
for (const item of result.messages) {
console.log(item.contact, "->", item.msg_id);
}
} else {
console.error("Failed:", result.message ?? "no message in response");
}<?php
$payload = [
'client_id' => 12345,
'api_key' => 'YOUR_API_KEY',
'whatsapp_client' => 678,
'msg_type' => 0,
'country_code' => '91',
'phone' => implode(',', ['9876543210', '9812345670', 'Sales Team Mumbai']),
'msg' => 'Our Diwali sale starts tomorrow. Get 20% off on all orders!',
];
$ch = curl_init('https://wbiztool.com/api/v1/send_msg/multi/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($result['status'] ?? 0) === 1) {
foreach ($result['messages'] as $item) {
echo $item['contact'] . ' -> ' . $item['msg_id'] . PHP_EOL;
}
} else {
echo 'Failed: ' . ($result['message'] ?? 'no message in response');
}استبدل 12345 وYOUR_API_KEY و678 بقيمك الخاصة. راجع المصادقة لمعرفة مكان العثور عليها.
معاملات الطلب#
المصادقة
client_idintegerمطلوبمعرّف العميل في API (API Client ID) من Settings → API keys (الإعدادات ← مفاتيح API).
api_keystringمطلوبمفتاح API الخاص بك من الصفحة نفسها.
whatsapp_clientintegerمطلوبمعرّف رقم WhatsApp الذي ستُرسَل منه الرسائل، من إعدادات WhatsApp. على عكس إرسال رسالة، لا تختار نقطة النهاية هذه رقمًا نيابةً عنك أبدًا.
المستلمون والرسالة
phonestringمطلوبأرقام الهواتف وأسماء المجموعات في نص واحد مفصول بفواصل، مثل
9876543210,9812345670,Sales Team Mumbai. لا ترسل مصفوفة JSON. راجع طريقة قراءة المستلمين.country_codestringاختياريرمز الاتصال الدولي للدولة بدون
+، مثل91. يُضاف قبل كل رقم هاتف إلا إذا كان الرقم يبدأ به بالفعل. في JSON، أرسله كنص ("91")، لا كرقم. إذا أرسلته كرقم، فسيُعامَل كل رقم هاتف في القائمة على أنه اسم مجموعة (is_group: true)، وستفشل تلك الرسائل.msg_typeintegerاختياري
0نص (افتراضي)، و1صورة، و2ملف أو مستند.msgstringمطلوب عندما تكون قيمة msg_type هي 0نص الرسالة. للصور والملفات يكون هو التعليق (caption) ويمكن أن يكون فارغًا. يعمل تنسيق WhatsApp:
*bold*و_italic_و~strikethrough~. ويُقبلmessageكاسم بديل.
الصور والملفات
img_urlstringمطلوب عندما تكون قيمة msg_type هي 1عنوان URL عام للصورة يبدأ بـ
httpأوhttps.file_urlstringمطلوب عندما تكون قيمة msg_type هي 2عنوان URL عام يبدأ بـ
httpأوhttpsويمكن تنزيل الملف منه مباشرةً.file_namestringاختيارياسم الملف الذي يراه المستلمون، مثل
price-list.pdf. يُرسَل بأحرف صغيرة، وتُستبدل أحرف مثل& : ? * $ ;بـ_، ويُقتطع عند 150 حرفًا. إذا حذفته، يُؤخذ الاسم من عنوان URL.
خيارات الإرسال
webhookstringاختياريعنوان URL يستقبل طلب
POSTلكل رسالة عند إرسالها أو فشلها. البيانات المرسلة هي نفسها كما في إرسال رسالة.
curl -X POST https://wbiztool.com/api/v1/send_msg/multi/ \
-H "Content-Type: application/json" \
-d '{
"client_id": 12345,
"api_key": "YOUR_API_KEY",
"whatsapp_client": 678,
"msg_type": 1,
"country_code": "91",
"phone": "9876543210,9812345670",
"img_url": "https://example.com/offers/diwali-sale.jpg",
"msg": "Our Diwali sale starts tomorrow."
}'طريقة قراءة المستلمين#
يقسّم Wbiztool قيمة phone عند الفواصل، ويحذف المسافات حول كل عنصر، ثم يحدّد نوع كل عنصر:
- أرقام فقط (لا بأس بوجود
+أو أصفار في البداية): يُعامَل كرقم هاتف. يُضافcountry_codeإلا إذا كان الرقم يبدأ به بالفعل، ثم يجب أن يتكون الرقم من 6 إلى 15 رقمًا. - أي شيء آخر: يُعامَل كاسم مجموعة WhatsApp، ويُعثر عليه بالطريقة نفسها المتبعة في الإرسال إلى مجموعة.
- المجموعة التي يتكون اسمها من أرقام فقط (مثل
2024) تُعامَل كرقم هاتف، ولا يمكن الإرسال من نقطة النهاية هذه إلى مجموعات تحتوي أسماؤها على فواصل. استخدم الإرسال إلى مجموعة لهذه الحالات.
أمور أخرى يجب معرفتها:
- الأرقام القصيرة جدًا أو الطويلة جدًا بعد إضافة رمز الدولة تُتخطّى بصمت. لا تظهر في الاستجابة ولا تحصل على
msg_id. - لا تُحذف الأرقام المكررة. الرقم المذكور مرتين يتلقى رسالتين.
- إذا صادف أن رقمًا محليًا يبدأ بالأرقام نفسها الموجودة في
country_code(مثل9123456780معcountry_codeبقيمة91)، فلن يُضاف الرمز. أرسل هذه الأرقام متضمنةً رمز الدولة مسبقًا (919123456780). - لا يُتحقق من عناوين URL للصور والملفات عند استدعاء API. فهي تُنزَّل عند إرسال كل رسالة، لذا فإن الرابط المعطّل يجعل الرسائل تفشل لاحقًا بدلًا من أن يفشل الطلب. وتنطبق قواعد وقت الإرسال نفسها المتبعة في إرسال رسالة: تفشل الصور التي يزيد حجمها على 16 MB والفيديوهات التي يزيد حجمها على 64 MB، وملفات الصوت بصيغتي WAV وOGG غير مدعومة، ويُضاف
.pdfإلى الملفات (msg_type2) التي ليس لها امتداد مدعوم. راجع إرسال الصور والملفات.
الرصيد#
يُتحقق من الدفعة كاملةً مقابل رصيدك المتبقي قبل إنشاء أي شيء. يُحتسب كل عنصر غير فارغ في phone، بما في ذلك العناصر التي تُتخطّى لاحقًا. إذا كان العدد أكبر من رصيدك المتبقي، فلن تُنشأ أي رسائل وستحصل على:
{
"message": "Not enough credits: 120 messages requested, 85 credits remaining",
"status": 0
}
الرسائل الموجودة في قائمة الانتظار ولم تُرسَل بعد تُحتسب أيضًا من رصيدك المتبقي. قسّم القوائم الكبيرة إلى طلبات أصغر أو اشحن رصيد باقتك. وللحملات الكبيرة، ارفع جدول بيانات من صفحة الحملات بدلًا من ذلك.
الاستجابة#
يُرجع الطلب الناجح HTTP 200:
{
"msg_ids": [9817263, 9817264, 9817265],
"messages": [
{ "msg_id": 9817263, "contact": "919876543210", "is_group": false },
{ "msg_id": 9817264, "contact": "919812345670", "is_group": false },
{ "msg_id": 9817265, "contact": "Sales Team Mumbai", "is_group": true }
],
"message": "Successfully created 3 messages",
"status": 1
}
| الحقل | النوع | الوصف |
|---|---|---|
status | integer | 1 إذا دخلت رسالة واحدة على الأقل قائمة الانتظار، و0 في غير ذلك. |
message | string | Successfully created N messages عند النجاح، وإلا نص الخطأ. |
msg_ids | array of integers | معرّفات الرسائل في قائمة الانتظار، بترتيب phone. يظهر عند النجاح فقط. |
messages | array | كائن واحد لكل رسالة في قائمة الانتظار. يظهر عند النجاح فقط. |
messages[].msg_id | integer | معرّف الرسالة. |
messages[].contact | string | رقم الهاتف بعد تطبيق رمز الدولة، أو اسم المجموعة. |
messages[].is_group | boolean | true إذا عومل العنصر كاسم مجموعة. |
قارن messages بالقائمة التي أرسلتها لمعرفة الأرقام التي تُخطّيت، وتأكد من أن is_group تساوي false لكل عنصر قصدت به رقم هاتف.
الأخطاء#
تُرجع معظم الأخطاء HTTP 200 مع status بقيمة 0، لذا تحقّق دائمًا من status في الجسم. وباستثناء أخطاء HTTP 400 و403، تكون الاستجابات (بما فيها الناجحة) بصيغة JSON لكنها تُرسَل مع Content-Type: text/html، لذا حلّل الجسم بنفسك بدلًا من الاعتماد على الاكتشاف التلقائي لـ JSON (مثلًا في الأدوات بدون برمجة):
{ "message": "Invalid whatsapp client", "status": 0 }
| الرسالة | طريقة الإصلاح |
|---|---|
Auth Error | أرسل client_id وapi_key كليهما. |
Invalid Client Id | أرسل client_id كرقم. يُرجَع مع HTTP 403. |
Auth Error: invalid api key | تأكد من أن المفتاح موجود، ولم يُحذف، وينتمي إلى client_id هذا. يُرجَع مع HTTP 400. |
Msg cant be null | الرسائل النصية (msg_type 0) تحتاج إلى msg. |
Image Url Can't be null | مع msg_type 1، أرسل img_url. |
File Url Can't be null | مع msg_type 2، أرسل file_url. |
Not enough credits: … messages requested, … credits remaining | أرسل إلى عدد أقل من المستلمين أو أضف رصيدًا. راجع الرصيد. |
Invalid whatsapp client | معرّف whatsapp_client هذا غير موجود في مساحة العمل الخاصة بك. |
No valid contacts found | كل عنصر في phone كان فارغًا أو تُخطّي. تأكد من أن الأرقام تتكون من 6 إلى 15 رقمًا مع رمز الدولة. |
Demo Account can not access apis | استخدم حسابًا عاديًا. |
Invalid JSON format: … | جسم JSON غير صالح، أو أنك أرسلت حقول نموذج بدون client_id. |
نصائح#
- أرسل
phoneكنص: اجمع قائمتك بالفواصل. مصفوفة JSON تُرجع{}. - لا تستخدم
send_bulk_messagesمن مكتبة Python حاليًا: فهي ترسل القائمة باسمphones، الذي تتجاهله نقطة النهاية هذه. استدعِ نقطة النهاية مباشرةً كما في الأمثلة أعلاه. - تتبّع كل رسالة: احفظ كل
msg_idمنmessages، أو مرّرwebhookليصلك إشعار عند إرسال كل رسالة أو فشلها. - أبقِ رقمك متصلًا: تُرسَل كل رسالة من رقم WhatsApp الخاص بك، لذا يجب أن يبقى متصلًا في إعدادات WhatsApp حتى تُرسَل الدفعة كاملة.
- نص مختلف لكل شخص: ترسل نقطة النهاية هذه
msgنفسها إلى الجميع. استدعِ إرسال رسالة مرة لكل مستلم لتخصيص كل رسالة.
