Mainstream messaging
Перехід з BlueBubbles
Комплектний Plugin 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напряму на 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 із Messages, встановіть
channels.imessage.cliPathна SSH-обгортку та задайтеremoteHostдля віддаленого отримання вкладень. - Коли Gateway зупинено, увімкніть
channels.imessage, а потім виконайтеopenclaw channels status --probe --channel imessage. - Перевірте один DM, одну дозволену групу, вкладення, якщо їх увімкнено, і кожну дію приватного API, яку, як очікується, використовуватиме агент.
- Видаліть сервер BlueBubbles і стару конфігурацію
channels.bluebubblesпісля перевірки шляху iMessage.
Коли ця міграція має сенс
- Ви вже запускаєте
imsgна тому самому Mac (або на доступному через SSH), де виконано вхід у Messages.app. - Ви хочете мати на один рухомий компонент менше — без окремого сервера BlueBubbles, без REST-ендпоінта для автентифікації, без зв’язування Webhook. Один бінарний файл CLI замість сервера + клієнтського застосунку + помічника.
- Ви використовуєте підтримувану macOS / збірку
imsg, де проба приватного API повідомляєavailable: true.
Що робить imsg
imsg — це локальний macOS CLI для Messages. 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. Для OpenClaw iMessage запускайтеimsgна Mac, де виконано вхід, або через SSH-обгортку до цього Mac.
Перш ніж почати
-
Встановіть
imsgна Mac, де працює Messages.app:brew install steipete/tap/imsg imsg --version imsg chats --limit 3Якщо
imsg chatsзавершується помилкоюunable to open database file, порожнім виводом абоauthorization denied, надайте повний доступ до диска терміналу, редактору, процесу Node, сервісу Gateway або батьківському процесу SSH, який запускаєimsg, а потім знову відкрийте цей батьківський процес. -
Перевірте поверхні читання, спостереження, надсилання та RPC перед зміною конфігурації OpenClaw:
imsg chats --limit 10 --json | jq -s imsg history --chat-id 42 --limit 10 --attachments --json | jq -s imsg watch --chat-id 42 --reactions --json imsg send --chat-id 42 --text "OpenClaw imsg test" imsg rpc --helpЗамініть
42на справжній ідентифікатор чату зimsg chats. Для надсилання потрібен дозвіл автоматизації для Messages.app. Якщо OpenClaw працюватиме через SSH, виконайте ці команди через ту саму SSH-обгортку або контекст користувача, який використовуватиме OpenClaw. -
Увімкніть міст приватного API, коли потрібні розширені дії:
imsg launch imsg status --jsonimsg launchвимагає вимкненого SIP. Базове надсилання, історія та спостереження працюють безimsg launch; розширені дії — ні. -
Після додавання увімкненої конфігурації
channels.imessageперевірте міст через OpenClaw:openclaw channels status --probeПотрібне значення
imessage.privateApi.available: true. Якщо виводитьсяfalse, спочатку виправте це — див. Виявлення можливостей.channels status --probeперевіряє лише налаштовані й увімкнені облікові записи. -
Зробіть знімок конфігурації:
cp ~/.openclaw/openclaw.json5 ~/.openclaw/openclaw.json5.bak
Переклад конфігурації
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); використовуйте wrapper script для SSH. |
| (неявно) | channels.imessage.dbPath |
Необов'язкове перевизначення chat.db Messages.app; автоматично виявляється, якщо пропущено. |
| (неявно) | channels.imessage.remoteHost |
host або user@host — потрібно лише коли cliPath є SSH wrapper і ви хочете отримувати вкладення через SCP. |
channels.bluebubbles.dmPolicy |
channels.imessage.dmPolicy |
Ті самі значення (pairing / allowlist / open / disabled). |
channels.bluebubbles.allowFrom |
channels.imessage.allowFrom |
Підтвердження спарювання переносяться за handle, а не за токеном. |
channels.bluebubbles.groupPolicy |
channels.imessage.groupPolicy |
Ті самі значення (allowlist / open / disabled). |
channels.bluebubbles.groupAllowFrom |
channels.imessage.groupAllowFrom |
Те саме. |
channels.bluebubbles.groups |
channels.imessage.groups |
Скопіюйте це дослівно, включно з будь-яким wildcard-записом groups: { "*": { ... } }. Групові requireMention, tools, toolsBySender переносяться. З groupPolicy: "allowlist" порожній або відсутній блок groups тихо відкидає кожне групове повідомлення — див. "Пастка реєстру груп" нижче. |
channels.bluebubbles.sendReadReceipts |
channels.imessage.sendReadReceipts |
Типово true. З вбудованим Plugin це спрацьовує лише коли probe приватного API працює. |
channels.bluebubbles.includeAttachments |
channels.imessage.includeAttachments |
Та сама форма, так само вимкнено за замовчуванням. Якщо у вас вкладення проходили в BlueBubbles, потрібно явно повторно задати це в блоці iMessage — воно не переноситься неявно, а вхідні фото/медіа будуть тихо відкидатися без рядка журналу Inbound message, доки ви цього не зробите. |
channels.bluebubbles.attachmentRoots |
channels.imessage.attachmentRoots |
Локальні корені; ті самі правила wildcard. |
| (Н/Д) | 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 — групові чати в обох каналах зберігають миттєве надсилання кожного повідомлення. Розширює типовий вхідний debounce до 2500 мс, якщо ввімкнено без явного messages.inbound.byChannel.imessage. Див. документацію iMessage § Об'єднання DM із розділеним надсиланням. |
channels.bluebubbles.enrichGroupParticipantsFromContacts |
(Н/Д) | iMessage вже читає display names відправників із 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.*.
Пастка реєстру груп
Вбудований iMessage Plugin запускає два окремі gates allowlist для груп поспіль. Обидва мають пройти, щоб групове повідомлення дійшло до агента:
- Allowlist відправника / цільового чату (
channels.imessage.groupAllowFrom) — перевіряєтьсяisAllowedIMessageSender. Зіставляє вхідні повідомлення за handle відправника,chat_guid,chat_identifierабоchat_id. Та сама форма, що й у BlueBubbles. - Реєстр груп (
channels.imessage.groups) — перевіряєтьсяresolveChannelGroupPolicyзinbound-processing.ts:199. ЗgroupPolicy: "allowlist"цей gate вимагає або:- wildcard-запис
groups: { "*": { ... } }(задаєallowAll = true), або - явний запис для окремого
chat_idуgroups.
- wildcard-запис
Якщо gate 1 проходить, але gate 2 ні, повідомлення відкидається. Plugin видає два сигнали рівня warn, тож це більше не є тихим за типового рівня журналювання:
- Одноразовий startup
warnдля кожного облікового запису, коли заданоgroupPolicy: "allowlist", алеchannels.imessage.groupsпорожній (немає wildcard"*", немає записів для окремихchat_id) — спрацьовує до надходження будь-яких повідомлень. - Одноразовий
warnдля кожногоchat_idпід час першого відкидання конкретної групи в runtime, із назвою chat_id та точним ключем, який треба додати доgroups, щоб дозволити її.
DM продовжують працювати, бо вони йдуть іншим code path.
Це найпоширеніший режим збою міграції BlueBubbles → вбудований iMessage: оператори копіюють groupAllowFrom і groupPolicy, але пропускають блок groups, бо BlueBubbles groups: { "*": { "requireMention": true } } виглядає як непов'язане налаштування згадки. Насправді воно критично важливе для gate реєстру.
Мінімальна конфігурація, щоб групові повідомлення продовжували проходити після groupPolicy: "allowlist":
{
channels: {
imessage: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123", "chat_guid:any;-;..."],
groups: {
"*": { requireMention: true },
},
},
},
}
requireMention: true під * не шкодить, коли шаблони згадок не налаштовані: runtime встановлює 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, відкидає друга перевірка — додайте блок groups.
Покроково
-
Додайте блок iMessage поряд з наявним блоком BlueBubbles. Тримайте його вимкненим, доки Gateway усе ще маршрутизує трафік BlueBubbles:
{ channels: { bluebubbles: { enabled: true, // ... existing config ... }, imessage: { enabled: false, cliPath: "/opt/homebrew/bin/imsg", dmPolicy: "pairing", allowFrom: ["+15555550123"], // copy from bluebubbles.allowFrom groupPolicy: "allowlist", groupAllowFrom: [], // copy from bluebubbles.groupAllowFrom groups: { "*": { requireMention: true } }, // copy from bluebubbles.groups — silently drops groups if missing, see "Group registry footgun" above actions: { reactions: true, edit: true, unsend: true, reply: true, sendWithEffect: true, sendAttachment: true, }, }, }, } -
Перевірте до того, як трафік стане важливим — зупиніть Gateway, тимчасово увімкніть блок iMessage і підтвердьте через CLI, що iMessage повідомляє про справний стан:
openclaw gateway stop # edit config: channels.imessage.enabled = true openclaw channels status --probe --channel imessage # expect imessage.privateApi.available: truechannels status --probeперевіряє лише налаштовані, увімкнені облікові записи. Не перезапускайте Gateway з одночасно увімкненими BlueBubbles і iMessage, якщо ви навмисно не хочете запускати обидва монітори каналів. Якщо ви не перемикаєтеся негайно, повернітьchannels.imessage.enabledдоfalseперед перезапуском Gateway. Використовуйте прямі командиimsgу розділі Перед початком, щоб перевірити Mac до вмикання трафіку OpenClaw. -
Перемкніться. Щойно увімкнений обліковий запис iMessage повідомить про справний стан, видаліть конфігурацію BlueBubbles і залиште iMessage увімкненим:
{ channels: { imessage: { enabled: true /* ... */ }, }, }Перезапустіть Gateway. Вхідний трафік iMessage тепер проходить через вбудований Plugin.
-
Перевірте DM. Надішліть агенту пряме повідомлення; підтвердьте, що відповідь надходить.
-
Перевірте групи окремо. DM і групи проходять різними шляхами коду — успіх DM не доводить, що групи маршрутизуються. Надішліть агенту повідомлення в спареному груповому чаті й підтвердьте, що відповідь надходить. Якщо група замовкає (немає відповіді агента, немає помилки), перевірте журнал Gateway на
imessage: dropping group message from chat_id=<id>або стартовий рядокimessage: groupPolicy="allowlist" but channels.imessage.groups is empty— обидва спрацьовують на стандартному рівні журналювання. Якщо з’являється будь-який із них, ваш блокgroupsвідсутній або порожній — див. "Group registry footgun" вище. -
Перевірте поверхню дій — зі спареного DM попросіть агента поставити реакцію, відредагувати, скасувати надсилання, відповісти, надіслати фото і (в групі) перейменувати групу / додати або вилучити учасника. Кожна дія має нативно з’явитися в Messages.app. Якщо будь-яка викидає "iMessage
<action>requires the imsg private API bridge", знову запустітьimsg launchі оновітьchannels status --probe. -
Видаліть сервер і конфігурацію BlueBubbles, щойно DM, групи й дії iMessage буде перевірено. OpenClaw не використовуватиме
channels.bluebubbles.
Коротко про паритет дій
| Дія | застарілий BlueBubbles | вбудований iMessage |
|---|---|---|
| Надсилання тексту / резервне SMS | ✅ | ✅ |
| Надсилання медіа (фото, відео, файл, голос) | ✅ | ✅ |
Відповідь у гілці (reply_to_guid) |
✅ | ✅ (закриває #51892) |
Tapback (react) |
✅ | ✅ |
| Редагування / скасування надсилання (отримувачі macOS 13+) | ✅ | ✅ |
| Надсилання з екранним ефектом | ✅ | ✅ (закриває частину #9394) |
| Форматований текст: жирний / курсив / підкреслення / закреслення | ✅ | ✅ (форматування typed-run через attributedBody) |
| Перейменування групи / встановлення іконки групи | ✅ | ✅ |
| Додавання / вилучення учасника, вихід із групи | ✅ | ✅ |
| Сповіщення про прочитання та індикатор набору | ✅ | ✅ (обмежено перевіркою приватного API) |
| Об’єднання DM від того самого відправника | ✅ | ✅ (лише DM; увімкнення через channels.imessage.coalesceSameSenderDms) |
| Доганяння вхідних повідомлень, отриманих, поки Gateway був вимкнений | ✅ (повтор Webhook + отримання історії) | ✅ (увімкнення через channels.imessage.catchup.enabled; закриває #78649) |
Доганяння iMessage тепер доступне як опційна функція у вбудованому Plugin. Під час запуску Gateway, якщо channels.imessage.catchup.enabled має значення true, Gateway виконує один прохід chats.list + messages.history для кожного чату через той самий клієнт JSON-RPC, який використовує imsg watch, повторно пропускає кожен пропущений вхідний рядок через живий шлях dispatch (списки дозволів, політика груп, debouncer, кеш echo) і зберігає курсор для кожного облікового запису, щоб наступні запуски продовжували з місця зупинки. Див. Доганяння після простою Gateway для налаштування.
Спарювання, сесії та прив’язки ACP
- Схвалення спарювання переносяться за handle. Вам не потрібно повторно схвалювати відомих відправників —
channels.imessage.allowFromрозпізнає ті самі рядки+15555550123/user@example.com, які використовував BlueBubbles. - Сесії залишаються обмеженими на рівні агент + чат. DM згортаються в основну сесію агента за стандартного
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:, bare handle) ідентичні.
Немає каналу відкату
Немає підтримуваного runtime BlueBubbles, на який можна перемкнутися назад. Якщо перевірка iMessage не вдається, встановіть channels.imessage.enabled: false, перезапустіть Gateway, усуньте блокер imsg і повторіть перемикання.
Кеш відповідей розташований у ~/.openclaw/state/imessage/reply-cache.jsonl (режим 0600, батьківський каталог 0700). Його безпечно видалити, якщо потрібен чистий старт.
Пов’язане
- Видалення BlueBubbles і шлях imsg iMessage — коротке оголошення та резюме для оператора.
- iMessage — повний довідник каналу iMessage, включно з налаштуванням
imsg launchі визначенням можливостей. /channels/bluebubbles— застаріла URL-адреса, що переспрямовує на цей посібник із міграції.- Спарювання — автентифікація DM і потік спарювання.
- Маршрутизація каналів — як Gateway обирає канал для вихідних відповідей.