Mainstream messaging
الحالة: جاهز للإنتاج عبر WhatsApp Web (Baileys). يدير Gateway الجلسة (أو الجلسات) المرتبطة؛ ولا توجد قناة WhatsApp منفصلة من Twilio.
التثبيت
يطلب openclaw onboard وopenclaw channels add --channel whatsapp تثبيت Plugin عند اختياره أول مرة؛ ويوفر openclaw channels login --channel whatsapp مسار التثبيت نفسه إذا كان Plugin مفقودًا. تستخدم نسخ التطوير مسار Plugin المحلي؛ بينما تثبّت الإصدارات المستقرة/التجريبية @openclaw/whatsapp من ClawHub أولًا، مع الرجوع إلى npm عند التعذر. يُشحن وقت تشغيل WhatsApp خارج حزمة OpenClaw الأساسية على npm، لذلك تبقى تبعيات وقت التشغيل الخاصة به مع Plugin الخارجي. التثبيت اليدوي:
openclaw plugins install clawhub:@openclaw/whatsappلا تستخدم حزمة npm المجردة (@openclaw/whatsapp) إلا كخيار احتياطي للسجل؛ وثبّت إصدارًا محددًا بدقة فقط للحصول على تثبيت قابل لإعادة الإنتاج.
سياسة الرسائل المباشرة الافتراضية للمرسلين غير المعروفين هي الإقران.
أدلة تشخيص وإصلاح تشمل مختلف القنوات.
أنماط وأمثلة كاملة لإعداد القنوات.
الإعداد السريع
إعداد سياسة الوصول
{channels: {whatsapp: { dmPolicy: "pairing", allowFrom: ["+15551234567"], groupPolicy: "allowlist", groupAllowFrom: ["+15551234567"],},},}ربط WhatsApp (رمز QR)
openclaw channels login --channel whatsappيعتمد تسجيل الدخول على رمز QR فقط. على المضيفين البعيدين أو الذين يعملون بلا واجهة رسومية، تأكد قبل بدء تسجيل الدخول من وجود وسيلة موثوقة لإيصال رمز QR المباشر إلى الهاتف؛ فقد تنتهي صلاحية رموز QR المعروضة في الطرفية أو لقطات الشاشة أو مرفقات المحادثة أثناء نقلها.
لحساب محدد:
openclaw channels login --channel whatsapp --account workلإرفاق دليل مصادقة موجود أو مخصص قبل تسجيل الدخول:
openclaw channels add --channel whatsapp --account work --auth-dir /path/to/wa-authopenclaw channels login --channel whatsapp --account workبدء Gateway
openclaw gatewayالموافقة على طلب الإقران الأول (وضع الإقران)
openclaw pairing list whatsappopenclaw pairing approve whatsapp <CODE>تنتهي صلاحية طلبات الإقران بعد ساعة واحدة؛ ويقتصر عدد الطلبات المعلقة على 3 لكل حساب.
أنماط النشر
رقم مخصص (موصى به)
- هوية WhatsApp منفصلة لـ OpenClaw
- قوائم سماح وحدود توجيه أوضح للرسائل المباشرة
- احتمال أقل للالتباس في المحادثة الذاتية
{ channels: { whatsapp: { dmPolicy: "allowlist", allowFrom: ["+15551234567"], }, },}الخيار الاحتياطي للرقم الشخصي
يدعم الإعداد الأولي وضع الرقم الشخصي ويكتب إعدادًا أساسيًا ملائمًا للمحادثة الذاتية: dmPolicy: "allowlist"، وallowFrom متضمنًا رقمك، وselfChatMode: true. تعتمد وسائل حماية المحادثة الذاتية في وقت التشغيل على الرقم الذاتي المرتبط إضافةً إلى allowFrom.
نموذج وقت التشغيل
- يدير Gateway مقبس WhatsApp وحلقة إعادة الاتصال.
- يراقب مراقب الحماية إشارتين بصورة مستقلة: نشاط نقل WhatsApp Web الخام ونشاط رسائل التطبيق. لا تُعاد جلسة هادئة لكنها متصلة لمجرد عدم وصول رسالة مؤخرًا؛ ولا يفرض إعادة الاتصال إلا عند توقف وصول إطارات النقل خلال نافذة داخلية ثابتة (غير قابلة لإعداد المستخدم)، أو استمرار صمت رسائل التطبيق مدة تتجاوز 4 أضعاف مهلة الرسائل العادية. مباشرة بعد إعادة اتصال جلسة كانت نشطة مؤخرًا، تستخدم النافذة الأولى مهلة الرسائل العادية الأقصر بدلًا من نافذة 4 أضعاف المهلة. يستطيع OpenClaw الرد تلقائيًا على الرسائل غير المتصلة التي يسلّمها Baileys مبكرًا أثناء إعادة الاتصال، ضمن مدة منع تكرار معرّف الرسالة الواردة؛ ويحافظ بدء التشغيل الأولي على حاجز السجل القديم قصير المدة.
- تُحدَّد توقيتات مقبس Baileys صراحةً ضمن
web.whatsapp.*: keepAliveIntervalMs(الفاصل الزمني لنبض التطبيق)، وconnectTimeoutMs(مهلة مصافحة فتح الاتصال)، وdefaultQueryTimeoutMs(مدد انتظار استعلامات Baileys، إضافةً إلى مهل الإرسال الصادر/الحضور وإيصالات قراءة الوارد في OpenClaw). - تتطلب عمليات الإرسال الصادرة مستمع WhatsApp نشطًا للحساب المستهدف؛ وإلا تفشل عمليات الإرسال فورًا.
- تُرفق عمليات الإرسال إلى المجموعات بيانات الإشارة الأصلية لرموز
@+<digits>و@<digits>(في النص وتسميات الوسائط) عندما يطابق الرمز البيانات الوصفية الحالية للمشارك، بما في ذلك المجموعات المدعومة بمعرّفات LID. - تُتجاهل محادثات الحالة والبث (
@statusو@broadcast). - تستخدم المحادثات المباشرة قواعد جلسات الرسائل المباشرة (
session.dmScope؛ والقيمة الافتراضيةmainتدمج الرسائل المباشرة في الجلسة الرئيسية للوكيل). تُعزل جلسات المجموعات حسب كل JID (agent:<agentId>:whatsapp:group:<jid>). - يمكن استهداف قنوات/نشرات WhatsApp صراحةً في الإرسال الصادر عبر JID الأصلي الذي ينتهي بـ
@newsletter، باستخدام بيانات جلسة القناة الوصفية (agent:<agentId>:whatsapp:channel:<jid>) بدلًا من دلالات الرسائل المباشرة. - يحترم نقل WhatsApp Web متغيرات بيئة الوكيل القياسية على مضيف Gateway (
HTTPS_PROXYوHTTP_PROXYوNO_PROXYوصيغها بالأحرف الصغيرة). فضّل إعداد الوكيل على مستوى المضيف على الإعدادات الخاصة بكل قناة. - عند تفعيل
messages.removeAckAfterReply، يزيل OpenClaw تفاعل الإقرار بعد تسليم رد مرئي.
الاتصال بمقدم الطلب الحالي باستخدام MeowCaller (تجريبي)
يمكن لـ Plugin إتاحة whatsapp_call في دورات الوكيل الواردة من WhatsApp. ويستخدم MeowCaller لإجراء مكالمة صوتية عبر WhatsApp مع مقدم الطلب الحالي المصرح له وتشغيل رسالة تحويل النص إلى كلام من OpenClaw بعد إجابته. لا تحتوي الأداة على معامل لرقم الوجهة، لذلك لا يمكن لتوجيه نصي إعادة توجيه المكالمة. وهي معطلة افتراضيًا.
تفعيل المكالمات التجريبية
أضف actions.calls: true إلى إعداد قناة WhatsApp وأعد تشغيل Gateway:
{"channels": {"whatsapp": { "actions": { "calls": true }}}}عند غيابها أو ضبطها على false، لا يتيح OpenClaw أداة whatsapp_call.
تثبيت CLI المراجع من MeowCaller
يتوقع المهايئ وجود ملف meowcaller تنفيذي ضمن PATH لمضيف Gateway. إلى أن يُدمج طلب السحب رقم 7 في MeowCaller، ابنِ الفرع المراجع:
git clone --branch feat/send-only-notify https://github.com/steipete/meowcaller.gitcd meowcallergit checkout 752050471fc2bf7a8cdfbf7dbd3cd4e865d85d3fmkdir -p "$HOME/.local/bin"go build -o "$HOME/.local/bin/meowcaller" ./cmd/meowcallerتأكد من وجود $HOME/.local/bin ضمن PATH لخدمة Gateway. تحتوي هذه المراجعة على أمري pair الصريح وnotify المخصص للإرسال فقط؛ ولا يفتح notify أي ميكروفون أو مكبر صوت أو جهاز فيديو أو عملية التقاط تشخيصية. لا تستبدله بأمر play من مثال CLI للمشروع الأصلي.
إقران جهاز MeowCaller المرتبط
اطلب من وكيل WhatsApp التحقق من إعداد المكالمات (يُبلغ إجراء حالة whatsapp_call عن دليل الحالة الخاص بالحساب وأمر الإقران). للحساب الافتراضي:
state_dir="$HOME/.openclaw/credentials/whatsapp-calls/default"mkdir -p "$state_dir"chmod 700 "$state_dir"meowcaller pair --store "$state_dir/wa-voip.db"شغّل هذا تفاعليًا، وامسح رمز QR من WhatsApp > Linked devices، وانتظر ظهور MeowCaller linked device ready. حافظ على خصوصية wa-voip.db — فهو جلسة MeowCaller. تحصل الحسابات غير الافتراضية على مسار التخزين الخاص بها من إجراء الحالة؛ وعلى Windows، شغّل أمر PowerShell الخاص بها.
إعداد تحويل النص إلى كلام والاتصال من WhatsApp
أعدّ موفر تحويل النص إلى كلام يدعم الاتصالات الهاتفية، وأعد تشغيل Gateway، ثم أرسل طلبًا مثل اتصل بي وقل إن عملية البناء اكتملت. تحل الأداة هوية المرسل من السياق الوارد الموثوق، وتنشئ ملف WAV خاصًا ومؤقتًا، وتشغّل MeowCaller ضمن نافذة مكالمة محدودة، ثم تحذف الملف الصوتي بعد ذلك. يمرر OpenClaw مخزن الحساب صراحةً، وينتظر حالة خروج صفرية بعد الإجابة/التشغيل/إنهاء المكالمة، ويعامل انتهاء المهلة أو حالة الخروج غير الصفرية على أنه فشل في استدعاء الأداة.
الحدود: مكالمات صوتية صادرة فردية فقط، ولا أرقام وجهة عشوائية، ولا مصادقة مشتركة مع اتصال المحادثة، ولا مكالمات ذاتية من وضع الرقم الشخصي/المحادثة الذاتية، ويقتصر الصوت المُنشأ على 60 ثانية، ولا يتوفر إيصال لسماع الصوت من جهة الهاتف يتجاوز اكتمال الإجابة/التشغيل/إنهاء المكالمة في MeowCaller، ويوقف OpenClaw العملية المصاحبة بعد نافذة محدودة من 115 إلى 175 ثانية (تشمل مراحل اتصال MeowCaller والإجابة والتشغيل والإيقاف).
مطالبات الموافقة
يمكن لـ WhatsApp عرض مطالبات الموافقة على التنفيذ وPlugin كتفاعلات 👍/👎، ويتحكم فيها إعداد تمرير الموافقات ذي المستوى الأعلى:
{ approvals: { exec: { enabled: true, mode: "session", }, plugin: { enabled: true, mode: "targets", targets: [{ channel: "whatsapp", to: "+15551234567" }], }, },}يعمل approvals.exec وapprovals.plugin بصورة مستقلة؛ فتفعيل WhatsApp كقناة لا يؤدي إلا إلى ربط وسيلة النقل، ولا يرسل شيئًا ما لم تكن فئة الموافقات المطابقة مفعلة وموجهة إليها. لا يسلّم وضع الجلسة موافقات الرموز التعبيرية الأصلية إلا للموافقات الناشئة من WhatsApp. يستخدم وضع الأهداف مسار التمرير المشترك للأهداف الصريحة ولا ينشئ توزيعًا منفصلًا للرسائل المباشرة إلى الموافقين.
تتطلب تفاعلات الموافقة في WhatsApp تحديد الموافقين صراحةً في allowFrom (أو "*"). يحدد defaultTo أهداف الرسائل الافتراضية العادية، وليس قائمة الموافقين. وتظل أوامر /approve اليدوية تمر عبر مسار تخويل مرسل WhatsApp المعتاد قبل حسم الموافقة.
خطافات Plugin والخصوصية
قد تحمل رسائل WhatsApp الواردة محتوى شخصيًا وأرقام هواتف ومعرّفات مجموعات وأسماء مرسلين وحقول ربط الجلسات. لا يبث WhatsApp حمولات خطاف message_received الواردة إلى Plugins ما لم تشترك صراحةً:
{ channels: { whatsapp: { pluginHooks: { messageReceived: true, }, }, },}احصر الاشتراك في حساب واحد ضمن channels.whatsapp.accounts.<id>.pluginHooks.messageReceived. لا تفعّل هذا إلا لـ Plugins التي تثق بها للتعامل مع محتوى WhatsApp الوارد ومعرّفاته.
التحكم في الوصول والتفعيل
سياسة الرسائل المباشرة
channels.whatsapp.dmPolicy:
| القيمة | السلوك |
|---|---|
pairing (الافتراضي) |
يطلب المرسلون غير المعروفين الإقران؛ ويوافق المالك |
allowlist |
يُسمح فقط للمرسلين الموجودين في allowFrom |
open |
يتطلب أن تتضمن allowFrom القيمة "*" |
disabled |
يحظر جميع الرسائل المباشرة |
تقبل allowFrom أرقامًا بتنسيق E.164 (وتُطبَّع داخليًا). وهي قائمة تحكم في وصول مرسلي الرسائل المباشرة فقط — ولا تمنع عمليات الإرسال الصادرة الصريحة إلى معرّفات JID للمجموعات أو معرّفات JID للقنوات التي تنتهي بـ@newsletter.
تجاوز الحسابات المتعددة: تكون لـchannels.whatsapp.accounts.<id>.dmPolicy (وكذلك .allowFrom) الأولوية على الإعدادات الافتراضية على مستوى القناة لذلك الحساب.
ملاحظات وقت التشغيل:
- تستمر عمليات الاقتران في مخزن السماح الخاص بالقناة وتُدمج مع
allowFromالمُهيّأ - تستخدم الأتمتة المجدولة والوجهة الاحتياطية لمستلم Heartbeat أهداف تسليم صريحة أو
allowFromالمُهيّأ؛ ولا تُعد موافقات اقتران الرسائل المباشرة مستلمين ضمنيين لـ Cron أو Heartbeat - إذا لم تُهيّأ قائمة سماح، يُسمح افتراضيًا بالرقم الذاتي المرتبط
- لا يُجري OpenClaw مطلقًا اقترانًا تلقائيًا للرسائل المباشرة الصادرة ذات
fromMe(الرسائل التي ترسلها إلى نفسك من الجهاز المرتبط)
سياسة المجموعات وقوائم السماح
يتكون الوصول إلى المجموعات من طبقتين:
- قائمة السماح لعضوية المجموعات (
channels.whatsapp.groups): إذا حُذفgroups، تكون جميع المجموعات مؤهلة؛ وإذا كان موجودًا، يعمل كقائمة سماح للمجموعات (تسمح"*"بالجميع). - سياسة مرسلي المجموعات (
channels.whatsapp.groupPolicy+groupAllowFrom): تتجاوزopenقائمة سماح المرسلين، وتتطلبallowlistتطابقًا معgroupAllowFrom(أو*)، وتحظرdisabledجميع الرسائل الواردة من المجموعات.
إذا لم تُعيّن groupAllowFrom، تعود عمليات التحقق من المرسل إلى allowFrom عندما تحتوي على إدخالات. تُقيّم قوائم سماح المرسلين قبل التنشيط بالإشارة أو الرد.
إذا لم توجد كتلة channels.whatsapp إطلاقًا، يعود وقت التشغيل إلى groupPolicy: "allowlist" (مع تسجيل تحذير)، حتى إذا عُيّنت channels.defaults.groupPolicy إلى قيمة أخرى.
الإشارات و/activation
تتطلب الردود في المجموعات إشارة افتراضيًا. يشمل اكتشاف الإشارات ما يلي:
- إشارات WhatsApp الصريحة إلى هوية البوت
- أنماط التعبيرات النمطية المُهيّأة للإشارات (
agents.list[].groupChat.mentionPatterns، مع الرجوع إلىmessages.groupChat.mentionPatterns) - نصوص تفريغ الملاحظات الصوتية الواردة لرسائل المجموعات المصرح بها
- الاكتشاف الضمني للرد على البوت (يتطابق مرسل الرد مع هوية البوت)
الأمان: يحقق الاقتباس/الرد شرط الإشارة فقط — ولا يمنح تفويضًا للمرسل. مع groupPolicy: "allowlist"، يظل المرسلون غير المدرجين في قائمة السماح محظورين حتى عند الرد على رسالة مستخدم مُدرج في قائمة السماح.
أمر التنشيط على مستوى الجلسة: /activation mention أو /activation always. يحدّث هذا حالة الجلسة (وليس الإعداد العام) ويقتصر على المالك.
ارتباطات ACP المُهيّأة
يدعم WhatsApp ارتباطات ACP الدائمة عبر bindings[] في المستوى الأعلى:
{ bindings: [ { type: "acp", agentId: "codex", match: { channel: "whatsapp", accountId: "work", peer: { kind: "direct", id: "+15555550123" }, }, }, { type: "acp", agentId: "codex", match: { channel: "whatsapp", accountId: "work", peer: { kind: "group", id: "120363424282127706@g.us" }, }, }, ],}تتطابق المحادثات المباشرة مع أرقام E.164؛ وتتطابق المجموعات مع معرّفات JID لمجموعات WhatsApp. تُطبّق قوائم سماح المجموعات وسياسة المرسلين وشروط الإشارة/التنشيط قبل أن يضمن OpenClaw وجود جلسة ACP المرتبطة. يمتلك الارتباط المتطابق مسار التوجيه — ولا توزّع مجموعات البث تلك الجولة على جلسات WhatsApp العادية.
سلوك الرقم الشخصي والمحادثة الذاتية
عندما يكون الرقم الذاتي المرتبط موجودًا أيضًا في allowFrom، تُفعّل ضمانات المحادثة الذاتية: يُتخطى إرسال إيصالات القراءة لجولات المحادثة الذاتية، ويُتجاهل سلوك التشغيل التلقائي عبر JID الإشارة الذي قد ينبهك أنت، وتستخدم الردود افتراضيًا [{identity.name}] (أو [openclaw]) عندما لا تكون messages.responsePrefix مُعيّنة.
تسوية الرسائل والسياق
غلاف الرسائل الواردة وسياق الرد
تُغلّف الرسائل الواردة بغلاف الرسائل الواردة المشترك. يضيف الرد المقتبس سياقًا بهذه الصيغة:
[Replying to <sender> id:<stanzaId>]<quoted body or media placeholder>[/Replying]تُملأ بيانات الرد الوصفية (ReplyToId وReplyToBody وReplyToSender وJID/E.164 للمرسل) عند توفرها. إذا كان الهدف المقتبس وسائط قابلة للتنزيل، يحفظه OpenClaw عبر مخزن الوسائط الواردة المعتاد ويعرض MediaPath/MediaType كي يتمكن الوكيل من فحصه مباشرة بدلًا من رؤية <media:image> فقط.
العناصر النائبة للوسائط واستخراج الموقع/جهة الاتصال
تُسوّى الرسائل التي تحتوي على وسائط فقط إلى عناصر نائبة: <media:image> و<media:video> و<media:audio> و<media:document> و<media:sticker>.
تُفرّغ الملاحظات الصوتية المصرح بها في المجموعات قبل التحقق من شرط الإشارة عندما يكون النص الأساسي هو <media:audio> فقط، لذا فإن نطق إشارة البوت في الملاحظة الصوتية يمكن أن يشغّل الرد. إذا ظل النص المُفرّغ لا يشير إلى البوت، فيبقى ضمن سجل المجموعة المعلّق بدلًا من العنصر النائب الخام.
تُعرض نصوص الموقع كإحداثيات موجزة. وتُعرض تسميات/تعليقات الموقع وتفاصيل جهة الاتصال/vCard كبيانات وصفية غير موثوق بها داخل سياج، لا كنص مضمّن في الموجّه.
حقن سجل المجموعة المعلّق
تُخزّن رسائل المجموعة غير المعالجة مؤقتًا وتُحقن كسياق عند تشغيل البوت أخيرًا.
- الحد الافتراضي:
50 - الإعداد:
channels.whatsapp.historyLimit، مع الرجوع إلىmessages.groupChat.historyLimit - القيمة
0تعطّل ذلك
علامات الحقن: [Chat messages since your last reply - for context] و[Current message - respond to this].
إيصالات القراءة
تكون مفعّلة افتراضيًا للرسائل الواردة المقبولة. لتعطيلها عموميًا:
{ channels: { whatsapp: { sendReadReceipts: false } } }التجاوز لكل حساب: channels.whatsapp.accounts.<id>.sendReadReceipts. تتخطى جولات المحادثة الذاتية إيصالات القراءة حتى عند تفعيلها عموميًا.
التسليم والتقسيم والوسائط
تقسيم النص
- الحد الافتراضي للمقطع:
channels.whatsapp.textChunkLimit = 4000 channels.whatsapp.chunkMode = "length" | "newline"؛ يفضّلnewlineحدود الفقرات (الأسطر الفارغة)، ثم يعود إلى التقسيم الآمن حسب الطول
سلوك الوسائط الصادرة
- يدعم حمولات الصور والفيديو والصوت (ملاحظة صوتية بنمط الضغط للتحدث) والمستندات
- يُرسل الصوت كحمولة
audioفي Baileys معptt: true، فيظهر كملاحظة صوتية بنمط الضغط للتحدث؛ ويُحافظ علىaudioAsVoiceفي حمولات الرد كي يظل إخراج الملاحظة الصوتية من تحويل النص إلى كلام في هذا المسار بغض النظر عن تنسيق المصدر لدى المزوّد - يُرسل صوت Ogg/Opus الأصلي بصيغة
audio/ogg; codecs=opus؛ أما أي تنسيق آخر (بما في ذلك إخراج MP3/WebM من تحويل النص إلى كلام في Microsoft Edge) فيُحوّل ترميزه باستخدامffmpegإلى Ogg/Opus أحادي القناة بتردد 48 كيلوهرتز قبل التسليم بنمط الضغط للتحدث - يرسل
/tts latestأحدث رد للمساعد كملاحظة صوتية واحدة ويمنع تكرار الإرسال للرد نفسه؛ ويتحكم/tts chat on|off|defaultفي التحويل التلقائي من النص إلى كلام للمحادثة الحالية - يتيح
gifPlayback: trueفي إرسال الفيديو تشغيل صور GIF المتحركة - يوجّه
forceDocument/asDocumentالصور وملفات GIF ومقاطع الفيديو الصادرة عبر حمولة المستند في Baileys لتجنب ضغط الوسائط في WhatsApp، مع الحفاظ على اسم الملف ونوع MIME المُحددين - تُطبّق التسميات التوضيحية على أول عنصر وسائط في رد متعدد الوسائط، باستثناء الملاحظات الصوتية بنمط الضغط للتحدث: يُرسل الصوت أولًا دون تسمية توضيحية، ثم تُرسل التسمية التوضيحية كرسالة نصية منفصلة (لا تعرض عملاء WhatsApp تسميات الملاحظات الصوتية باتساق)
- يمكن أن يكون مصدر الوسائط HTTP(S) أو
file://أو مسارًا محليًا
حدود حجم الوسائط وسلوك الرجوع الاحتياطي
- الحد الأقصى لحفظ الوسائط الواردة وإرسال الوسائط الصادرة:
channels.whatsapp.mediaMaxMb(الافتراضي50) - التجاوز لكل حساب:
channels.whatsapp.accounts.<id>.mediaMaxMb - تُحسّن الصور تلقائيًا (تغيير الحجم/فحص الجودة) لتلائم الحدود، ما لم يطلب
forceDocument/asDocumentالتسليم كمستند - عند فشل إرسال الوسائط، يرسل الرجوع الاحتياطي للعنصر الأول تحذيرًا نصيًا بدلًا من إسقاط الرد بصمت
اقتباس الردود
يتحكم channels.whatsapp.replyToMode في اقتباس الرد الأصلي (تقتبس الردود الصادرة الرسالة الواردة بوضوح):
| القيمة | السلوك |
|---|---|
"off" (افتراضي) |
لا تقتبس مطلقًا؛ أرسل كرسالة عادية |
"first" |
اقتبس مقطع الرد الصادر الأول فقط |
"all" |
اقتبس كل مقطع من الرد الصادر |
"batched" |
اقتبس الردود المجمّعة الموضوعة في قائمة الانتظار؛ واترك الردود الفورية دون اقتباس |
التجاوز لكل حساب: channels.whatsapp.accounts.<id>.replyToMode.
{ channels: { whatsapp: { replyToMode: "first" } } }مستوى التفاعلات
يتحكم channels.whatsapp.reactionLevel في مدى استخدام الوكيل لتفاعلات الرموز التعبيرية:
| المستوى | تفاعلات الإقرار | التفاعلات التي يبدأها الوكيل |
|---|---|---|
"off" |
لا | لا |
"ack" |
نعم | لا |
"minimal" (افتراضي) |
نعم | نعم، بإرشادات محافظة |
"extensive" |
نعم | نعم، بإرشادات مشجعة |
التجاوز لكل حساب: channels.whatsapp.accounts.<id>.reactionLevel.
{ channels: { whatsapp: { reactionLevel: "ack" } } }تفاعلات الإقرار
يرسل channels.whatsapp.ackReaction تفاعلًا فوريًا عند استلام رسالة واردة، وفقًا لـreactionLevel (ويُمنع عندما تكون القيمة "off"):
{ channels: { whatsapp: { ackReaction: { emoji: "👀", direct: true, group: "mentions", // always | mentions | never }, }, },}ملاحظات: يُرسل فور قبول الرسالة الواردة (قبل الرد)؛ وإذا وُجد ackReaction دون emoji، يستخدم WhatsApp الرمز التعبيري لهوية الوكيل الذي جرى توجيه الرسالة إليه، مع الرجوع إلى "👀" (احذف ackReaction أو عيّن emoji: "" لعدم إرسال إقرار)؛ تُسجل حالات الفشل لكنها لا تمنع تسليم الرد؛ يتفاعل وضع المجموعة mentions فقط في الجولات التي شغّلتها إشارة، بينما يتجاوز تنشيط المجموعة always هذا التحقق؛ يستخدم WhatsApp إعداد channels.whatsapp.ackReaction فقط (ولا ينطبق هنا الإعداد القديم messages.ackReaction).
تفاعلات حالة دورة الحياة
عيّن messages.statusReactions.enabled: true للسماح لـWhatsApp باستبدال تفاعل الإقرار خلال الجولة بدلًا من ترك رمز تعبيري ثابت للاستلام، مع التنقل بين حالات مثل الانتظار في قائمة، والتفكير، ونشاط الأدوات، وCompaction، والانتهاء، والخطأ:
{ messages: { statusReactions: { enabled: true, emojis: { deploy: "🛫", build: "🏗️", concierge: "💁", }, }, },}ملاحظات: يظل channels.whatsapp.ackReaction متحكمًا في أهلية الرسائل المباشرة والمجموعات؛ وتستخدم حالة الانتظار في القائمة الرمز التعبيري الفعلي نفسه المستخدم في تفاعلات الإقرار العادية؛ ولدى WhatsApp خانة واحدة لتفاعل البوت لكل رسالة، لذا تستبدل تحديثات دورة الحياة التفاعل الحالي في موضعه؛ ويمسح messages.removeAckAfterReply: true تفاعل الحالة النهائي بعد مدة الاحتفاظ المُهيّأة لحالة الانتهاء/الخطأ؛ وتشمل فئات الرموز التعبيرية للأدوات tool وcoding وweb وdeploy وbuild وconcierge.
الحسابات المتعددة وبيانات الاعتماد
اختيار الحساب والإعدادات الافتراضية
تأتي معرّفات الحسابات من channels.whatsapp.accounts. يكون اختيار الحساب الافتراضي هو default إذا كان موجودًا، وإلا فأول معرّف حساب مُهيّأ (مرتب أبجديًا). تُسوّى معرّفات الحسابات داخليًا لأغراض البحث.
مسارات بيانات الاعتماد والتوافق مع الإصدارات القديمة
- مسار المصادقة الحالي:
~/.openclaw/credentials/whatsapp/<accountId>/creds.json(النسخة الاحتياطية:creds.json.bak) - لا تزال المصادقة الافتراضية القديمة في
~/.openclaw/credentials/معروفة ويجري ترحيلها لتدفقات الحساب الافتراضي
سلوك تسجيل الخروج
يمحو openclaw channels logout --channel whatsapp [--account <id>] حالة مصادقة WhatsApp لذلك الحساب. عندما يكون Gateway متاحًا، يوقف تسجيل الخروج أولًا المستمع النشط لذلك الحساب، بحيث تتوقف الجلسة المرتبطة عن تلقي الرسائل قبل إعادة التشغيل التالية. يوقف openclaw channels remove --channel whatsapp أيضًا المستمع النشط قبل تعطيل إعدادات الحساب أو حذفها.
في أدلة المصادقة القديمة، يُحتفظ بملف oauth.json بينما تُزال ملفات مصادقة Baileys.
الأدوات والإجراءات وعمليات كتابة الإعدادات
- يتضمن دعم أدوات الوكيل إجراء تفاعل WhatsApp (
react). - بوابات الإجراءات:
channels.whatsapp.actions.reactionsوchannels.whatsapp.actions.polls(الإجراءات الموجودة قيمتها الافتراضيةtrue) وchannels.whatsapp.actions.calls(قيمتها الافتراضيةfalse، راجع MeowCaller أعلاه). - تكون عمليات كتابة الإعدادات التي تبدأها القناة مفعّلة افتراضيًا؛ عطّلها عبر
channels.whatsapp.configWrites: false.
استكشاف الأخطاء وإصلاحها
غير مرتبط (رمز QR مطلوب)
العَرَض: تفيد حالة القناة بأنها غير مرتبطة.
openclaw channels login --channel whatsappopenclaw channels statusمرتبط لكنه غير متصل / حلقة إعادة اتصال
العَرَض: حساب مرتبط مع انقطاعات متكررة أو محاولات متكررة لإعادة الاتصال.
يمكن للحسابات قليلة النشاط أن تظل متصلة بعد انقضاء مهلة الرسائل المعتادة؛ ولا تعيد آلية المراقبة التشغيل إلا عند توقف نشاط نقل WhatsApp Web، أو إغلاق المقبس، أو استمرار غياب النشاط على مستوى التطبيق لما بعد نافذة الأمان الأطول (راجع نموذج وقت التشغيل أعلاه).
إذا أظهرت السجلات تكرار status=408 Request Time-out Connection was lost، فاضبط توقيتات مقبس Baileys ضمن web.whatsapp. ابدأ بتقليل keepAliveIntervalMs إلى ما دون مهلة خمول شبكتك وزيادة connectTimeoutMs على الاتصالات البطيئة أو كثيرة الفقد:
{ web: { whatsapp: { keepAliveIntervalMs: 15000, connectTimeoutMs: 60000, defaultQueryTimeoutMs: 60000, }, },}الإصلاح:
openclaw channels status --probeopenclaw doctoropenclaw logs --followopenclaw gateway statusإذا استمرت الحلقة بعد إصلاح اتصال المضيف والتوقيت، فأنشئ نسخة احتياطية من دليل مصادقة الحساب ثم أعد ربطه:
cp -a ~/.openclaw/credentials/whatsapp/<accountId> \ ~/.openclaw/credentials/whatsapp/<accountId>.bakopenclaw channels logout --channel whatsapp --account <accountId>openclaw channels login --channel whatsapp --account <accountId>إذا ذكر ~/.openclaw/logs/whatsapp-health.log أن Gateway inactive بينما يُظهر كل من openclaw gateway status وopenclaw channels status --probe حالة سليمة، فشغّل openclaw doctor. على Linux، يحذّر الفاحص من إدخالات crontab القديمة التي تستدعي السكربت المتقاعد ~/.openclaw/bin/ensure-whatsapp.sh؛ أزل تلك الإدخالات باستخدام crontab -e — فقد تفتقر Cron إلى بيئة ناقل مستخدم systemd، ما يجعل ذلك السكربت القديم يبلغ خطأً عن سلامة Gateway.
انتهاء مهلة تسجيل الدخول عبر QR خلف وكيل
العَرَض: يفشل openclaw channels login --channel whatsapp قبل عرض رمز QR صالح للاستخدام، مع status=408 Request Time-out أو انقطاع مقبس TLS.
يستخدم تسجيل الدخول إلى WhatsApp Web بيئة الوكيل القياسية لمضيف Gateway (HTTPS_PROXY وHTTP_PROXY وصِيَغهما بالأحرف الصغيرة وNO_PROXY). تحقّق من أن عملية Gateway ترث بيئة الوكيل وأن NO_PROXY لا يطابق mmg.whatsapp.net.
لا يوجد مستمع نشط عند الإرسال
تفشل عمليات الإرسال الصادر فورًا عندما لا يوجد مستمع Gateway نشط للحساب المستهدف. تأكد من تشغيل Gateway ومن ارتباط الحساب.
يظهر الرد في النص المنسوخ لكن ليس في WhatsApp
تسجّل صفوف النص المنسوخ ما أنشأه الوكيل؛ ويُتحقق من تسليم WhatsApp بشكل منفصل. لا يعتبر OpenClaw الرد التلقائي مُرسلًا إلا بعد أن يعيد Baileys معرّف رسالة صادرة لعملية إرسال واحدة على الأقل لنص أو وسائط مرئية.
تفاعلات الإقرار هي إيصالات مستقلة تسبق الرد — لا يثبت نجاح التفاعل أن الرد النصي أو رد الوسائط اللاحق قد قُبل. افحص سجلات Gateway بحثًا عن auto-reply delivery failed أو auto-reply was not accepted by WhatsApp provider.
تجاهل رسائل المجموعة بصورة غير متوقعة
تحقّق بهذا الترتيب: groupPolicy، ثم groupAllowFrom/allowFrom، ثم إدخالات قائمة السماح groups، ثم اشتراط الإشارة (requireMention + أنماط الإشارة)، ثم المفاتيح المكررة في openclaw.json (تتجاوز إدخالات JSON5 اللاحقة الإدخالات السابقة — احتفظ بمفتاح groupPolicy واحد لكل نطاق).
إذا كان channels.whatsapp.groups موجودًا، فقد يظل WhatsApp يرصد الرسائل الواردة من مجموعات أخرى، لكن OpenClaw يسقطها قبل توجيه الجلسة. أضف JID المجموعة إلى channels.whatsapp.groups، أو أضف groups["*"] للسماح بجميع المجموعات مع إبقاء تخويل المرسلين خاضعًا لـgroupPolicy/groupAllowFrom.
تحذير وقت تشغيل Bun
يجب أن يستخدم وقت تشغيل Gateway الخاص بـWhatsApp Node. يُصنّف Bun على أنه غير متوافق مع التشغيل المستقر لـGateway الخاص بـWhatsApp/Telegram.
مطالبات النظام
يدعم WhatsApp مطالبات نظام على نمط Telegram للمجموعات والمحادثات المباشرة عبر خريطتي groups وdirect.
تحديد المطالبة لرسائل المجموعات: تُحدَّد خريطة groups الفعلية أولًا — إذا عرّف الحساب مفتاح groups خاصًا به بأي صورة، فإنه يستبدل خريطة groups الجذرية بالكامل (من دون دمج عميق). ثم يجري البحث عن المطالبة في تلك الخريطة الناتجة وحدها:
- مطالبة خاصة بالمجموعة (
groups["<groupId>"].systemPrompt): تُستخدم عندما يكون إدخال المجموعة موجودًا ويكون مفتاحsystemPromptفيه معرّفًا. تمنع السلسلة الفارغة ("") استخدام حرف البدل، ولا تطبّق أي مطالبة. - مطالبة حرف بدل للمجموعات (
groups["*"].systemPrompt): تُستخدم عندما يكون إدخال المجموعة المحددة غائبًا، أو موجودًا من دون مفتاحsystemPrompt.
يتبع تحديد المطالبة للرسائل المباشرة النمط نفسه تمامًا مع خريطة direct وdirect["*"].
الاختلاف عن Telegram: يمنع Telegram استخدام groups الجذرية لكل حساب في إعداد متعدد الحسابات (حتى الحسابات التي لا تملك groups خاصة بها)، لمنع الروبوت من تلقي رسائل مجموعات لا ينتمي إليها. لا يطبّق WhatsApp ذلك الضابط — إذ يرث أي حساب لا يملك تجاوزًا خاصًا به groups/direct الجذرية، بصرف النظر عن عدد الحسابات. في إعداد WhatsApp متعدد الحسابات، عرّف الخريطة الكاملة صراحةً ضمن كل حساب إذا أردت مطالبات خاصة بكل حساب.
سلوك مهم:
- يُعد
channels.whatsapp.groupsخريطة إعدادات لكل مجموعة وقائمة سماح للمجموعات على مستوى المحادثة في الوقت نفسه. سواء في النطاق الجذري أو نطاق الحساب، تعنيgroups["*"]«السماح بجميع المجموعات» لذلك النطاق. - لا تُضف
systemPromptبحرف بدل إلا عندما تريد بالفعل السماح لجميع المجموعات في ذلك النطاق. ولإبقاء مجموعة ثابتة فقط من معرّفات المجموعات مؤهلة، كرر المطالبة في كل إدخال مسموح به صراحةً بدلًا من استخدامgroups["*"]. - السماح للمجموعة وتخويل المرسل فحصان منفصلان. توسّع
groups["*"]نطاق المجموعات التي تصل إلى معالجة المجموعات؛ لكنها لا تخوّل كل مرسل في تلك المجموعات — إذ يظل ذلك خاضعًا لـgroupPolicy/groupAllowFrom. - لا يملك
channels.whatsapp.directأثرًا جانبيًا مماثلًا للرسائل المباشرة: لا يوفّرdirect["*"]سوى إعداد افتراضي بعد السماح للرسالة المباشرة بالفعل وفقdmPolicyمعallowFromأو قواعد مخزن الاقتران.
مثال:
{ channels: { whatsapp: { groups: { // استخدمه فقط إذا كان ينبغي السماح بجميع المجموعات في النطاق الجذري. // ينطبق على جميع الحسابات التي لا تعرّف خريطة groups خاصة بها. "*": { systemPrompt: "المطالبة الافتراضية لجميع المجموعات." }, }, direct: { // ينطبق على جميع الحسابات التي لا تعرّف خريطة direct خاصة بها. "*": { systemPrompt: "المطالبة الافتراضية لجميع المحادثات المباشرة." }, }, accounts: { work: { groups: { // يعرّف هذا الحساب groups خاصة به، ولذلك تُستبدل groups الجذرية // بالكامل. للاحتفاظ بحرف بدل، عرّف "*" صراحةً هنا أيضًا. "120363406415684625@g.us": { requireMention: false, systemPrompt: "ركّز على إدارة المشروع.", }, // استخدمه فقط إذا كان ينبغي السماح بجميع المجموعات في هذا الحساب. "*": { systemPrompt: "المطالبة الافتراضية لمجموعات العمل." }, }, direct: { // يعرّف هذا الحساب خريطة direct خاصة به، ولذلك تُستبدل إدخالات direct // الجذرية بالكامل. للاحتفاظ بحرف بدل، عرّف "*" صراحةً هنا أيضًا. "+15551234567": { systemPrompt: "مطالبة لمحادثة عمل مباشرة محددة." }, "*": { systemPrompt: "المطالبة الافتراضية لمحادثات العمل المباشرة." }, }, }, }, }, },}مؤشرات مرجع الإعدادات
المرجع الأساسي: مرجع الإعدادات - WhatsApp
| المجال | الحقول |
|---|---|
| الوصول | dmPolicy, allowFrom, groupPolicy, groupAllowFrom, groups |
| التسليم | textChunkLimit, chunkMode, mediaMaxMb, sendReadReceipts, ackReaction, reactionLevel |
| تعدد الحسابات | accounts.<id>.enabled، وaccounts.<id>.authDir، وتجاوزات أخرى خاصة بكل حساب |
| العمليات | configWrites, debounceMs, web.enabled, web.heartbeatSeconds, web.reconnect.*, web.whatsapp.* |
| سلوك الجلسة | session.dmScope, historyLimit, dmHistoryLimit, dms.<id>.historyLimit |
| المطالبات | groups.<id>.systemPrompt, groups["*"].systemPrompt, direct.<id>.systemPrompt, direct["*"].systemPrompt |