imessage المضمّن يصل الآن إلى سطح API الخاص نفسه الذي يستخدمه BlueBubbles (react وedit وunsend وreply وsendWithEffect وإدارة المجموعات والمرفقات) عبر تشغيل steipete/imsg من خلال JSON-RPC. إذا كنت تشغّل بالفعل جهاز Mac مثبتًا عليه imsg، يمكنك الاستغناء عن خادم BlueBubbles والسماح للـ Plugin بالتواصل مع Messages.app مباشرة.
تمت إزالة دعم BlueBubbles. يدعم OpenClaw خدمة iMessage عبر imsg فقط. هذا الدليل مخصص لترحيل إعدادات channels.bluebubbles القديمة إلى channels.imessage؛ ولا يوجد مسار ترحيل آخر مدعوم.
للاطلاع على الإعلان القصير وملخص المشغّل، راجع إزالة BlueBubbles ومسار imsg لـ iMessage.
قائمة تحقق الترحيل
استخدم قائمة التحقق هذه عندما تكون تعرف بالفعل إعداد BlueBubbles القديم لديك وتريد أقصر مسار آمن:- تحقق من
imsgمباشرة على جهاز Mac الذي يشغّل Messages.app (imsg chatsوimsg historyوimsg sendوimsg rpc --help). - انسخ مفاتيح السلوك من
channels.bluebubblesإلىchannels.imessage:dmPolicyوallowFromوgroupPolicyوgroupAllowFromوgroupsوincludeAttachmentsوattachmentRootsوmediaMaxMbوtextChunkLimitوcoalesceSameSenderDmsوactions. - احذف مفاتيح النقل التي لم تعد موجودة:
serverUrlوpasswordوعناوين URL الخاصة بالـ Webhook وإعداد خادم BlueBubbles. - إذا لم يكن Gateway يعمل على جهاز Mac الخاص بالرسائل، فاضبط
channels.imessage.cliPathعلى غلاف SSH واضبطremoteHostلجلب المرفقات عن بعد. - مع إيقاف Gateway، فعّل
channels.imessage، ثم شغّلopenclaw channels status --probe --channel imessage. - اختبر رسالة مباشرة واحدة، ومجموعة واحدة مسموحًا بها، والمرفقات إذا كانت مفعّلة، وكل إجراء API خاص تتوقع أن يستخدمه الوكيل.
- احذف خادم BlueBubbles وإعداد
channels.bluebubblesالقديم بعد التحقق من مسار iMessage.
متى يكون هذا الترحيل مناسبًا
- أنت تشغّل
imsgبالفعل على جهاز Mac نفسه (أو على جهاز يمكن الوصول إليه عبر SSH) حيث تم تسجيل الدخول إلى Messages.app. - تريد جزءًا متحركًا أقل — لا خادم BlueBubbles منفصل، ولا نقطة نهاية REST للمصادقة، ولا توصيل Webhook. ملف CLI تنفيذي واحد بدلًا من خادم + تطبيق عميل + مساعد.
- أنت تستخدم إصدار macOS /
imsgمدعومًا حيث يعرض فحص API الخاصavailable: true.
ما الذي يفعله imsg
imsg هو CLI محلي لنظام macOS مخصص للرسائل. يبدأ OpenClaw تشغيل imsg rpc كعملية فرعية ويتواصل عبر JSON-RPC من خلال stdin/stdout. لا يوجد خادم HTTP، ولا عنوان URL للـ Webhook، ولا عفريت خلفية، ولا وكيل تشغيل، ولا منفذ يحتاج إلى كشفه.
- تأتي القراءات من
~/Library/Messages/chat.dbباستخدام مقبض SQLite للقراءة فقط. - تأتي الرسائل الواردة الحية من
imsg watch/watch.subscribe، الذي يتتبع أحداث نظام الملفات فيchat.dbمع رجوع احتياطي إلى الاستقصاء. - تستخدم عمليات الإرسال أتمتة Messages.app لإرسال النصوص والملفات العادية.
- تستخدم الإجراءات المتقدمة
imsg launchلحقن مساعدimsgفي Messages.app. هذا ما يتيح إيصالات القراءة، ومؤشرات الكتابة، والإرسال الغني، والتحرير، والتراجع عن الإرسال، والردود المتسلسلة، وtapbacks، وإدارة المجموعات. - يمكن لإصدارات Linux فحص نسخة من
chat.db، لكنها لا تستطيع الإرسال، أو مراقبة قاعدة بيانات Mac الحية، أو تشغيل Messages.app. بالنسبة إلى iMessage في OpenClaw، شغّلimsgعلى جهاز Mac الذي تم تسجيل الدخول عليه أو من خلال غلاف SSH إلى ذلك الجهاز.
قبل أن تبدأ
-
ثبّت
imsgعلى جهاز Mac الذي يشغّل Messages.app:إذا فشلimsg chatsبرسالةunable to open database file، أو بإخراج فارغ، أوauthorization denied، فامنح وصول القرص الكامل للطرفية، أو المحرر، أو عملية Node، أو خدمة Gateway، أو عملية SSH الأصلية التي تطلقimsg، ثم أعد فتح تلك العملية الأصلية. -
تحقق من أسطح القراءة والمراقبة والإرسال وRPC قبل تغيير إعداد OpenClaw:
استبدل
42بمعرّف محادثة حقيقي منimsg chats. يتطلب الإرسال إذن Automation لـ Messages.app. إذا كان OpenClaw سيعمل عبر SSH، فشغّل هذه الأوامر من خلال غلاف SSH نفسه أو سياق المستخدم نفسه الذي سيستخدمه OpenClaw. إذا نجحت القراءات/الفحوصات لكن فشل الإرسال مع AppleEvents-1743، فتحقق مما إذا كان إذن Automation قد وصل إلى/usr/libexec/sshd-keygen-wrapper؛ راجع فشل إرسال غلاف SSH مع AppleEvents -1743. -
فعّل جسر API الخاص عندما تحتاج إلى الإجراءات المتقدمة:
يتطلب
imsg launchتعطيل SIP. تعمل وظائف الإرسال الأساسي والسجل والمراقبة بدونimsg launch؛ أما الإجراءات المتقدمة فلا تعمل بدونه. -
بعد إضافة إعداد
channels.imessageمفعّل، تحقق من الجسر عبر OpenClaw:تحتاج إلىimessage.privateApi.available: true. إذا أبلغ عنfalse، فأصلح ذلك أولًا — راجع اكتشاف الإمكانات. لا يفحصchannels status --probeإلا الحسابات المهيأة والمفعّلة. -
خذ لقطة من إعدادك:
ترجمة الإعداد
تشترك iMessage وBlueBubbles في كثير من إعدادات مستوى القناة. المفاتيح التي تتغير هي في معظمها مفاتيح نقل (خادم REST مقابل CLI محلي). تحافظ مفاتيح السلوك (dmPolicy وgroupPolicy وallowFrom وما إلى ذلك) على المعنى نفسه.
| BlueBubbles | iMessage المضمّن | ملاحظات |
|---|---|---|
channels.bluebubbles.enabled | channels.imessage.enabled | الدلالات نفسها. |
channels.bluebubbles.serverUrl | (أزيل) | لا يوجد خادم REST؛ فالـ Plugin يشغّل imsg rpc عبر stdio. |
channels.bluebubbles.password | (أزيل) | لا حاجة إلى مصادقة Webhook. |
| (ضمني) | channels.imessage.cliPath | المسار إلى imsg (الافتراضي imsg)؛ استخدم سكربت غلاف لـ SSH. |
| (ضمني) | channels.imessage.dbPath | تجاوز اختياري لـ Messages.app chat.db؛ يُكتشف تلقائياً عند إغفاله. |
| (ضمني) | channels.imessage.remoteHost | host أو user@host؛ لا يلزم إلا عندما يكون cliPath غلاف SSH وتريد جلب مرفقات SCP. |
channels.bluebubbles.dmPolicy | channels.imessage.dmPolicy | القيم نفسها (pairing / allowlist / open / disabled). |
channels.bluebubbles.allowFrom | channels.imessage.allowFrom | تنتقل موافقات الاقتران حسب المعرف، لا حسب الرمز. |
channels.bluebubbles.groupPolicy | channels.imessage.groupPolicy | القيم نفسها (allowlist / open / disabled). |
channels.bluebubbles.groupAllowFrom | channels.imessage.groupAllowFrom | نفسه. |
channels.bluebubbles.groups | channels.imessage.groups | انسخ هذا حرفياً، بما في ذلك أي إدخال بدل groups: { "*": { ... } }. تنتقل إعدادات requireMention وtools وtoolsBySender لكل مجموعة. مع groupPolicy: "allowlist"، يؤدي غياب كتلة groups أو كونها فارغة إلى إسقاط كل رسالة مجموعة بصمت؛ راجع “مطب سجل المجموعات” أدناه. |
channels.bluebubbles.sendReadReceipts | channels.imessage.sendReadReceipts | الافتراضي true. مع الـ Plugin المضمّن، لا يعمل هذا إلا عندما يكون فحص API الخاص قيد التشغيل. |
channels.bluebubbles.includeAttachments | channels.imessage.includeAttachments | البنية نفسها، ومعطّل افتراضياً أيضاً. إذا كانت المرفقات تعمل لديك على BlueBubbles فيجب إعادة ضبط هذا صراحة في كتلة iMessage؛ فهو لا ينتقل ضمنياً، وستُسقط الصور/الوسائط الواردة بصمت من دون سطر سجل Inbound message إلى أن تفعل ذلك. |
channels.bluebubbles.attachmentRoots | channels.imessage.attachmentRoots | الجذور المحلية؛ قواعد البدل نفسها. |
| (غير منطبق) | channels.imessage.remoteAttachmentRoots | لا يُستخدم إلا عند ضبط remoteHost لجلب SCP. |
channels.bluebubbles.mediaMaxMb | channels.imessage.mediaMaxMb | الافتراضي 16 ميغابايت على iMessage (كان افتراضي BlueBubbles هو 8 ميغابايت). اضبطه صراحة إذا أردت الإبقاء على الحد الأدنى. |
channels.bluebubbles.textChunkLimit | channels.imessage.textChunkLimit | الافتراضي 4000 في كليهما. |
channels.bluebubbles.coalesceSameSenderDms | channels.imessage.coalesceSameSenderDms | نفس خيار التفعيل الصريح. لرسائل DM فقط؛ تحتفظ محادثات المجموعات بالإرسال الفوري لكل رسالة على القناتين. يوسّع مهلة إزالة الارتداد الافتراضية للوارد إلى 7000 مللي ثانية عند تفعيله من دون messages.inbound.byChannel.imessage صريح أو messages.inbound.debounceMs عام. راجع وثائق iMessage § تجميع رسائل DM المقسّمة الإرسال. |
channels.bluebubbles.enrichGroupParticipantsFromContacts | (غير منطبق) | يقرأ iMessage أسماء عرض المرسلين من chat.db مسبقاً. |
channels.bluebubbles.actions.* | channels.imessage.actions.* | مفاتيح تفعيل لكل إجراء: reactions وedit وunsend وreply وsendWithEffect وrenameGroup وsetGroupIcon وaddParticipant وremoveParticipant وleaveGroup وsendAttachment. |
channels.bluebubbles.accounts.*) واحداً لواحد إلى channels.imessage.accounts.*.
مطب سجل المجموعات
يشغّل Plugin iMessage المضمّن بوابتي قائمة سماح منفصلتين للمجموعات، الواحدة تلو الأخرى. يجب أن تنجح كلتاهما كي تصل رسالة المجموعة إلى الوكيل:- قائمة سماح المرسل / هدف المحادثة (
channels.imessage.groupAllowFrom) — يتحقق منهاisAllowedIMessageSender. تطابق الرسائل الواردة حسب معرف المرسل أوchat_guidأوchat_identifierأوchat_id. لها بنية BlueBubbles نفسها. - سجل المجموعات (
channels.imessage.groups) — يتحقق منهresolveChannelGroupPolicyمنinbound-processing.ts:199. معgroupPolicy: "allowlist"، تتطلب هذه البوابة أحد الأمرين:- إدخال بدل
groups: { "*": { ... } }(يضبطallowAll = true)، أو - إدخالاً صريحاً لكل
chat_idتحتgroups.
- إدخال بدل
warn كي لا يبقى هذا صامتاً عند مستوى السجل الافتراضي:
- تحذير بدء تشغيل
warnمرة واحدة لكل حساب عندما يكونgroupPolicy: "allowlist"مضبوطاً لكنchannels.imessage.groupsفارغ (لا يوجد بدل"*"ولا إدخالات لكلchat_id)؛ يُطلق قبل وصول أي رسائل. - تحذير
warnمرة واحدة لكلchat_idفي أول مرة تُسقط فيها مجموعة محددة وقت التشغيل، مع تسمية chat_id والمفتاح الدقيق المطلوب إضافته إلىgroupsللسماح بها.
groupAllowFrom وgroupPolicy لكن يتجاوزون كتلة groups، لأن groups: { "*": { "requireMention": true } } في BlueBubbles تبدو كإعداد إشارة غير ذي صلة. لكنها في الواقع ضرورية لبوابة السجل.
الحد الأدنى من الإعدادات اللازمة لإبقاء رسائل المجموعات متدفقة بعد groupPolicy: "allowlist":
requireMention: true ضمن * غير ضار عندما لا تكون أنماط الإشارة مضبوطة: يعيّن وقت التشغيل canDetectMention = false ويتجاوز إسقاط الإشارة عند inbound-processing.ts:512. وعند ضبط أنماط الإشارة (agents.list[].groupChat.mentionPatterns)، يعمل كما هو متوقع.
إذا سجّل Gateway الرسالة imessage: dropping group message from chat_id=<id> أو سطر بدء التشغيل imessage: groupPolicy="allowlist" but channels.imessage.groups is empty، فهذا يعني أن البوابة 2 تسقط الرسائل — أضف كتلة groups.
خطوة بخطوة
-
أضف كتلة iMessage إلى جانب كتلة BlueBubbles الحالية. أبقها معطلة ما دام Gateway لا يزال يوجّه حركة BlueBubbles:
-
اختبر قبل أن تصبح حركة الرسائل مهمة — أوقف Gateway، وفعّل كتلة iMessage مؤقتًا، وتأكد من أن iMessage يبلّغ عن حالة سليمة من CLI:
لا يفحص
channels status --probeإلا الحسابات المضبوطة والمفعلة. لا تُعد تشغيل Gateway مع تفعيل كل من BlueBubbles وiMessage إلا إذا كنت تقصد تشغيل مراقبي القناتين معًا. إذا لم تكن ستنتقل فورًا، فأعد ضبطchannels.imessage.enabledإلىfalseقبل إعادة تشغيل Gateway. استخدم أوامرimsgالمباشرة في قبل أن تبدأ للتحقق من Mac قبل تفعيل حركة OpenClaw. -
انتقل. بعد أن يبلّغ حساب iMessage المفعّل عن حالة سليمة، أزل إعدادات BlueBubbles وأبق iMessage مفعّلًا:
أعد تشغيل Gateway. ستتدفق حركة iMessage الواردة الآن عبر Plugin المضمّن.
- تحقق من الرسائل المباشرة. أرسل إلى الوكيل رسالة مباشرة؛ وتأكد من وصول الرد.
-
تحقق من المجموعات بشكل منفصل. الرسائل المباشرة والمجموعات تسلك مسارات برمجية مختلفة — نجاح الرسائل المباشرة لا يثبت أن المجموعات موجّهة. أرسل إلى الوكيل رسالة في دردشة جماعية مقترنة وتأكد من وصول الرد. إذا صمتت المجموعة (لا رد من الوكيل، ولا خطأ)، فتحقق من سجل Gateway بحثًا عن
imessage: dropping group message from chat_id=<id>أو سطر بدء التشغيلimessage: groupPolicy="allowlist" but channels.imessage.groups is empty— كلاهما يظهر عند مستوى السجل الافتراضي. إذا ظهر أي منهما، فكتلةgroupsمفقودة أو فارغة — راجع “فخ سجل المجموعات” أعلاه. -
تحقق من سطح الإجراءات — من رسالة مباشرة مقترنة، اطلب من الوكيل إضافة تفاعل، أو تعديل رسالة، أو إلغاء إرسالها، أو الرد عليها، أو إرسال صورة، و(في مجموعة) إعادة تسمية المجموعة / إضافة مشارك أو إزالته. يجب أن يظهر كل إجراء أصليًا في Messages.app. إذا ألقى أي إجراء الخطأ “iMessage
<action>requires the imsg private API bridge”، فشغّلimsg launchمرة أخرى وحدّثchannels status --probe. -
أزل خادم BlueBubbles وإعداداته بعد التحقق من رسائل iMessage المباشرة والمجموعات والإجراءات. لن يستخدم OpenClaw
channels.bluebubbles.
تكافؤ الإجراءات بنظرة سريعة
| الإجراء | BlueBubbles القديم | iMessage المضمّن |
|---|---|---|
| إرسال نص / احتياطي SMS | ✅ | ✅ |
| إرسال وسائط (صورة، فيديو، ملف، صوت) | ✅ | ✅ |
رد مترابط (reply_to_guid) | ✅ | ✅ (يغلق #51892) |
Tapback (react) | ✅ | ✅ |
| تعديل / إلغاء الإرسال (مستلمو macOS 13+) | ✅ | ✅ |
| إرسال مع تأثير شاشة | ✅ | ✅ (يغلق جزءًا من #9394) |
| نص غني عريض / مائل / مسطر / مشطوب | ✅ | ✅ (تنسيق typed-run عبر attributedBody) |
| إعادة تسمية المجموعة / تعيين أيقونة المجموعة | ✅ | ✅ |
| إضافة / إزالة مشارك، مغادرة المجموعة | ✅ | ✅ |
| إيصالات القراءة ومؤشر الكتابة | ✅ | ✅ (مقيّد بفحص API الخاص) |
| دمج الرسائل المباشرة من المرسل نفسه | ✅ | ✅ (للرسائل المباشرة فقط؛ تفعيل اختياري عبر channels.imessage.coalesceSameSenderDms) |
| الاسترداد الوارد بعد إعادة التشغيل | ✅ (إعادة تشغيل Webhook + جلب السجل) | ✅ (تلقائي: إعادة تشغيل الفائت عبر since_rowid + إزالة التكرار؛ نافذة أوسع محليًا) |
since_rowid في imsg watch.subscribe ويزيل التكرار حسب GUID، بينما يمنع حاجز عمر السجل القديم “قنبلة السجل” الناتجة عن Push-flush. يتم ذلك عبر اتصال RPC الخاص بـ imsg، لذلك يعمل أيضًا مع إعدادات cliPath عبر SSH عن بعد؛ وتحصل الإعدادات المحلية على نافذة استرداد أوسع لأنها تستطيع قراءة chat.db. راجع الاسترداد الوارد بعد إعادة تشغيل الجسر أو Gateway.
الاقتران والجلسات وارتباطات ACP
- موافقات الاقتران تنتقل حسب المعرف. لا تحتاج إلى إعادة الموافقة على المرسلين المعروفين — يتعرف
channels.imessage.allowFromعلى سلاسل+15555550123/user@example.comنفسها التي استخدمها BlueBubbles. - الجلسات تبقى محددة النطاق لكل وكيل + دردشة. تُدمج الرسائل المباشرة في الجلسة الرئيسية للوكيل وفق الإعداد الافتراضي
session.dmScope=main؛ وتبقى جلسات المجموعات معزولة لكلchat_id. تختلف مفاتيح الجلسات (agent:<id>:imessage:group:<chat_id>مقابل مكافئ BlueBubbles) — لا ينتقل سجل المحادثات القديم ضمن مفاتيح جلسات BlueBubbles إلى جلسات iMessage. - ارتباطات ACP التي تشير إلى
match.channel: "bluebubbles"يجب تحديثها إلى"imessage". أشكالmatch.peer.id(chat_id:، وchat_guid:، وchat_identifier:، والمعرف المجرد) متطابقة.
لا قناة رجوع
لا يوجد وقت تشغيل BlueBubbles مدعوم للرجوع إليه. إذا فشل التحقق من iMessage، فاضبطchannels.imessage.enabled: false، وأعد تشغيل Gateway، وأصلح عائق imsg، ثم أعد محاولة الانتقال.
توجد ذاكرة التخزين المؤقت للردود في حالة Plugin ضمن SQLite. يستورد openclaw doctor --fix ملف imessage/reply-cache.jsonl الجانبي القديم ويؤرشفه عند وجوده.
ذات صلة
- إزالة BlueBubbles ومسار imsg iMessage — إعلان قصير وملخص للمشغّلين.
- iMessage — مرجع قناة iMessage الكامل، بما في ذلك إعداد
imsg launchواكتشاف القدرات. /channels/bluebubbles— عنوان URL قديم يعيد التوجيه إلى دليل الترحيل هذا.- الاقتران — مصادقة الرسائل المباشرة وتدفق الاقتران.
- توجيه القنوات — كيف يختار Gateway قناة للردود الصادرة.