Mainstream messaging

BlueBubbles

الحالة: Plugin قديم مضمّن يتواصل مع خادم BlueBubbles على macOS عبر HTTP. تستمر إعدادات BlueBubbles الحالية في العمل، لكن عمليات نشر OpenClaw iMessage الجديدة يجب أن تفضّل Plugin iMessage الأصلي عندما تناسب متطلباته مضيفك.

نظرة عامة

  • يعمل على macOS عبر تطبيق BlueBubbles المساعد (bluebubbles.app).
  • بديل قديم للمنشآت التي تعتمد بالفعل على معرّفات قناة BlueBubbles، أو حالة Webhook، أو أهداف المجموعات، أو تسليم cron، أو توجيه مساحة العمل.
  • موصى به/مختبر: macOS Sequoia (15). يعمل macOS Tahoe (26)؛ التحرير معطّل حاليًا على Tahoe، وقد تُبلغ تحديثات أيقونة المجموعة عن النجاح لكنها لا تتزامن.
  • يتواصل OpenClaw معه عبر REST API الخاصة به (GET /api/v1/ping، POST /message/text، POST /chat/:id/*).
  • تصل الرسائل الواردة عبر webhooks؛ أما الردود الصادرة، ومؤشرات الكتابة، وإيصالات القراءة، وtapbacks فهي استدعاءات REST.
  • تُستوعب المرفقات والملصقات كوسائط واردة (وتُعرض للوكيل عند الإمكان).
  • تُسلَّم ردود Auto-TTS التي تُنشئ صوت MP3 أو CAF كفقاعات مذكرة صوتية في iMessage بدلًا من مرفقات ملفات عادية.
  • تعمل الاقتران/قائمة السماح بالطريقة نفسها مثل القنوات الأخرى (/channels/pairing وما إلى ذلك) مع channels.bluebubbles.allowFrom + رموز الاقتران.
  • تُعرض التفاعلات كأحداث نظام تمامًا مثل Slack/Telegram حتى يتمكن الوكلاء من "ذكرها" قبل الرد.
  • الميزات المتقدمة: التحرير، إلغاء الإرسال، ترابط الردود، تأثيرات الرسائل، إدارة المجموعات.

البدء السريع

  • Install BlueBubbles

    ثبّت خادم BlueBubbles على جهاز Mac الخاص بك (اتبع التعليمات في bluebubbles.app/install).

  • Enable the web API

    في إعدادات BlueBubbles، فعّل web API واضبط كلمة مرور.

  • Configure OpenClaw

    شغّل openclaw onboard وحدد BlueBubbles، أو اضبطه يدويًا:

    {
      channels: {
        bluebubbles: {
          enabled: true,
          serverUrl: "http://192.168.1.100:1234",
          password: "example-password",
          webhookPath: "/bluebubbles-webhook",
        },
      },
    }
    
  • Point webhooks at the gateway

    وجّه webhooks الخاصة بـ BlueBubbles إلى Gateway لديك (مثال: https://your-gateway-host:3000/bluebubbles-webhook?password=<password>).

  • Start the gateway

    ابدأ Gateway؛ سيسجّل معالج Webhook ويبدأ الاقتران.

  • إبقاء Messages.app نشطًا (إعدادات VM / بلا واجهة)

    قد تنتهي بعض إعدادات macOS VM / الدائمة التشغيل إلى دخول Messages.app في حالة "خمول" (تتوقف الأحداث الواردة حتى يُفتح التطبيق/يُجلب إلى المقدمة). الحل البسيط هو تنبيه Messages كل 5 دقائق باستخدام AppleScript + LaunchAgent.

  • Save the AppleScript

    احفظ هذا باسم ~/Scripts/poke-messages.scpt:

    try
      tell application "Messages"
        if not running then
          launch
        end if
    
        -- Touch the scripting interface to keep the process responsive.
        set _chatCount to (count of chats)
      end tell
    on error
      -- Ignore transient failures (first-run prompts, locked session, etc).
    end try
    
  • Install a LaunchAgent

    احفظ هذا باسم ~/Library/LaunchAgents/com.user.poke-messages.plist:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
      <dict>
        <key>Label</key>
        <string>com.user.poke-messages</string>
    
        <key>ProgramArguments</key>
        <array>
          <string>/bin/bash</string>
          <string>-lc</string>
          <string>/usr/bin/osascript &quot;$HOME/Scripts/poke-messages.scpt&quot;</string>
        </array>
    
        <key>RunAtLoad</key>
        <true/>
    
        <key>StartInterval</key>
        <integer>300</integer>
    
        <key>StandardOutPath</key>
        <string>/tmp/poke-messages.log</string>
        <key>StandardErrorPath</key>
        <string>/tmp/poke-messages.err</string>
      </dict>
    </plist>
    

    يعمل هذا كل 300 ثانية وعند تسجيل الدخول. قد يؤدي التشغيل الأول إلى ظهور مطالبات Automation في macOS (osascript → Messages). وافق عليها في جلسة المستخدم نفسها التي تشغّل LaunchAgent.

  • Load it

    launchctl unload ~/Library/LaunchAgents/com.user.poke-messages.plist 2>/dev/null || true
    launchctl load ~/Library/LaunchAgents/com.user.poke-messages.plist
    
  • الإعداد الأولي

    يتوفر BlueBubbles في الإعداد الأولي التفاعلي:

    openclaw onboard
    

    يطالبك المعالج بما يلي:

    Server URLstringrequired

    عنوان خادم BlueBubbles (مثل http://192.168.1.100:1234).

    Passwordstringrequired

    كلمة مرور API من إعدادات خادم BlueBubbles.

    Webhook pathstring

    مسار نقطة نهاية Webhook.

    DM policystring

    pairing، أو allowlist، أو open، أو disabled.

    Allow liststring[]

    أرقام الهواتف، أو عناوين البريد الإلكتروني، أو أهداف الدردشة.

    يمكنك أيضًا إضافة BlueBubbles عبر CLI:

    openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --password <password>
    

    التحكم في الوصول (الرسائل المباشرة + المجموعات)

    DMs

    • الافتراضي: channels.bluebubbles.dmPolicy = "pairing".
    • يتلقى المرسلون غير المعروفين رمز اقتران؛ ويتم تجاهل الرسائل حتى الموافقة (تنتهي صلاحية الرموز بعد ساعة واحدة).
    • الموافقة عبر:
      • openclaw pairing list bluebubbles
      • openclaw pairing approve bluebubbles &lt;CODE&gt;
    • الاقتران هو تبادل الرمز الافتراضي. التفاصيل: الاقتران

    Groups

    • channels.bluebubbles.groupPolicy = open | allowlist | disabled (الافتراضي: allowlist).
    • يتحكم channels.bluebubbles.groupAllowFrom في من يمكنه التحفيز داخل المجموعات عند ضبط allowlist.

    إثراء أسماء جهات الاتصال (macOS، اختياري)

    غالبًا ما تتضمن webhooks الخاصة بمجموعات BlueBubbles عناوين المشاركين الخام فقط. إذا كنت تريد أن يعرض سياق GroupMembers أسماء جهات الاتصال المحلية بدلًا من ذلك، فيمكنك الاشتراك في إثراء جهات الاتصال المحلية على macOS:

    • يفعّل channels.bluebubbles.enrichGroupParticipantsFromContacts = true البحث. الافتراضي: false.
    • لا تعمل عمليات البحث إلا بعد أن تسمح صلاحية الوصول إلى المجموعة، وتفويض الأوامر، وبوابة الذكر بمرور الرسالة.
    • يُثري المشاركون ذوو أرقام الهاتف غير المسماة فقط.
    • تبقى أرقام الهاتف الخام كبديل احتياطي عند عدم العثور على تطابق محلي.
    {
      channels: {
        bluebubbles: {
          enrichGroupParticipantsFromContacts: true,
        },
      },
    }
    

    بوابة الذكر (المجموعات)

    يدعم BlueBubbles بوابة الذكر لدردشات المجموعات، بما يطابق سلوك iMessage/WhatsApp:

    • يستخدم agents.list[].groupChat.mentionPatterns (أو messages.groupChat.mentionPatterns) لاكتشاف الإشارات.
    • عند تفعيل requireMention لمجموعة، لا يرد الوكيل إلا عند ذكره.
    • تتجاوز أوامر التحكم من المرسلين المصرح لهم بوابة الذكر.

    إعداد كل مجموعة:

    {
      channels: {
        bluebubbles: {
          groupPolicy: "allowlist",
          groupAllowFrom: ["+15555550123"],
          groups: {
            "*": { requireMention: true }, // default for all groups
            "iMessage;-;chat123": { requireMention: false }, // override for specific group
          },
        },
      },
    }
    

    بوابة الأوامر

    • تتطلب أوامر التحكم (مثل /config و/model) تفويضًا.
    • يستخدم allowFrom وgroupAllowFrom لتحديد تفويض الأوامر.
    • يمكن للمرسلين المصرح لهم تشغيل أوامر التحكم حتى من دون ذكر في المجموعات.

    موجّه النظام لكل مجموعة

    يقبل كل إدخال ضمن channels.bluebubbles.groups.* سلسلة systemPrompt اختيارية. تُحقن القيمة في موجّه نظام الوكيل في كل دورة تتعامل مع رسالة في تلك المجموعة، بحيث يمكنك ضبط شخصية أو قواعد سلوكية لكل مجموعة من دون تعديل موجّهات الوكيل:

    {
      channels: {
        bluebubbles: {
          groups: {
            "iMessage;-;chat123": {
              systemPrompt: "Keep responses under 3 sentences. Mirror the group's casual tone.",
            },
          },
        },
      },
    }
    

    يطابق المفتاح ما يبلّغ عنه BlueBubbles كـ chatGuid / chatIdentifier / chatId رقمي للمجموعة، ويوفر إدخال حرف البدل "*" إعدادًا افتراضيًا لكل مجموعة من دون تطابق دقيق (النمط نفسه المستخدم بواسطة requireMention وسياسات الأدوات لكل مجموعة). تنتصر المطابقات الدقيقة دائمًا على حرف البدل. تتجاهل الرسائل المباشرة هذا الحقل؛ استخدم تخصيص الموجّه على مستوى الوكيل أو الحساب بدلًا من ذلك.

    مثال عملي: الردود المترابطة وتفاعلات tapback (API خاصة)

    مع تفعيل API الخاصة في BlueBubbles، تصل الرسائل الواردة مع معرّفات رسائل قصيرة (مثل [[reply_to:5]]) ويمكن للوكيل استدعاء action=reply للترابط مع رسالة محددة أو action=react لإسقاط tapback. تُعد systemPrompt لكل مجموعة طريقة موثوقة لإبقاء الوكيل يختار الأداة الصحيحة:

    {
      channels: {
        bluebubbles: {
          groups: {
            "iMessage;+;chat-family": {
              systemPrompt: "When replying in this group, always call action=reply with the [[reply_to:N]] messageId from context so your response threads under the triggering message. Never send a new unlinked message. For short acknowledgements ('ok', 'got it', 'on it'), use action=react with an appropriate tapback emoji (❤️, 👍, 😂, ‼️, ❓) instead of sending a text reply.",
            },
          },
        },
      },
    }
    

    تتطلب كل من تفاعلات tapback والردود المترابطة API الخاصة في BlueBubbles؛ راجع الإجراءات المتقدمة ومعرّفات الرسائل للآليات الأساسية.

    ارتباطات محادثات ACP

    يمكن تحويل دردشات BlueBubbles إلى مساحات عمل ACP مستمرة من دون تغيير طبقة النقل.

    تدفق المشغّل السريع:

    • شغّل /acp spawn codex --bind here داخل الرسالة المباشرة أو دردشة المجموعة المسموح بها.
    • تُوجّه الرسائل المستقبلية في محادثة BlueBubbles نفسها إلى جلسة ACP المنشأة.
    • يعيد /new و/reset ضبط جلسة ACP المرتبطة نفسها في مكانها.
    • يغلق /acp close جلسة ACP ويزيل الارتباط.

    تُدعم أيضًا الارتباطات المستمرة المضبوطة عبر إدخالات bindings[] في المستوى الأعلى مع type: "acp" وmatch.channel: "bluebubbles".

    يمكن لـ match.peer.id استخدام أي صيغة هدف BlueBubbles مدعومة:

    • معرّف DM مُطبّع مثل +15555550123 أو [email protected]
    • chat_id:<id>
    • chat_guid:<guid>
    • chat_identifier:<identifier>

    لربط المجموعات بشكل مستقر، فضّل chat_id:* أو chat_identifier:*.

    مثال:

    {
      agents: {
        list: [
          {
            id: "codex",
            runtime: {
              type: "acp",
              acp: { agent: "codex", backend: "acpx", mode: "persistent" },
            },
          },
        ],
      },
      bindings: [
        {
          type: "acp",
          agentId: "codex",
          match: {
            channel: "bluebubbles",
            accountId: "default",
            peer: { kind: "dm", id: "+15555550123" },
          },
          acp: { label: "codex-imessage" },
        },
      ],
    }
    

    راجع وكلاء ACP لمعرفة سلوك ربط ACP المشترك.

    مؤشرات الكتابة + إيصالات القراءة

    • مؤشرات الكتابة: تُرسل تلقائيًا قبل إنشاء الرد وأثناءه.
    • إيصالات القراءة: يتحكم بها channels.bluebubbles.sendReadReceipts (الافتراضي: true).
    • مؤشرات الكتابة: يرسل OpenClaw أحداث بدء الكتابة؛ ويمسح BlueBubbles حالة الكتابة تلقائيًا عند الإرسال أو انتهاء المهلة (الإيقاف اليدوي عبر DELETE غير موثوق).
    {
      channels: {
        bluebubbles: {
          sendReadReceipts: false, // disable read receipts
        },
      },
    }
    

    إجراءات متقدمة

    يدعم BlueBubbles إجراءات رسائل متقدمة عند تفعيلها في الإعدادات:

    {
      channels: {
        bluebubbles: {
          actions: {
            reactions: true, // tapbacks (default: true)
            edit: true, // edit sent messages (macOS 13+, broken on macOS 26 Tahoe)
            unsend: true, // unsend messages (macOS 13+)
            reply: true, // reply threading by message GUID
            sendWithEffect: true, // message effects (slam, loud, etc.)
            renameGroup: true, // rename group chats
            setGroupIcon: true, // set group chat icon/photo (flaky on macOS 26 Tahoe)
            addParticipant: true, // add participants to groups
            removeParticipant: true, // remove participants from groups
            leaveGroup: true, // leave group chats
            sendAttachment: true, // send attachments/media
          },
        },
      },
    }
    
    Available actions
    • react: إضافة/إزالة تفاعلات tapback (messageId، emoji، remove). مجموعة tapback الأصلية في iMessage هي love وlike وdislike وlaugh وemphasize وquestion. عندما يختار الوكيل رمزًا تعبيريًا خارج تلك المجموعة (مثل 👀)، تعود أداة التفاعل إلى love بحيث يظل tapback يظهر بدلًا من فشل الطلب بالكامل. تظل تفاعلات الإقرار المكوّنة تتحقق بصرامة وتُرجع خطأ عند القيم غير المعروفة.
    • edit: تحرير رسالة مُرسلة (messageId، text).
    • unsend: إلغاء إرسال رسالة (messageId).
    • reply: الرد على رسالة محددة (messageId، text، to).
    • sendWithEffect: الإرسال مع تأثير iMessage (text، to، effectId).
    • renameGroup: إعادة تسمية دردشة جماعية (chatGuid، displayName).
    • setGroupIcon: تعيين أيقونة/صورة دردشة جماعية (chatGuid، media) - غير مستقر على macOS 26 Tahoe (قد تُرجع API نجاحًا لكن الأيقونة لا تتزامن).
    • addParticipant: إضافة شخص إلى مجموعة (chatGuid، address).
    • removeParticipant: إزالة شخص من مجموعة (chatGuid، address).
    • leaveGroup: مغادرة دردشة جماعية (chatGuid).
    • upload-file: إرسال وسائط/ملفات (to، buffer، filename، asVoice).
      • المذكرات الصوتية: عيّن asVoice: true مع صوت MP3 أو CAF للإرسال كرسالة صوتية في iMessage. يحوّل BlueBubbles ‏MP3 → CAF عند إرسال المذكرات الصوتية.
    • الاسم المستعار القديم: لا يزال sendAttachment يعمل، لكن upload-file هو اسم الإجراء القياسي.

    معرّفات الرسائل (قصيرة مقابل كاملة)

    قد يعرض OpenClaw معرّفات رسائل قصيرة (مثل 1 و2) لتوفير الرموز.

    • يمكن أن تكون MessageSid / ReplyToId معرّفات قصيرة.
    • تحتوي MessageSidFull / ReplyToIdFull على المعرّفات الكاملة للمزوّد.
    • المعرّفات القصيرة موجودة في الذاكرة؛ وقد تنتهي صلاحيتها عند إعادة التشغيل أو إخلاء ذاكرة التخزين المؤقت.
    • تقبل الإجراءات messageId قصيرًا أو كاملًا، لكن المعرّفات القصيرة ستُرجع خطأ إذا لم تعد متاحة.

    استخدم المعرّفات الكاملة للأتمتة والتخزين الدائمين:

    • القوالب: {{MessageSidFull}}، {{ReplyToIdFull}}
    • السياق: MessageSidFull / ReplyToIdFull في الحمولات الواردة

    راجع الإعدادات لمتغيرات القوالب.

    دمج رسائل DM ذات الإرسال المقسّم (أمر + URL في إنشاء واحد)

    عندما يكتب مستخدم أمرًا وURL معًا في iMessage - مثل Dump https://example.com/article - تقسم Apple الإرسال إلى تسليمين منفصلين عبر Webhook:

    1. رسالة نصية ("Dump").
    2. فقاعة معاينة URL ("https://...") مع صور معاينة OG كمرفقات.

    يصل Webhookان إلى OpenClaw بفاصل يقارب 0.8-2.0 ثانية في معظم الإعدادات. بدون الدمج، يتلقى الوكيل الأمر وحده في الدور 1، ويرد (غالبًا "أرسل لي URL")، ولا يرى URL إلا في الدور 2 - وعندها يكون سياق الأمر قد فُقد بالفعل.

    يُدخل channels.bluebubbles.coalesceSameSenderDms رسالة DM في دمج Webhooks المتتالية من المرسل نفسه في دور وكيل واحد. تستمر الدردشات الجماعية في استخدام مفتاح لكل رسالة للحفاظ على بنية الأدوار متعددة المستخدمين.

    When to enable

    فعّل عندما:

    • ترسل Skills تتوقع command + payload في رسالة واحدة (dump، paste، save، queue، إلخ).
    • يلصق مستخدموك عناوين URL أو صورًا أو محتوى طويلًا بجانب الأوامر.
    • يمكنك قبول زمن انتقال دور DM الإضافي (انظر أدناه).

    اتركه معطلًا عندما:

    • تحتاج إلى أقل زمن انتقال للأوامر لمحفزات DM ذات الكلمة الواحدة.
    • تكون كل تدفقاتك أوامر لمرة واحدة بدون متابعات حمولة.

    Enabling

    {
      channels: {
        bluebubbles: {
          coalesceSameSenderDms: true, // opt in (default: false)
        },
      },
    }
    

    عند تشغيل العلامة وعدم وجود messages.inbound.byChannel.bluebubbles صريح، تتسع نافذة إزالة الاهتزاز إلى 2500 ms (الافتراضي لعدم الدمج هو 500 ms). النافذة الأوسع مطلوبة - إيقاع الإرسال المقسّم من Apple البالغ 0.8-2.0 ثانية لا يناسب الافتراضي الأضيق.

    لضبط النافذة بنفسك:

    {
      messages: {
        inbound: {
          byChannel: {
            // 2500 ms works for most setups; raise to 4000 ms if your Mac is slow
            // or under memory pressure (observed gap can stretch past 2 s then).
            bluebubbles: 2500,
          },
        },
      },
    }
    

    Trade-offs

    • زمن انتقال إضافي لأوامر التحكم في DM. عند تشغيل العلامة، تنتظر رسائل أوامر التحكم في DM (مثل Dump وSave وما إلى ذلك) الآن حتى نافذة إزالة الاهتزاز قبل الإرسال، لاحتمال وصول Webhook حمولة. تحافظ أوامر الدردشة الجماعية على الإرسال الفوري.
    • المخرجات المدمجة محدودة - يُحدد النص المدمج عند 4000 حرف مع علامة …[truncated] صريحة؛ وتُحدد المرفقات عند 20؛ وتُحدد إدخالات المصدر عند 10 (مع الاحتفاظ بالأول والأحدث بعد ذلك). لا يزال كل messageId مصدر يصل إلى إزالة التكرار الوارد، لذا يُتعرّف على إعادة تشغيل لاحقة من MessagePoller لأي حدث فردي كتكرار.
    • اختياري، لكل قناة. القنوات الأخرى (Telegram وWhatsApp وSlack و…) غير متأثرة.

    السيناريوهات وما يراه الوكيل

    ما ينشئه المستخدم ما تسلّمه Apple العلامة معطلة (افتراضي) العلامة مفعلة + نافذة 2500 ms
    Dump https://example.com (إرسال واحد) 2 Webhooks بفاصل ~1 s دوران للوكيل: "Dump" وحده، ثم URL دور واحد: نص مدمج Dump https://example.com
    Save this 📎image.jpg caption (مرفق + نص) 2 Webhooks دوران دور واحد: نص + صورة
    /status (أمر مستقل) 1 Webhook إرسال فوري انتظار حتى النافذة، ثم إرسال
    URL ملصق وحده 1 Webhook إرسال فوري إرسال فوري (إدخال واحد فقط في الحاوية)
    نص + URL مُرسلان كرسالتين منفصلتين متعمدتين، بينهما دقائق 2 Webhooks خارج النافذة دوران دوران (تنتهي النافذة بينهما)
    تدفق سريع (>10 رسائل DM صغيرة داخل النافذة) N Webhooks N أدوار دور واحد، مخرجات محدودة (الأول + الأحدث، مع تطبيق حدود النص/المرفقات)

    استكشاف أخطاء دمج الإرسال المقسّم وإصلاحها

    إذا كانت العلامة مفعلة وما زالت الإرسالات المقسّمة تصل كدورين، فتحقق من كل طبقة:

    Config actually loaded
    grep coalesceSameSenderDms ~/.openclaw/openclaw.json
    

    ثم openclaw gateway restart - تُقرأ العلامة عند إنشاء سجل مزيل الاهتزاز.

    Debounce window wide enough for your setup

    انظر إلى سجل خادم BlueBubbles ضمن ~/Library/Logs/bluebubbles-server/main.log:

    grep -E "Dispatching event to webhook" main.log | tail -20
    

    قِس الفجوة بين إرسال النص بأسلوب "Dump" وإرسال "https://..."; Attachments: الذي يليه. ارفع messages.inbound.byChannel.bluebubbles ليغطي تلك الفجوة بشكل مريح.

    Session JSONL timestamps ≠ webhook arrival

    تعكس طوابع أحداث الجلسة الزمنية (~/.openclaw/agents/<id>/sessions/*.jsonl) وقت تسليم Gateway للرسالة إلى الوكيل، وليس وقت وصول Webhook. تعني الرسالة الثانية الموضوعة في قائمة الانتظار والموسومة [Queued messages while agent was busy] أن الدور الأول كان لا يزال قيد التشغيل عندما وصل Webhook الثاني - وكانت حاوية الدمج قد أُفرغت بالفعل. اضبط النافذة وفق سجل خادم BB، وليس سجل الجلسة.

    Memory pressure slowing reply dispatch

    على الأجهزة الأصغر (8 GB)، قد تستغرق أدوار الوكيل وقتًا طويلًا بما يكفي لتُفرغ حاوية الدمج قبل اكتمال الرد، ويصل URL كدور ثانٍ في قائمة الانتظار. تحقق من memory_pressure وps -o rss -p $(pgrep openclaw-gateway)؛ إذا كان Gateway يتجاوز ~500 MB RSS وكان الضاغط نشطًا، فأغلق العمليات الثقيلة الأخرى أو انتقل إلى مضيف أكبر.

    Reply-quote sends are a different path

    إذا نقر المستخدم على Dump كـ رد على فقاعة URL موجودة (يعرض iMessage شارة "1 Reply" على فقاعة Dump)، فإن URL موجود في replyToBody، وليس في Webhook ثانٍ. لا ينطبق الدمج - فهذا شأن Skill/المطالبة، وليس شأن مزيل الاهتزاز.

    بث الكتل

    تحكم فيما إذا كانت الردود تُرسل كرسالة واحدة أو تُبث في كتل:

    {
      channels: {
        bluebubbles: {
          blockStreaming: true, // enable block streaming (off by default)
        },
      },
    }
    

    الوسائط + الحدود

    • تُنزّل المرفقات الواردة وتُخزن في ذاكرة التخزين المؤقت للوسائط.
    • حد الوسائط عبر channels.bluebubbles.mediaMaxMb للوسائط الواردة والصادرة (الافتراضي: 8 MB).
    • يُقسّم النص الصادر إلى channels.bluebubbles.textChunkLimit (الافتراضي: 4000 حرف).

    مرجع الإعدادات

    الإعدادات الكاملة: الإعدادات

    الاتصال وWebhook
    • channels.bluebubbles.enabled: تفعيل/تعطيل القناة.
    • channels.bluebubbles.serverUrl: عنوان URL الأساسي لواجهة BlueBubbles REST API.
    • channels.bluebubbles.password: كلمة مرور API.
    • channels.bluebubbles.webhookPath: مسار نقطة نهاية Webhook (الافتراضي: /bluebubbles-webhook).
    سياسة الوصول
    • channels.bluebubbles.dmPolicy: pairing | allowlist | open | disabled (الافتراضي: pairing).
    • channels.bluebubbles.allowFrom: قائمة سماح للرسائل المباشرة (المعرّفات، رسائل البريد الإلكتروني، أرقام E.164، وchat_id:*، وchat_guid:*).
    • channels.bluebubbles.groupPolicy: open | allowlist | disabled (الافتراضي: allowlist).
    • channels.bluebubbles.groupAllowFrom: قائمة سماح لمرسلي المجموعات.
    • channels.bluebubbles.enrichGroupParticipantsFromContacts: على macOS، يمكنك اختيارياً إثراء المشاركين غير المسمّين في المجموعة من جهات الاتصال المحلية بعد اجتياز التحقق. الافتراضي: false.
    • channels.bluebubbles.groups: إعداد لكل مجموعة (requireMention، إلخ).
    التسليم والتقسيم
    • channels.bluebubbles.sendReadReceipts: إرسال إيصالات القراءة (الافتراضي: true).
    • channels.bluebubbles.blockStreaming: تفعيل بث الكتل (الافتراضي: false؛ مطلوب للردود المتدفقة).
    • channels.bluebubbles.textChunkLimit: حجم المقطع الصادر بعدد الأحرف (الافتراضي: 4000).
    • channels.bluebubbles.sendTimeoutMs: مهلة كل طلب بالمللي ثانية لإرسال النصوص الصادرة عبر /api/v1/message/text (الافتراضي: 30000). ارفعها على إعدادات macOS 26 التي قد تتوقف فيها عمليات إرسال iMessage عبر Private API لمدة تتجاوز 60 ثانية داخل إطار عمل iMessage؛ على سبيل المثال 45000 أو 60000. تبقي المجسّات، وعمليات البحث عن الدردشات، والتفاعلات، والتعديلات، وفحوصات الصحة حالياً على الافتراضي الأقصر البالغ 10 ثوانٍ؛ ومن المخطط توسيع التغطية لتشمل التفاعلات والتعديلات كمتابعة لاحقة. تجاوز لكل حساب: channels.bluebubbles.accounts.<accountId>.sendTimeoutMs.
    • channels.bluebubbles.chunkMode: length (الافتراضي) يقسّم فقط عند تجاوز textChunkLimit؛ أما newline فيقسّم عند الأسطر الفارغة (حدود الفقرات) قبل التقسيم حسب الطول.
    الوسائط والسجل
    • channels.bluebubbles.mediaMaxMb: حد الوسائط الواردة/الصادرة بالميغابايت (الافتراضي: 8).
    • channels.bluebubbles.mediaLocalRoots: قائمة سماح صريحة للأدلة المحلية المطلقة المسموح بها لمسارات الوسائط المحلية الصادرة. يتم رفض إرسال المسارات المحلية افتراضياً ما لم يتم تكوين هذا. تجاوز لكل حساب: channels.bluebubbles.accounts.<accountId>.mediaLocalRoots.
    • channels.bluebubbles.coalesceSameSenderDms: دمج Webhook الرسائل المباشرة المتتالية من المرسل نفسه في دورة وكيل واحدة حتى يصل إرسال Apple المقسّم للنص+URL كرسالة واحدة (الافتراضي: false). راجع دمج الرسائل المباشرة المقسّمة للاطلاع على السيناريوهات وضبط النافذة والمفاضلات. يوسّع نافذة إزالة الارتداد الافتراضية للوارد من 500 مللي ثانية إلى 2500 مللي ثانية عند تفعيله بدون messages.inbound.byChannel.bluebubbles صريح.
    • channels.bluebubbles.historyLimit: الحد الأقصى لرسائل المجموعة للسياق (0 يعطّلها).
    • channels.bluebubbles.dmHistoryLimit: حد سجل الرسائل المباشرة.
    • channels.bluebubbles.replyContextApiFallback: عندما يصل رد وارد بدون replyToBody/replyToSender وتفشل ذاكرة التخزين المؤقت لسياق الرد داخل الذاكرة، اجلب الرسالة الأصلية من BlueBubbles HTTP API كخيار احتياطي بأفضل جهد (الافتراضي: false). مفيد لعمليات النشر متعددة النسخ التي تشترك في حساب BlueBubbles واحد، أو بعد إعادة تشغيل العملية، أو بعد إخلاء ذاكرة التخزين المؤقت طويلة العمر TTL/LRU. يخضع الجلب لحماية SSRF بالسياسة نفسها المطبقة على كل طلب عميل BlueBubbles آخر، ولا يرمي أخطاء أبداً، ويملأ ذاكرة التخزين المؤقت حتى تُستهلك الردود اللاحقة بكلفة موزعة. تجاوز لكل حساب: channels.bluebubbles.accounts.<accountId>.replyContextApiFallback. ينتشر إعداد مستوى القناة إلى الحسابات التي تحذف العلامة.
    الإجراءات والحسابات
    • channels.bluebubbles.actions: تفعيل/تعطيل إجراءات محددة.
    • channels.bluebubbles.accounts: تكوين متعدد الحسابات.

    الخيارات العامة ذات الصلة:

    • agents.list[].groupChat.mentionPatterns (أو messages.groupChat.mentionPatterns).
    • messages.responsePrefix.

    العنونة / أهداف التسليم

    فضّل chat_guid للتوجيه المستقر:

    • chat_guid:iMessage;-;+15555550123 (مفضل للمجموعات)
    • chat_id:123
    • chat_identifier:...
    • المعرّفات المباشرة: +15555550123، [email protected]
      • إذا لم يكن لدى المعرّف المباشر دردشة رسائل مباشرة موجودة، فسينشئ OpenClaw واحدة عبر POST /api/v1/chat/new. يتطلب هذا تفعيل BlueBubbles Private API.

    توجيه iMessage مقابل SMS

    عندما يكون للمعرّف نفسه دردشة iMessage ودردشة SMS على Mac (على سبيل المثال رقم هاتف مسجّل في iMessage لكنه تلقى أيضاً بدائل الفقاعة الخضراء)، يفضّل OpenClaw دردشة iMessage ولا يخفّض أبداً إلى SMS بصمت. لفرض دردشة SMS، استخدم بادئة هدف صريحة sms: (على سبيل المثال sms:+15555550123). تستمر المعرّفات التي لا تملك دردشة iMessage مطابقة في الإرسال عبر أي دردشة يبلّغ عنها BlueBubbles.

    الأمان

    • تتم مصادقة طلبات Webhook بمقارنة معاملات الاستعلام أو الرؤوس guid/password مع channels.bluebubbles.password.
    • أبقِ كلمة مرور API ونقطة نهاية Webhook سرّيتين (تعامل معهما كبيانات اعتماد).
    • لا يوجد تجاوز للمضيف المحلي لمصادقة BlueBubbles Webhook. إذا كنت تمرّر حركة Webhook عبر وكيل، فأبقِ كلمة مرور BlueBubbles على الطلب من طرف إلى طرف. لا يحل gateway.trustedProxies محل channels.bluebubbles.password هنا. راجع أمان Gateway.
    • فعّل HTTPS + قواعد جدار الحماية على خادم BlueBubbles إذا كنت تعرضه خارج شبكتك المحلية.

    استكشاف الأخطاء وإصلاحها

    • إذا توقفت أحداث الكتابة/القراءة عن العمل، فتحقق من سجلات BlueBubbles Webhook وتأكد من أن مسار Gateway يطابق channels.bluebubbles.webhookPath.
    • تنتهي صلاحية رموز الاقتران بعد ساعة واحدة؛ استخدم openclaw pairing list bluebubbles وopenclaw pairing approve bluebubbles <code>.
    • تتطلب التفاعلات BlueBubbles private API (POST /api/v1/message/react)؛ تأكد من أن إصدار الخادم يوفّرها.
    • يتطلب التعديل/إلغاء الإرسال macOS 13+ وإصدار خادم BlueBubbles متوافقاً. على macOS 26 (Tahoe)، التعديل معطل حالياً بسبب تغييرات private API.
    • قد تكون تحديثات أيقونة المجموعة غير مستقرة على macOS 26 (Tahoe): قد تعيد API نجاحاً لكن الأيقونة الجديدة لا تتم مزامنتها.
    • يخفي OpenClaw تلقائياً الإجراءات المعروفة بأنها معطلة بناءً على إصدار macOS في خادم BlueBubbles. إذا ظل التعديل ظاهراً على macOS 26 (Tahoe)، فعطّله يدوياً باستخدام channels.bluebubbles.actions.edit=false.
    • تم تفعيل coalesceSameSenderDms لكن الإرسالات المقسّمة (مثل Dump + URL) ما زالت تصل كدورتين: راجع قائمة تحقق استكشاف أخطاء دمج الإرسال المقسّم وإصلاحها - الأسباب الشائعة هي نافذة إزالة ارتداد ضيقة جداً، أو إساءة قراءة الطوابع الزمنية لسجل الجلسة كوقت وصول Webhook، أو إرسال اقتباس رد (الذي يستخدم replyToBody، وليس Webhook ثانياً).
    • لمعلومات الحالة/الصحة: openclaw status --all أو openclaw status --deep.

    للاطلاع على مرجع عام لسير عمل القنوات، راجع القنوات ودليل Plugins.

    ذات صلة