BlueBubbles (macOS REST)

Статус: встроенный плагин, взаимодействующий с BlueBubbles macOS сервером по HTTP. Рекомендуется для интеграции iMessage благодаря более богатому API и простой настройке по сравнению с устаревшим каналом imsg.

Обзор

  • Работает на macOS через приложение-помощник BlueBubbles (bluebubbles.app).
  • Рекомендуется/протестировано: macOS Sequoia (15). macOS Tahoe (26) работает; редактирование на Tahoe в данный момент сломано, обновление иконки группы может сообщить об успехе, но не синхронизируется.
  • OpenClaw взаимодействует через REST API (GET /api/v1/ping, POST /message/text, POST /chat/:id/*).
  • Входящие сообщения приходят через вебхуки; исходящие ответы, индикаторы набора, подтверждения прочтения и тапбэки — REST-вызовы.
  • Вложения и стикеры загружаются как входящие медиа (и передаются агенту при возможности).
  • Спаривание/список доступа работает так же, как для других каналов (/channels/pairing и т.д.) с channels.bluebubbles.allowFrom + кодами спаривания.
  • Реакции отображаются как системные события (как в Slack/Telegram), чтобы агенты могли «упомянуть» их перед ответом.
  • Расширенные функции: редактирование, отмена отправки, потоки ответов, эффекты сообщений, управление группами.

Быстрый старт

  1. Установите сервер BlueBubbles на Mac (следуйте инструкциям на bluebubbles.app/install).

  2. В конфигурации BlueBubbles включите web API и задайте пароль.

  3. Запустите openclaw onboard и выберите BlueBubbles, или настройте вручную:

    {
      channels: {
        bluebubbles: {
          enabled: true,
          serverUrl: "http://192.168.1.100:1234",
          password: "example-password",
          webhookPath: "/bluebubbles-webhook",
        },
      },
    }
  4. Направьте вебхуки BlueBubbles на шлюз (пример: https://your-gateway-host:3000/bluebubbles-webhook?password=<password>).

  5. Запустите шлюз; он зарегистрирует обработчик вебхуков и начнёт спаривание.

Примечание по безопасности:

  • Всегда устанавливайте пароль вебхука.
  • Аутентификация вебхуков всегда обязательна. OpenClaw отклоняет запросы вебхуков BlueBubbles без пароля/guid, соответствующего channels.bluebubbles.password (например ?password=<password> или x-password), независимо от топологии loopback/proxy.
  • Аутентификация по паролю проверяется до чтения/разбора полного тела вебхука.

Поддержание Messages.app в активном состоянии (VM / headless-установки)

Некоторые macOS VM / постоянно работающие установки могут привести к «засыпанию» Messages.app (входящие события прекращаются, пока приложение не будет открыто/вынесено на передний план). Простое решение — активировать Messages каждые 5 минут через AppleScript + LaunchAgent.

1) Сохраните 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

2) Установите 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 секунд и при входе.
  • Первый запуск может вызвать запрос разрешений macOS Automation (osascript -> Messages). Подтвердите их в той же сессии пользователя, где работает LaunchAgent.

Загрузка:

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

Мастер запрашивает:

  • URL сервера (обязательно): адрес сервера BlueBubbles (например, http://192.168.1.100:1234)
  • Пароль (обязательно): API-пароль из настроек BlueBubbles Server
  • Путь вебхука (необязательно): по умолчанию /bluebubbles-webhook
  • Политика ЛС: pairing, allowlist, open или disabled
  • Список доступа: номера телефонов, email или цели чатов

Также можно добавить BlueBubbles через CLI:

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

Контроль доступа (ЛС + группы)

ЛС:

  • По умолчанию: channels.bluebubbles.dmPolicy = "pairing".
  • Неизвестные отправители получают код спаривания; сообщения игнорируются до подтверждения (коды истекают через 1 час).
  • Подтверждение:
    • openclaw pairing list bluebubbles
    • openclaw pairing approve bluebubbles <CODE>
  • Спаривание — стандартный обмен токенами. Подробнее: Спаривание

Группы:

  • channels.bluebubbles.groupPolicy = open | allowlist | disabled (по умолчанию: allowlist).
  • channels.bluebubbles.groupAllowFrom управляет тем, кто может активировать бота в группах при allowlist.

Гейтинг по упоминанию (группы)

BlueBubbles поддерживает гейтинг по упоминанию для групповых чатов, аналогично iMessage/WhatsApp:

  • Использует agents.list[].groupChat.mentionPatterns (или messages.groupChat.mentionPatterns) для обнаружения упоминаний.
  • При включённом requireMention для группы агент отвечает только при упоминании.
  • Управляющие команды от авторизованных отправителей обходят гейтинг по упоминанию.

Конфигурация по группам:

{
  channels: {
    bluebubbles: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15555550123"],
      groups: {
        "*": { requireMention: true }, // по умолчанию для всех групп
        "iMessage;-;chat123": { requireMention: false }, // переопределение для конкретной группы
      },
    },
  },
}

Гейтинг команд

  • Управляющие команды (например, /config, /model) требуют авторизации.
  • Используют allowFrom и groupAllowFrom для определения авторизации команд.
  • Авторизованные отправители могут выполнять управляющие команды без упоминания в группах.

Набор текста + подтверждения прочтения

  • Индикаторы набора: отправляются автоматически перед и во время генерации ответа.
  • Подтверждения прочтения: управляются через channels.bluebubbles.sendReadReceipts (по умолчанию: true).
  • Индикаторы набора: OpenClaw отправляет события начала набора; BlueBubbles автоматически очищает набор при отправке или по таймауту (ручная остановка через DELETE ненадёжна).
{
  channels: {
    bluebubbles: {
      sendReadReceipts: false, // отключить подтверждения прочтения
    },
  },
}

Расширенные действия

BlueBubbles поддерживает расширенные действия с сообщениями при включении в конфигурации:

{
  channels: {
    bluebubbles: {
      actions: {
        reactions: true, // тапбэки (по умолчанию: true)
        edit: true, // редактирование отправленных сообщений (macOS 13+, сломано на macOS 26 Tahoe)
        unsend: true, // отмена отправки (macOS 13+)
        reply: true, // потоки ответов по GUID сообщения
        sendWithEffect: true, // эффекты сообщений (slam, loud и т.д.)
        renameGroup: true, // переименование групповых чатов
        setGroupIcon: true, // установка иконки/фото группового чата (нестабильно на macOS 26 Tahoe)
        addParticipant: true, // добавление участников в группы
        removeParticipant: true, // удаление участников из групп
        leaveGroup: true, // выход из групповых чатов
        sendAttachment: true, // отправка вложений/медиа
      },
    },
  },
}

Доступные действия:

  • react: добавление/удаление тапбэк-реакций (messageId, emoji, remove)
  • 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)
  • sendAttachment: отправка медиа/файлов (to, buffer, filename, asVoice)
    • Голосовые заметки: задайте asVoice: true с аудио MP3 или CAF для отправки голосовым сообщением iMessage. BlueBubbles конвертирует MP3 в CAF при отправке голосовых заметок.

ID сообщений (короткие vs полные)

OpenClaw может показывать короткие ID сообщений (например, 1, 2) для экономии токенов.

  • MessageSid / ReplyToId могут быть короткими ID.
  • MessageSidFull / ReplyToIdFull содержат полные ID провайдера.
  • Короткие ID хранятся в памяти; они могут истечь при перезапуске или вытеснении из кэша.
  • Действия принимают короткие или полные messageId, но короткие ID вернут ошибку, если больше не доступны.

Используйте полные ID для долговременных автоматизаций и хранения:

  • Шаблоны: {{MessageSidFull}}, {{ReplyToIdFull}}
  • Контекст: MessageSidFull / ReplyToIdFull во входящих пакетах

Подробнее: Конфигурация о шаблонных переменных.

Блочный стриминг

Управление тем, отправляются ли ответы одним сообщением или стримятся блоками:

{
  channels: {
    bluebubbles: {
      blockStreaming: true, // включить блочный стриминг (по умолчанию выключен)
    },
  },
}

Медиа + ограничения

  • Входящие вложения загружаются и сохраняются в кэше медиа.
  • Лимит медиа через channels.bluebubbles.mediaMaxMb для входящих и исходящих (по умолчанию: 8 МБ).
  • Исходящий текст разбивается по channels.bluebubbles.textChunkLimit (по умолчанию: 4000 символов).

Справочник конфигурации

Полная конфигурация: Конфигурация

Опции провайдера:

  • channels.bluebubbles.enabled: включение/выключение канала.
  • channels.bluebubbles.serverUrl: базовый URL REST API BlueBubbles.
  • channels.bluebubbles.password: API-пароль.
  • channels.bluebubbles.webhookPath: путь эндпоинта вебхука (по умолчанию: /bluebubbles-webhook).
  • channels.bluebubbles.dmPolicy: pairing | allowlist | open | disabled (по умолчанию: pairing).
  • channels.bluebubbles.allowFrom: список доступа ЛС (хэндлы, email, номера E.164, chat_id:*, chat_guid:*).
  • channels.bluebubbles.groupPolicy: open | allowlist | disabled (по умолчанию: allowlist).
  • channels.bluebubbles.groupAllowFrom: список доступа отправителей в группах.
  • channels.bluebubbles.groups: конфигурация по группам (requireMention и т.д.).
  • channels.bluebubbles.sendReadReceipts: отправка подтверждений прочтения (по умолчанию: true).
  • channels.bluebubbles.blockStreaming: включение блочного стриминга (по умолчанию: false; требуется для стриминга ответов).
  • channels.bluebubbles.textChunkLimit: размер исходящего чанка в символах (по умолчанию: 4000).
  • channels.bluebubbles.chunkMode: length (по умолчанию) разбивает только при превышении textChunkLimit; newline разбивает по пустым строкам (границам абзацев) перед разбивкой по длине.
  • channels.bluebubbles.mediaMaxMb: лимит входящих/исходящих медиа в МБ (по умолчанию: 8).
  • channels.bluebubbles.mediaLocalRoots: явный список разрешённых абсолютных локальных каталогов для исходящих локальных путей медиа. Отправка по локальному пути запрещена по умолчанию без настройки. Переопределение по аккаунту: channels.bluebubbles.accounts.<accountId>.mediaLocalRoots.
  • channels.bluebubbles.historyLimit: максимум групповых сообщений для контекста (0 отключает).
  • channels.bluebubbles.dmHistoryLimit: лимит истории ЛС.
  • 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. Для этого требуется включённый Private API BlueBubbles.

Безопасность

  • Запросы вебхуков аутентифицируются сравнением параметров guid/password в query или заголовках с channels.bluebubbles.password. Запросы с localhost тоже принимаются.
  • Храните API-пароль и эндпоинт вебхука в секрете (обращайтесь как с учётными данными).
  • Доверие localhost означает, что reverse proxy на том же хосте может непреднамеренно обойти пароль. Если вы проксируете шлюз, требуйте аутентификацию на прокси и настройте gateway.trustedProxies. Подробнее: Безопасность шлюза.
  • Включите HTTPS + правила файрволла на сервере BlueBubbles при его открытии за пределами LAN.

Устранение неполадок

  • Если набор текста/уведомления о прочтении перестают работать, проверьте логи вебхуков BlueBubbles и убедитесь, что путь шлюза совпадает с channels.bluebubbles.webhookPath.
  • Коды спаривания истекают через один час; используйте openclaw pairing list bluebubbles и openclaw pairing approve bluebubbles <code>.
  • Реакции требуют private API BlueBubbles (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.
  • Информация о статусе/здоровье: openclaw status --all или openclaw status --deep.

Для общего справочника по рабочим процессам каналов см. Каналы и руководство Плагины.