انتقل إلى المحتوى

بوت واتساب بالذكاء الاصطناعي مع Claude أو GPT أو Gemini

اربط WhatsApp Cloud API الرسمية بنماذج Claude أو GPT أو Gemini عبر خادم Node.js صغير، مع كود مُختبَر وقواعد Meta وحدود الأمان وحساب التكلفة.

آخر تحديث: 1 نوفمبر 2026نسخة Markdown

لبناء بوت واتساب بالذكاء الاصطناعي، اربط WhatsApp Cloud API الرسمية من Meta بخادم صغير تملكه. يرسل واتساب كل رسالة من عملائك إلى الخادم، فيطلب الخادم ردًّا من النموذج ثم يرسله عبر Cloud API. وبمفتاح من 5abeer تصل مكتبة OpenAI إلى نماذج Claude وGPT وGemini بأقل من أسعارها الرسمية.

ما الذي تحتاجه لبناء بوت واتساب بالذكاء الاصطناعي؟#

  • تطبيق مطوّر على Meta فيه منتج WhatsApp، ويأتي معه رقم أعمال تجريبي.
  • مفتاح API من 5abeer لمزوّد النموذج الذي سيستخدمه البوت. يستخدم الكود النموذج الافتراضي claude-sonnet-5.5، فيحتاج إلى مفتاح Claude. الخطوات في أنشئ مفتاحًا وفي ما هو مفتاح API وكيف تحصل على واحد لـ Claude وGPT وGemini.
  • Node.js بالإصدار 22 أو أحدث، مع الحزمتين express وopenai.
  • خادم يبقى يعمل وله عنوان HTTPS عام. وتشترط Meta شهادة TLS أو SSL صالحة، ولا تقبل الشهادات الموقّعة ذاتيًا.

بأي طريقة تربط البوت بواتساب؟#

هذه الطرق الثلاث الشائعة، راجعناها في 2026-11-01:

الطريقةما هيهل تناسب بوت شركة؟
WhatsApp Cloud APIواجهة Meta نفسها لأرقام الأعمال، وهي المستخدمة هنانعم: رسمية، والكود ملكك
مزوّد حلول أعمال (Business Solution Provider)شركة تربطك بالمنصة وتقدّم أدواتها الخاصةنعم، إذا أردت صندوق رسائل مشتركًا أو مساعدة في الإعداد، مع مراجعة رسومها
مكتبة غير رسمية لواتساب ويبكود يسجّل الدخول بحساب عادي ويشغّله آليًالا: تخالف شروط واتساب

وتمنع شروط خدمة واتساب الرسائل الجماعية والرسائل الآلية والاتصال الآلي، وأي استخدام غير شخصي لخدماتها ما لم تأذن به، لذلك يعرّض البوت المبني على حساب عادي رقمك للخطر.

هل تسمح Meta ببوتات الذكاء الاصطناعي على واتساب؟#

نعم، ما دام البوت يخدم عملاء نشاطك أنت. فشروط Meta لمنصة WhatsApp Business، المحدّثة في 23 سبتمبر 2026، تمنع مزودي الذكاء الاصطناعي حين يكون الذكاء الاصطناعي هو الوظيفة الأساسية لما يقدّمونه، لا وظيفة عارضة أو مساندة. وصفحة مزودي الذكاء الاصطناعي لدى Meta لا تسمح لهم بتقديم مساعدات عامة إلا حيث يُلزم القانون Meta بالسماح بذلك.

وبوت المتجر الذي يجيب عن أسئلة الطلبات والمنتجات يستخدم الذكاء الاصطناعي جزءًا من خدمة العملاء، وهذه هي الحالة في هذا الدليل. وتقيّد الشروط أيضًا استخدام بيانات واتساب لديك في تدريب أنظمة الذكاء الاصطناعي.

و5abeer ليست إلا واجهة النموذج التي يستدعيها خادمك، فلا تتصل بواتساب ولا بحساب Meta الخاص بك. وهذه معلومات عامة لا استشارة قانونية، فاقرأ شروط Meta قبل الإطلاق.

كيف تربط الخادم بنماذج Claude أو GPT أو Gemini؟#

تعمل 5abeer بصيغة Chat Completions من OpenAI، لذلك يستخدم الخادم مكتبة OpenAI الرسمية مع عنوان أساس ومفتاح مختلفين. والإعداد نفسه يشغّل شات بوت الموقع وبوت تليجرام بالذكاء الاصطناعي.

متوافق مع OpenAIhttps://api.5abeer.ai/v1Authorization: Bearer <KEY>
متوافق مع Anthropichttps://api.5abeer.aix-api-key: <KEY>
Geminihttps://api.5abeer.ai/v1betax-goog-api-key: <KEY>

أرسل أولًا طلبًا تجريبيًا واحدًا لتتأكد من المفتاح والنموذج. والصيغة مشروحة في Chat Completions.

curl --request POST "https://api.5abeer.ai/v1/chat/completions" \
  --header "Authorization: Bearer $KHABEER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"model":"claude-sonnet-5.5","messages":[{"role":"user","content":"اكتب فكرة منتج في سطر واحد"}]}'
الرد
{
  "id": "chatcmpl-9f2",
  "object": "chat.completion",
  "model": "claude-sonnet-5.5",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "مرحبًا! كيف أساعدك اليوم؟"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 21,
    "completion_tokens": 12,
    "total_tokens": 33
  }
}

المفتاح يُقرأ من متغير البيئة ⁦KHABEER_API_KEY⁩، فلا يظهر في الكود.

كيف يبدو كود الخادم؟#

البوت ملف واحد: تتحقق Meta من عنوانك عبر GET /webhook، وتسلّم الرسائل عبر POST /webhook.

server.mjs
import crypto from "node:crypto";
import express from "express";
import OpenAI from "openai";

const env = process.env;
const missing = ["WHATSAPP_TOKEN", "WHATSAPP_APP_SECRET", "WHATSAPP_VERIFY_TOKEN", "WHATSAPP_PHONE_NUMBER_ID", "KHABEER_API_KEY"].filter((name) => !env[name]);
if (missing.length) {
  console.error("Set these environment variables first:", missing.join(", "));
  process.exit(1);
}

const client = new OpenAI({ apiKey: env.KHABEER_API_KEY, baseURL: "https://api.5abeer.ai/v1" });
const MODEL = env.CHAT_MODEL || "claude-sonnet-5.5";
const GRAPH = `https://graph.facebook.com/v26.0/${env.WHATSAPP_PHONE_NUMBER_ID}/messages`;

// One business answering its own customers. Replace the example store's facts with yours.
const SYSTEM = `You are the WhatsApp assistant of Example Store.
Answer only questions about the store, in the customer's language, briefly and in plain text.
Opening hours: 9:00 to 21:00, Saturday to Thursday. Shipping takes 2 to 4 days.
If you don't know the answer, say so and suggest the contact page on the store's website.`;

const MAX_TURNS = 10; // the last 5 questions and answers per customer
const MAX_CHARS = 4000; // per customer message
const LIMIT = 20; // messages per customer every 10 minutes
const MEDIA = new Set(["audio", "document", "image", "sticker", "video"]);
const history = new Map(); // in memory: lost when the server restarts
const hits = new Map();
const seen = new Set();
const queues = new Map();
setInterval(() => hits.clear(), 10 * 60 * 1000).unref();

// Meta signs every POST with your app secret: X-Hub-Signature-256 is "sha256=" + the HMAC of the raw body.
function signed(req) {
  if (!Buffer.isBuffer(req.body)) return false;
  const expected = Buffer.from("sha256=" + crypto.createHmac("sha256", env.WHATSAPP_APP_SECRET).update(req.body).digest("hex"));
  const received = Buffer.from(req.get("x-hub-signature-256") ?? "");
  return received.length === expected.length && crypto.timingSafeEqual(received, expected);
}

async function send(customer, text) {
  // A WhatsApp text message holds at most 4,096 characters, so long answers go in parts.
  for (const part of text.match(/[\s\S]{1,4000}/gu)) {
    const res = await fetch(GRAPH, {
      method: "POST",
      headers: { Authorization: `Bearer ${env.WHATSAPP_TOKEN}`, "Content-Type": "application/json" },
      body: JSON.stringify({ messaging_product: "whatsapp", recipient_type: "individual", ...customer, type: "text", text: { body: part } }),
      signal: AbortSignal.timeout(15000),
    });
    if (!res.ok) throw new Error(`WhatsApp API ${res.status}: ${await res.text()}`);
  }
}

async function answer(id, customer, message, overLimit) {
  if (overLimit) return send(customer, "You've sent many messages. Please wait a few minutes, then try again.");
  if (MEDIA.has(message.type)) return send(customer, "Sorry, I can only read text messages.");
  if (message.type !== "text") return; // reactions, locations, system notices...
  const past = history.get(id) ?? [];
  const question = String(message.text?.body ?? "").slice(0, MAX_CHARS);
  let reply;
  try {
    const completion = await client.chat.completions.create({
      model: MODEL,
      messages: [{ role: "system", content: SYSTEM }, ...past, { role: "user", content: question }],
      max_tokens: 800,
    });
    reply = (completion.choices[0]?.message?.content ?? "").trim();
    if (!reply) throw new Error("empty answer");
  } catch (error) {
    console.error("model error:", error.message);
    return send(customer, "Sorry, I can't answer right now. Please try again in a minute.");
  }
  history.delete(id); // re-insert, so the oldest conversation comes first
  history.set(id, [...past, { role: "user", content: question }, { role: "assistant", content: reply }].slice(-MAX_TURNS));
  if (history.size > 10000) history.delete(history.keys().next().value);
  await send(customer, reply);
}

function receive(message) {
  if (seen.has(message.id)) return; // Meta retries failed deliveries, so a message can arrive twice
  seen.add(message.id);
  if (seen.size > 10000) seen.delete(seen.values().next().value);
  // Reply to the phone number, or to the business-scoped user ID when WhatsApp hides the number.
  const id = message.from_user_id ?? message.from;
  if (!id) return;
  const customer = message.from ? { to: message.from } : { recipient: message.from_user_id };
  const count = (hits.get(id) ?? 0) + 1;
  hits.set(id, count);
  if (count > LIMIT + 1) return; // stay silent: every reply is a message Meta may charge for
  // One queue per customer: answers go out in order, and each one sees the previous answer.
  const job = (queues.get(id) ?? Promise.resolve())
    .then(() => answer(id, customer, message, count > LIMIT))
    .catch((error) => console.error("reply error:", error.message))
    .finally(() => queues.get(id) === job && queues.delete(id));
  queues.set(id, job);
}

const app = express();

// Meta calls this once, when you save the callback URL in the App Dashboard.
app.get("/webhook", (req, res) => {
  const ok = req.query["hub.mode"] === "subscribe" && req.query["hub.verify_token"] === env.WHATSAPP_VERIFY_TOKEN;
  if (!ok) return res.sendStatus(403);
  res.type("text/plain").send(String(req.query["hub.challenge"]));
});

// Meta can batch up to 1,000 updates in one POST.
app.post("/webhook", express.raw({ type: "application/json", limit: "5mb" }), (req, res) => {
  if (!signed(req)) return res.sendStatus(401);
  let body;
  try {
    body = JSON.parse(req.body.toString("utf8"));
  } catch {
    return res.sendStatus(400);
  }
  res.sendStatus(200); // answer Meta first; the replies go out afterwards
  for (const entry of body?.entry ?? []) {
    for (const change of entry.changes ?? []) {
      if (change.value?.metadata?.phone_number_id !== env.WHATSAPP_PHONE_NUMBER_ID) continue;
      for (const message of change.value.messages ?? []) receive(message); // status updates have no "messages"
    }
  }
});

app.listen(env.PORT || 3000, () => console.log("WhatsApp bot running on port", env.PORT || 3000));

اختبرنا هذا الملف في 2026-11-01 على Node.js 22 وExpress 5.3 ومكتبة openai بالإصدار 7.47، أمام بديلين محليين للـ API ولـ WhatsApp Cloud API، برسائل webhook تجريبية موقّعة ومفاتيح وهمية. ويستدعي الكود الإصدار v26.0 من Graph API لدى Meta، وهو أحدث إصدار في سجل تغييراتها في ذلك اليوم.

ونصوص الرسائل الثابتة في الكود بالإنجليزية، مثل الاعتذار ورسالة الانتظار، فترجمها إذا كان عملاؤك يكتبون بالعربية. أما إجابات النموذج فتأتي بلغة العميل، لأن SYSTEM يطلب ذلك.

كيف تُعدّ تطبيق Meta؟#

  1. في لوحة تطبيقات Meta، أي App Dashboard، أنشئ تطبيقًا بحالة الاستخدام «Connect with customers through WhatsApp».
  2. في صفحة API Setup ضمن WhatsApp، انسخ معرّف رقم الهاتف (phone number ID). ويمكنك إضافة رقم نشاطك لاحقًا.
  3. انسخ App Secret من إعدادات تطبيقك. فبه يتحقق الخادم من أن كل تسليم قادم من Meta.
  4. الرمز المؤقت في صفحة API Setup تنتهي صلاحيته سريعًا. وللحصول على رمز يدوم، أضف مستخدم نظام (system user) في Business Settings، وأنشئ له رمزًا بالصلاحيات business_management وwhatsapp_business_management وwhatsapp_business_messaging.
  5. اختر نصًا عشوائيًا طويلًا ليكون رمز التحقق (verify token).
  6. بعد تشغيل الخادم، افتح في App Dashboard المسار Use cases > Customize > Configuration، واضبط عنوان الاستدعاء (callback URL) على عنوان HTTPS الخاص بك متبوعًا بـ /webhook، وأدخل رمز التحقق، واشترك في الحقل messages. فتستدعي Meta العنوان، ويعيد الخادم قيمة challenge.

كيف تشغّله؟#

شغّل هذه الأوامر في المجلد الذي فيه server.mjs، بقيمك أنت:

macOS / Linux
npm install express openai
export KHABEER_API_KEY="YOUR_5ABEER_API_KEY"
export WHATSAPP_TOKEN="YOUR_SYSTEM_USER_TOKEN"
export WHATSAPP_APP_SECRET="YOUR_APP_SECRET"
export WHATSAPP_VERIFY_TOKEN="YOUR_VERIFY_TOKEN"
export WHATSAPP_PHONE_NUMBER_ID="YOUR_PHONE_NUMBER_ID"
node server.mjs
Windows
npm install express openai
$env:KHABEER_API_KEY="YOUR_5ABEER_API_KEY"
$env:WHATSAPP_TOKEN="YOUR_SYSTEM_USER_TOKEN"
$env:WHATSAPP_APP_SECRET="YOUR_APP_SECRET"
$env:WHATSAPP_VERIFY_TOKEN="YOUR_VERIFY_TOKEN"
$env:WHATSAPP_PHONE_NUMBER_ID="YOUR_PHONE_NUMBER_ID"
node server.mjs

ولا تستطيع Meta الوصول إلى localhost، فلتجربته على جهازك افتح نفق HTTPS إلى المنفذ 3000، باستخدام Cloudflare Tunnel مثلًا، واجعل عنوانه هو عنوان الاستدعاء. ولتغيير النموذج أو المنفذ، اضبط CHAT_MODEL أو PORT.

كيف يعمل الكود؟#

  • التوقيع: توقّع Meta كل طلب POST بسرّ تطبيقك في الترويسة X-Hub-Signature-256. ويطابقه الخادم مع النص الخام للطلب، ويرفض أي طلب بلا توقيع صحيح بالخطأ 401.
  • الرد السريع: يعيد الخادم 200 أولًا، ثم يرسل الرد. وتعيد Meta إرسال التحديثات التي لا تتلقى 200، لذلك يتجاهل الخادم معرّفات الرسائل التي رآها من قبل.
  • الذاكرة والترتيب: يذهب مع كل سؤال جديد آخر 5 أسئلة وإجاباتها لدى العميل نفسه، وتحفظ قائمة انتظار لكل عميل ترتيب الإجابات. وتُمحى الذاكرة عند إعادة تشغيل الخادم.
  • الوسائط: تتلقى الصور والمقاطع الصوتية والفيديو والمستندات والملصقات ردًّا يوضّح أن البوت يقرأ النصوص وحدها.
  • الطول: يقتطع الخادم كل رسالة من العميل عند 4000 حرف. ولا تتسع رسالة واتساب النصية لأكثر من 4096 حرفًا، فتخرج الإجابات الأطول على أجزاء.
  • حد المعدل: لكل عميل عشرون رسالة كل 10 دقائق. وتتلقى الرسالة الحادية والعشرون تنبيهًا واحدًا بالانتظار، ولا يرد البوت على ما بعدها.
  • الأخطاء: تعيد المكتبة محاولة الاتصال بالنموذج مرتين، ثم يتلقى العميل اعتذارًا. ويحدّ max_tokens: 800 من طول الإجابة في نماذج Claude وGemini، وتتجاهله نماذج GPT، كما في المعاملات.
  • أسماء المستخدمين: عندما يُخفي واتساب رقم العميل، يرد الخادم على معرّف المستخدم الخاص بالنشاط (business-scoped user ID) عبر recipient.

متى يستطيع البوت أن يرد؟#

تشرح صفحة أسعار Meta أن مراسلة العميل لك أو اتصاله بك يُطلق عدّادًا زمنيًا مدته 24 ساعة يُسمّى نافذة خدمة العملاء، وأن الشركات لا تستطيع إرسال رسائل من غير القوالب إلا والنافذة مفتوحة. وهذا البوت يرد خلال ثوانٍ، أي داخل النافذة. أما إذا أردت أن تبدأ أنت مراسلة العميل، فتحتاج إلى قالب توافق عليه Meta.

كم يكلّف بوت واتساب بالذكاء الاصطناعي؟#

هناك فاتورتان: توكنات النموذج، وتُخصم من رصيدك في 5abeer، ورسوم Meta على الرسائل. وفي هذا المثال يجيب البوت عن 4000 رسالة في الشهر، بنحو 1200 توكن إدخال و250 توكن إخراج لكل رسالة:

مثال: تكلفة ⁦Claude Sonnet 5.5⁩

4.8 مليون توكن إدخال و1 مليون توكن إخراج

سعرنا‏294.00 ج.م‏أقل من السعر الرسمي بنسبة 70%‎
السعر الرسمي‏980.00 ج.م‏

السعر الرسمي من صفحة المزوّد، بتاريخ 19 أكتوبر 2026.

وهذا سعر التوكن في النموذج الافتراضي:

سعر ⁦Claude Sonnet 5.5⁩ لكل مليون توكن
الإدخال‏30 ج.م‏السعر الرسمي: ‏100 ج.م‏
الإخراج‏150 ج.م‏السعر الرسمي: ‏500 ج.م‏

السعر الرسمي من صفحة المزوّد، بتاريخ 19 أكتوبر 2026.

وتقول صفحة أسعار Meta، بصيغتها السارية من 1 أكتوبر 2026:

  • لا تحاسب Meta على الرسائل التي يرسلها مستخدم واتساب إلى الشركة.
  • تمنح Meta كل رقم هاتف تجاري شريحة مجانية من 1000 رسالة خدمة في الشهر (صفحة الأسعار، راجعناها في 2026-11-01).
  • وبعدها تحاسب Meta على كل رسالة خدمة بالأسعار المنشورة في صفحتها، إلا للجهات الحكومية والمنظمات غير الربحية المؤهلة.

وكل جزء من إجابة طويلة يُحسب رسالة. ولتنفق أقل على النموذج، اختر نموذجًا أصغر من صفحة النماذج، أو اختصر SYSTEM، أو اخفض MAX_TURNS وmax_tokens. وقارن بين المزوّدين في صفحة الـ API وصفحات Claude API وOpenAI API وGemini API، والباقات في صفحة الأسعار.

وخصّص للبوت مفتاحًا له حد إنفاق، كما في تحكّم في كل مفتاح. وعند بلوغ الحد تفشل الطلبات بالخطأ API_KEY_QUOTA_EXHAUSTED ويتلقى العملاء الاعتذار، فلا يتجاوز يوم مزدحم أو استخدام مسيء المبلغ الذي حددته.

كيف تحمي البوت؟#

  • احفظ مفتاح 5abeer ورمز واتساب وApp Secret في متغيرات بيئة على الخادم، ولا تضعها أبدًا في الكود أو في مستودع. وإذا تسرّب أحدها، فاستبدله.
  • أبقِ فحص التوقيع، فمن دونه يستطيع أي شخص يعرف العنوان إرسال رسائل مزيّفة وإنفاق رصيدك.
  • إذا كان للخادم عنوان ثابت، فأضف إلى مفتاحه قائمة عناوين IP مسموح بها، كما في تحكّم في كل مفتاح.
  • لا تضع في SYSTEM أسرارًا أو بيانات عملاء آخرين، فقد يحاول العملاء إقناع المساعد بترك تعليماته.
  • أخبر عملاءك أن مساعدًا بالذكاء الاصطناعي هو الذي يجيبهم، ووفّر لهم طريقًا للوصول إلى شخص.

أسئلة شائعة#

هل أستطيع استخدام مكتبة لواتساب ويب بدل Cloud API؟#

لا. فهذه المكتبات تشغّل حسابًا عاديًا تشغيلًا آليًا، وهو ما تمنعه شروط واتساب، وقد يتعرض الرقم للإيقاف.

هل يستطيع البوت استخدام GPT أو Gemini بدل Claude؟#

نعم. اضبط CHAT_MODEL على معرّف نموذج من صفحة النماذج، واستخدم مفتاحًا لمزوّد ذلك النموذج. فكل مفتاح يغطي مزوّدًا واحدًا، واستدعاء نموذج GPT بمفتاح Claude يعيد الخطأ MODEL_PLATFORM_NOT_ALLOWED.

هل يستطيع الرد على الرسائل الصوتية أو الصور؟#

ليس بالكود الحالي. ولإضافة ذلك، نزّل الوسائط عبر Cloud API وأرسلها إلى نموذج يقبل هذا النوع من المدخلات، أو حوّل الرسالة الصوتية إلى نص أولًا.

ماذا يحدث عندما ينفد رصيدي؟#

تفشل الطلبات بالخطأ INSUFFICIENT_BALANCE، ويتلقى العملاء الاعتذار حتى تشحن رصيدك. أما رسوم Meta فمنفصلة، وتُدفع من حسابك لدى Meta.

كيف أدفع ثمن الـ API؟#

تشحن رصيدك في خبير بأي طريقة من طرق الدفع، وتُخصم طلبات البوت من هذا الرصيد.

هل 5abeer جزء من Meta أو OpenAI أو Anthropic أو Google؟#

لا. 5abeer خدمة مستقلة لا تتبع أيًّا منها.

المصادر#

راجعناها في 2026-11-01:

ابدأ#

أنشئ مفتاح Claude، وضعه في KHABEER_API_KEY، ثم اربط رقم واتساب الخاص بك.