Mainstream messaging

iMessage

Стан: нативна інтеграція із зовнішнім CLI. Gateway запускає imsg rpc і взаємодіє через JSON-RPC у stdio — без окремого демона чи порту. Для повноцінного каналу iMessage наполегливо рекомендовано режим Private API; відповіді, реакції tapback, ефекти, опитування, відповіді на вкладення та групові дії потребують imsg launch й успішної перевірки Private API.

Для поширеного локального налаштування майстер OpenClaw може запропонувати підтверджене користувачем установлення або оновлення imsg через Homebrew на Mac із виконаним входом у Messages. Ручне налаштування й топології з SSH-обгорткою залишаються під керуванням оператора: установлюйте або оновлюйте imsg у тому самому користувацькому контексті, у якому працюватиме Gateway або обгортка.

Швидке налаштування

Локальний Mac (швидкий шлях)

  • Установіть і перевірте imsg

    bash
    brew install steipete/tap/imsgbrew update && brew upgrade imsgimsg rpc --helpimsg launchopenclaw channels status --probe

    Коли локальний майстер налаштування виявляє відсутню типову команду imsg, він може запропонувати встановити steipete/tap/imsg через Homebrew. Якщо він виявляє керований Homebrew компонент imsg, то може запропонувати повторно встановити або оновити його. Користувацькі обгортки cliPath не змінюються.

  • Налаштуйте OpenClaw

    json5
    {channels: {imessage: {enabled: true,cliPath: "/usr/local/bin/imsg",dbPath: "/Users/user/Library/Messages/chat.db",},},}
  • Запустіть Gateway

    bash
    openclaw gateway
  • Схваліть перше сполучення для приватних повідомлень (типова dmPolicy)

    bash
    openclaw pairing list imessageopenclaw pairing approve imessage <CODE>

    Термін дії запитів на сполучення спливає через 1 годину.

  • Віддалений Mac через SSH

    Більшості конфігурацій SSH не потрібен. Використовуйте цю топологію лише тоді, коли Gateway не може працювати на Mac із виконаним входом у Messages. OpenClaw потрібен лише сумісний зі stdio компонент cliPath, тому для cliPath можна вказати сценарій-обгортку, який підключається через SSH до віддаленого Mac і запускає imsg. Установлюйте й оновлюйте imsg на цьому віддаленому Mac, а не на хості Gateway:

    bash
    ssh messages-mac 'brew install steipete/tap/imsg && brew update && brew upgrade imsg'
    bash
    #!/usr/bin/env bashexec ssh -T messages-mac imsg "$@"

    Рекомендована конфігурація, коли вкладення ввімкнено:

    json5
    {channels: {imessage: {  enabled: true,  cliPath: "~/.openclaw/scripts/imsg-ssh",  remoteHost: "user@gateway-host", // використовується для отримання вкладень через SCP  includeAttachments: true,  // Необов’язково: додаткові дозволені кореневі каталоги вкладень (об’єднуються з типовим  // /Users/*/Library/Messages/Attachments).  attachmentRoots: ["/Users/*/Library/Messages/Attachments"],  remoteAttachmentRoots: ["/Users/*/Library/Messages/Attachments"],},},}

    Якщо remoteHost не задано, OpenClaw намагається визначити його автоматично, аналізуючи сценарій SSH-обгортки. remoteHost має бути host або user@host (без пробілів чи параметрів SSH); небезпечні значення ігноруються. OpenClaw використовує сувору перевірку ключа хоста для SCP, тому ключ хоста ретранслятора вже має бути в ~/.ssh/known_hosts. Шляхи вкладень перевіряються за дозволеними кореневими каталогами (attachmentRoots / remoteAttachmentRoots).

    Вимоги та дозволи (macOS)

    • На Mac, де працює imsg, має бути виконано вхід у Messages.
    • Для контексту процесу, у якому працює OpenClaw/imsg, потрібен Full Disk Access (для доступу до бази даних Messages).
    • Для надсилання повідомлень через Messages.app потрібен дозвіл Automation.
    • Для розширених дій (реакція / редагування / скасування надсилання / відповідь у гілці / ефекти / опитування / групові операції) потрібно вимкнути System Integrity Protection — див. Увімкнення Private API imsg. Базове надсилання й отримання тексту та медіафайлів працює без цього.
    Надсилання через SSH-обгортку завершується помилкою AppleEvents -1743

    Конфігурація з віддаленим SSH може читати чати, проходити channels status --probe та обробляти вхідні повідомлення, хоча надсилання вихідних повідомлень і далі завершується помилкою авторизації AppleEvents:

    text
    Немає дозволу надсилати події Apple до Messages. (-1743)

    Перевірте базу даних TCC користувача віддаленого Mac із виконаним входом або System Settings > Privacy & Security > Automation. Якщо запис Automation зареєстровано для /usr/libexec/sshd-keygen-wrapper, а не для imsg або процесу локальної оболонки, macOS може не показувати придатний перемикач Messages для цього серверного клієнта SSH:

    text
    kTCCServiceAppleEvents | /usr/libexec/sshd-keygen-wrapper | auth_value=0 | com.apple.MobileSMS

    У такому стані повторне виконання tccutil reset AppleEvents або повторний запуск imsg send через ту саму SSH-обгортку може й надалі завершуватися помилкою, оскільки доступ до Automation для Messages потрібен контексту процесу SSH-обгортки, а не застосунку, якому інтерфейс може надати дозвіл.

    Натомість використовуйте один із підтримуваних контекстів процесу imsg:

    • Запускайте Gateway або принаймні міст imsg у локальному сеансі користувача, який увійшов у Messages.
    • Запускайте Gateway за допомогою LaunchAgent цього користувача після надання Full Disk Access і Automation у тому самому сеансі.
    • Якщо зберігається двокористувацька топологія SSH, перед увімкненням каналу перевірте, що реальне вихідне надсилання imsg send успішно виконується через цю точну обгортку. Якщо надати їй Automation неможливо, замість використання SSH-обгортки для надсилання перейдіть на однокористувацьку конфігурацію imsg.

    Увімкнення Private API imsg

    imsg постачається у двох режимах роботи. Для OpenClaw рекомендовано режим Private API, оскільки він надає каналу нативні дії iMessage, на які очікують користувачі. Базовий режим залишається корисним для встановлень із низьким ризиком, початкової перевірки або хостів, де SIP неможливо вимкнути.

    • Базовий режим (типовий, не потребує змін SIP): вихідні текстові й медіаповідомлення через send, спостереження за вхідними повідомленнями та історією, список чатів. Це доступно одразу після нового встановлення brew install steipete/tap/imsg і надання стандартних дозволів macOS, зазначених вище.
    • Режим Private API: imsg впроваджує допоміжну dylib у Messages.app для виклику внутрішніх функцій IMCore. Це відкриває доступ до react, edit, unsend, reply (у гілці), sendWithEffect, poll і poll-vote (нативні опитування Messages), renameGroup, setGroupIcon, addParticipant, removeParticipant, leaveGroup, а також індикаторів набору тексту та сповіщень про прочитання.

    Рекомендований на цій сторінці набір дій потребує режиму Private API. README для imsg прямо зазначає цю вимогу:

    Розширені функції, як-от read, typing, launch, розширене надсилання через міст, зміна повідомлень і керування чатами, є необов’язковими. Для них потрібно вимкнути SIP і впровадити допоміжну dylib у Messages.app. imsg launch відмовляється виконувати впровадження, коли SIP увімкнено.

    Метод впровадження допоміжної бібліотеки використовує власну dylib компонента imsg для доступу до приватних API Messages. У шляху iMessage для OpenClaw немає стороннього сервера чи середовища виконання BlueBubbles.

    Налаштування

    1. Установіть (або оновіть) imsg на Mac, де працює Messages.app:

      bash
      brew install steipete/tap/imsgbrew update && brew upgrade imsgimsg --versionimsg status --json

      Вивід imsg status --json повідомляє про bridge_version, rpc_methods і selectors для кожного методу, щоб перед початком роботи можна було побачити, що підтримує поточна збірка.

    2. Вимкніть захист цілісності системи, а в сучасних версіях macOS — також перевірку бібліотек. Для впровадження допоміжної бібліотеки dylib не від Apple у підписаний Apple процес Messages.app потрібно вимкнути SIP і послабити перевірку бібліотек. Крок із SIP у режимі відновлення залежить від версії macOS:

      • macOS 10.13–10.15 (Sierra–Catalina): вимкніть перевірку бібліотек через Terminal, перезавантажтеся в режим відновлення, виконайте csrutil disable, перезапустіть систему.
      • macOS 11+ (Big Sur і новіші), Intel: перейдіть у режим відновлення (або відновлення через інтернет), виконайте csrutil disable, перезапустіть систему.
      • macOS 11+, Apple Silicon: скористайтеся послідовністю запуску кнопкою живлення, щоб увійти в режим відновлення; у нових версіях macOS утримуйте клавішу Left Shift, коли натискаєте Continue, а потім виконайте csrutil disable. Для віртуальних машин діє окрема процедура, тому спочатку створіть знімок віртуальної машини.

      У macOS 11 і новіших версіях одного csrutil disable зазвичай недостатньо. Apple усе одно застосовує перевірку бібліотек до Messages.app як до платформного виконуваного файла, тому допоміжний компонент зі спеціальним підписом відхиляється (Library Validation failed: ... platform binary, but mapped file is not) навіть за вимкненого SIP. Після вимкнення SIP також вимкніть перевірку бібліотек і перезавантажте систему:

      bash
      sudo defaults write /Library/Preferences/com.apple.security.libraryvalidation.plist DisableLibraryValidation -bool true

      macOS 26 (Tahoe), перевірено у версії 26.5.1: вимкненого SIP разом із наведеною вище командою DisableLibraryValidation достатньо для впровадження допоміжного компонента у версіях від 26.0 до 26.5.x. Жодні параметри завантаження не потрібні. Вирішальним чинником є файл plist, і саме цей крок найчастіше пропускають, коли впровадження в Tahoe завершується невдало:

      • З файлом plist: imsg launch виконує впровадження, а imsg status повідомляє advanced_features: true.
      • Без файла plist (навіть за вимкненого SIP): imsg launch завершується помилкою Failed to launch: Timeout waiting for Messages.app to initialize. AMFI відхиляє допоміжний компонент зі спеціальним підписом під час завантаження, тому міст не переходить у стан готовності, а запуск завершується через перевищення часу очікування. Саме з таким симптомом найчастіше стикаються в Tahoe; виправленням є наведений вище файл plist, а не радикальніше послаблення захисту.

      Якщо після оновлення macOS впровадження imsg launch або певні selectors починають повертати false, звичайною причиною є ця перевірка. Перш ніж припускати, що сам крок із SIP не спрацював, перевірте стан SIP і перевірки бібліотек. Якщо ці параметри правильні, але міст усе одно не може виконати впровадження, зберіть imsg status --json разом із виводом imsg launch і повідомте про це в проєкт imsg, замість того щоб додатково послаблювати загальносистемні засоби захисту.

    3. Впровадьте допоміжний компонент. Коли SIP вимкнено, а в Messages.app виконано вхід:

      bash
      imsg launch

      imsg launch відмовляється виконувати впровадження, якщо SIP усе ще ввімкнено, тож це також підтверджує успішність кроку 2.

    4. Перевірте міст з OpenClaw:

      bash
      openclaw channels status --probe

      Запис iMessage має повідомити works, а imsg status --json | jq '{rpc_methods, selectors}' — показати можливості, доступні у вашій збірці macOS. Для створення опитувань потрібен selectors.pollPayloadMessage; для голосування потрібні і selectors.pollVoteMessage, і метод RPC poll.vote. Plugin OpenClaw оголошує лише дії, підтримувані кешованою перевіркою, тоді як за порожнього кешу він оптимістично вважає їх доступними та виконує перевірку під час першого надсилання.

    Якщо openclaw channels status --probe повідомляє, що канал має стан works, але певні дії під час надсилання спричиняють помилку "iMessage <action> requires the imsg private API bridge", знову виконайте imsg launch — допоміжний компонент може від'єднатися (через перезапуск Messages.app, оновлення ОС тощо), а кешований стан available: true продовжуватиме оголошувати дії до наступного оновлення перевірки.

    Коли SIP залишається ввімкненим

    Якщо вимкнення SIP неприйнятне для вашої моделі загроз:

    • imsg переходить у базовий режим — лише текст, медіафайли та отримання.
    • Plugin OpenClaw усе одно оголошує надсилання тексту й медіафайлів та моніторинг вхідних повідомлень; він приховує react, edit, unsend, reply, sendWithEffect і групові операції з поверхні дій (відповідно до перевірки можливостей для кожного методу).
    • Для навантаження iMessage можна використовувати окремий Mac без Apple Silicon (або спеціалізований Mac для бота) з вимкненим SIP, залишивши SIP увімкненим на основних пристроях. Див. нижче Спеціалізований користувач macOS для бота (окрема ідентичність iMessage).

    Керування доступом і маршрутизація

    Політика приватних повідомлень

    channels.imessage.dmPolicy керує приватними повідомленнями:

    • pairing (типове значення)
    • allowlist (потрібен принаймні один запис allowFrom)
    • open (потрібно, щоб allowFrom містив "*")
    • disabled

    Поле списку дозволених: channels.imessage.allowFrom.

    Записи списку дозволених мають ідентифікувати відправників: дескриптори або статичні групи доступу відправників (accessGroup:<name>). Використовуйте channels.imessage.groupAllowFrom для цілей чатів, як-от chat_id:*, chat_guid:* або chat_identifier:*; використовуйте channels.imessage.groups для числових ключів реєстру chat_id.

    Політика груп і згадки

    channels.imessage.groupPolicy керує обробкою груп:

    • allowlist (типове значення)
    • open
    • disabled

    Список дозволених відправників групи: channels.imessage.groupAllowFrom.

    Записи groupAllowFrom також можуть посилатися на статичні групи доступу відправників (accessGroup:<name>).

    Резервна поведінка середовища виконання: якщо groupAllowFrom не задано, для перевірки відправників груп iMessage використовується allowFrom; задайте groupAllowFrom, якщо правила допуску до приватних повідомлень і груп мають відрізнятися. Явно порожній groupAllowFrom: [] не використовує резервне значення — він блокує всіх відправників груп за політики allowlist. Примітка щодо середовища виконання: якщо channels.imessage повністю відсутній, середовище виконання використовує резервне значення groupPolicy="allowlist" і записує попередження в журнал (навіть якщо задано channels.defaults.groupPolicy).

    Перевірка згадок у групах:

    • iMessage не має вбудованих метаданих згадок
    • для виявлення згадок використовуються шаблони регулярних виразів (agents.list[].groupChat.mentionPatterns, резервний варіант messages.groupChat.mentionPatterns)
    • без налаштованих шаблонів перевірку згадок неможливо застосувати
    • керівні команди від авторизованих відправників обходять перевірку згадок

    systemPrompt для окремих груп:

    Кожен запис у channels.imessage.groups.* приймає необов'язковий рядок systemPrompt, який додається до системного запиту агента під час кожного ходу, що обробляє повідомлення в цій групі. Порядок визначення відповідає channels.whatsapp.groups:

    1. Системний запит конкретної групи (groups["<chat_id>"].systemPrompt): використовується, коли запис конкретної групи існує в карті і в ньому визначено ключ systemPrompt. Якщо systemPrompt є порожнім рядком (""), шаблон не застосовується й системний запит для цієї групи не додається.
    2. Системний запит за шаблоном групи (groups["*"].systemPrompt): використовується, коли запис конкретної групи повністю відсутній у карті або коли він існує, але не визначає ключ systemPrompt.
    json5
    {  channels: {    imessage: {      groupPolicy: "allowlist",      groupAllowFrom: ["+15555550123"],      groups: {        "*": { systemPrompt: "Використовуйте британський правопис." },        "8421": {          requireMention: true,          systemPrompt: "Це чат чергування. Відповіді мають містити не більше 3 речень.",        },        "9907": {          // явне скасування: шаблон "Використовуйте британський правопис." тут не застосовується          systemPrompt: "",        },      },    },  },}

    Запити для окремих груп застосовуються лише до групових повідомлень — на приватні повідомлення це не впливає.

    Сеанси й детерміновані відповіді

    • Для приватних повідомлень використовується пряма маршрутизація, а для груп — групова.
    • За типового session.dmScope=main приватні повідомлення iMessage об'єднуються в основному сеансі агента.
    • Групові сеанси ізольовані (agent:<agentId>:imessage:group:<chat_id>).
    • Відповіді спрямовуються назад до iMessage за метаданими початкового каналу й цілі.

    Поведінка гілок, схожих на групові:

    Деякі гілки iMessage з кількома учасниками можуть надходити з is_group=false. Якщо цей chat_id явно налаштовано в channels.imessage.groups, OpenClaw обробляє його як груповий трафік (перевірка групи та ізоляція групового сеансу).

    Прив'язки розмов ACP

    Чати iMessage можна прив'язувати до сеансів ACP.

    Швидка процедура для оператора:

    • Виконайте /acp spawn codex --bind here у приватному повідомленні або дозволеному груповому чаті.
    • Подальші повідомлення в тій самій розмові iMessage спрямовуватимуться до створеного сеансу ACP.
    • /new і /reset скидають той самий прив'язаний сеанс ACP без його заміни.
    • /acp close закриває сеанс ACP і видаляє прив'язку.

    Налаштовані постійні прив'язки використовують записи верхнього рівня bindings[] з type: "acp" і match.channel: "imessage".

    match.peer.id може використовувати:

    • нормалізований дескриптор приватного повідомлення, як-от +15555550123 або user@example.com
    • chat_id:<id> (рекомендовано для стабільних групових прив'язок)
    • chat_guid:<guid>
    • chat_identifier:<identifier>

    Приклад:

    json5
    {  agents: {    list: [      {        id: "codex",        runtime: {          type: "acp",          acp: { agent: "codex", backend: "acpx", mode: "persistent" },        },      },    ],  },  bindings: [    {      type: "acp",      agentId: "codex",      match: {        channel: "imessage",        accountId: "default",        peer: { kind: "group", id: "chat_id:123" },      },      acp: { label: "codex-group" },    },  ],}

    Спільну поведінку прив'язок ACP описано в розділі Агенти ACP.

    Схеми розгортання

    Спеціалізований користувач macOS для бота (окрема ідентичність iMessage)

    Використовуйте окремі Apple ID і обліковий запис користувача macOS, щоб трафік бота був ізольований від вашого особистого профілю Messages.

    Типова процедура:

    1. Створіть окремого користувача macOS або ввійдіть до його облікового запису.
    2. Увійдіть у Messages за допомогою Apple ID бота в обліковому записі цього користувача.
    3. Установіть imsg в обліковому записі цього користувача.
    4. Створіть обгортку SSH, щоб OpenClaw міг запускати imsg у контексті цього користувача.
    5. Спрямуйте channels.imessage.accounts.<id>.cliPath і .dbPath до профілю цього користувача.

    Під час першого запуску можуть знадобитися дозволи в графічному інтерфейсі (Automation + Full Disk Access) у сеансі користувача бота.

    Віддалений Mac через Tailscale (приклад)

    Типова топологія:

    • Gateway працює на Linux/VM
    • iMessage + imsg працює на Mac у вашій мережі tailnet
    • Обгортка cliPath використовує SSH для запуску imsg
    • remoteHost уможливлює отримання вкладень через SCP

    Приклад:

    json5
    {  channels: {    imessage: {      enabled: true,      cliPath: "~/.openclaw/scripts/imsg-ssh",      remoteHost: "bot@mac-mini.tailnet-1234.ts.net",      includeAttachments: true,      dbPath: "/Users/bot/Library/Messages/chat.db",    },  },}
    bash
    #!/usr/bin/env bashexec ssh -T bot@mac-mini.tailnet-1234.ts.net imsg "$@"

    Використовуйте ключі SSH, щоб взаємодія через SSH і SCP не потребувала введення даних. Спочатку переконайтеся, що ключ хоста є довіреним (наприклад, ssh bot@mac-mini.tailnet-1234.ts.net), щоб заповнити known_hosts.

    Схема з кількома обліковими записами

    iMessage підтримує конфігурацію для кожного облікового запису в channels.imessage.accounts.

    Для кожного облікового запису можна перевизначити такі поля, як cliPath, dbPath, allowFrom, groupPolicy, mediaMaxMb, налаштування історії та списки дозволених кореневих каталогів вкладень.

    Історія особистих повідомлень

    Установіть channels.imessage.dmHistoryLimit, щоб додавати до нових сеансів особистих повідомлень нещодавню декодовану історію imsg для цієї розмови. Використовуйте channels.imessage.dms["<sender>"].historyLimit для перевизначень для окремих відправників, зокрема 0, щоб вимкнути історію для певного відправника.

    Історія особистих повідомлень iMessage отримується на вимогу з imsg. Якщо не задавати dmHistoryLimit, глобальне початкове заповнення історії особистих повідомлень буде вимкнено, але додатне значення channels.imessage.dms["<sender>"].historyLimit для окремого відправника все одно ввімкне початкове заповнення для нього.

    Медіафайли, поділ на фрагменти та цілі доставлення

    Вкладення та медіафайли
    • Приймання вхідних вкладень типово вимкнено — установіть channels.imessage.includeAttachments: true, щоб передавати фотографії, голосові нотатки, відео та інші вкладення агенту. Коли цю функцію вимкнено, повідомлення iMessage, що містять лише вкладення, відкидаються до надходження агенту й можуть узагалі не створювати рядок журналу Inbound message.
    • Шляхи до віддалених вкладень можна отримувати через SCP, якщо задано remoteHost
    • Шляхи до вкладень мають відповідати дозволеним кореневим каталогам:
      • channels.imessage.attachmentRoots (локально)
      • channels.imessage.remoteAttachmentRoots (віддалений режим SCP)
      • Налаштовані кореневі каталоги розширюють типовий шаблон кореневого каталогу /Users/*/Library/Messages/Attachments (об’єднуються, а не замінюють його)
    • SCP використовує сувору перевірку ключа хоста (StrictHostKeyChecking=yes)
    • Розмір вихідних медіафайлів визначає channels.imessage.mediaMaxMb (типово 16 MB)
    Вихідний текст і поділ на фрагменти
    • Обмеження розміру текстового фрагмента: channels.imessage.textChunkLimit (типово 4000)
    • Режим поділу на фрагменти: channels.imessage.streaming.chunkMode
      • length (типово)
      • newline (поділ насамперед за абзацами)
    • Вихідне форматування Markdown — напівжирний текст, курсив, підкреслення та закреслення — перетворюється на текст із нативними стилями (одержувачі з macOS 15+ бачать форматування, а зі старішими версіями — звичайний текст без маркерів); таблиці Markdown перетворюються відповідно до режиму таблиць Markdown каналу
    • channels.imessage.sendTransport (auto типово, bridge, applescript) визначає, як imsg доставляє надіслані повідомлення
    Формати адресації

    Бажані явні цілі:

    • chat_id:123 (рекомендовано для стабільного маршрутизування)
    • chat_guid:...
    • chat_identifier:...

    Також підтримуються цілі у вигляді ідентифікаторів користувачів:

    • imessage:+1555...
    • sms:+1555...
    • user@example.com
    bash
    imsg chats --limit 20

    Дії приватного API

    Коли imsg launch працює, а openclaw channels status --probe повідомляє privateApi.available: true, інструмент повідомлень може використовувати нативні дії iMessage на додачу до звичайного надсилання тексту.

    Усі дії типово ввімкнено; використовуйте channels.imessage.actions, щоб вимкнути окремі дії:

    json5
    {  channels: {    imessage: {      actions: {        reactions: true,        edit: true,        unsend: true,        reply: true,        sendWithEffect: true,        sendAttachment: true,        renameGroup: true,        setGroupIcon: true,        addParticipant: true,        removeParticipant: true,        leaveGroup: true,        polls: true,      },    },  },}
    Доступні дії
    • react: Додає або видаляє реакції iMessage (messageId, emoji, remove). Підтримувані реакції відповідають любові, схваленню, несхваленню, сміху, наголосу та запитанню. Видалення без емодзі очищує будь-яку встановлену реакцію.
    • reply: Надсилає відповідь у гілці на наявне повідомлення (messageId, text або message, а також chatGuid, chatId, chatIdentifier або to). Для відповіді з вкладенням додатково потрібна збірка imsg, у якій send-rich підтримує --file.
    • sendWithEffect: Надсилає текст з ефектом iMessage (text або message, effect або effectId). Короткі назви: slam, loud, gentle, invisibleink, confetti, lasers, fireworks, balloon, heart, echo, happybirthday, shootingstar, sparkles, spotlight.
    • edit: Редагує надіслане повідомлення в підтримуваних версіях macOS/приватного API (messageId, text або newText). Редагувати можна лише повідомлення, надіслані самим Gateway.
    • unsend: Відкликає надіслане повідомлення в підтримуваних версіях macOS/приватного API (messageId). Відкликати можна лише повідомлення, надіслані самим Gateway.
    • upload-file: Надсилає медіафайли/файли (buffer у форматі base64 або завантажений media/path/filePath, filename, необов’язковий asVoice). Застарілий псевдонім: sendAttachment.
    • renameGroup, setGroupIcon, addParticipant, removeParticipant, leaveGroup: Керують груповими чатами, коли поточною ціллю є групова розмова. Ці дії змінюють ідентичність Messages на хості, тому їх має виконувати відправник-власник або клієнт Gateway operator.admin.
    • poll: Створює нативне опитування Apple Messages (pollQuestion, pollOption, повторений від 2 до 12 разів, а також chatGuid, chatId, chatIdentifier або to). Одержувачі з iOS/iPadOS/macOS 26+ бачать його та голосують у нативному інтерфейсі; користувачі старіших версій ОС натомість отримують текст «Sent a poll». Потрібен selectors.pollPayloadMessage.
    • poll-vote: Голосує в наявному опитуванні (pollId або messageId, а також рівно один із pollOptionIndex, pollOptionId або pollOptionText). Потрібні selectors.pollVoteMessage і метод RPC poll.vote.

    Прийняті вхідні опитування відображаються для агента із запитанням, пронумерованими підписами варіантів, кількістю голосів та ідентифікатором повідомлення опитування, потрібним для poll-vote.

    Ідентифікатори повідомлень

    Контекст вхідних повідомлень iMessage містить як короткі значення MessageSid, так і повні GUID повідомлень (MessageSidFull), якщо вони доступні. Короткі ідентифікатори діють у межах нещодавнього кешу відповідей на основі SQLite та перед використанням перевіряються щодо поточного чату. Якщо термін дії короткого ідентифікатора сплив, повторіть спробу з його MessageSidFull, указавши ціллю розмову, з якої його отримано. Повні ідентифікатори не обходять прив’язку до розмови або облікового запису, тому замініть ідентифікатор з іншого чату на ідентифікатор із поточної цілі. Віддалені делеговані виклики можуть відхиляти застарілі повні ідентифікатори, коли немає підтвердження їхньої належності до поточної розмови.

    Виявлення можливостей

    OpenClaw приховує дії приватного API лише тоді, коли кешований стан перевірки вказує, що міст недоступний. Якщо стан невідомий, дії залишаються видимими, а під час їх виконання перевірки запускаються відкладено, щоб перша дія могла успішно виконатися після imsg launch без окремого ручного оновлення стану.

    Сповіщення про прочитання та введення тексту

    Коли міст приватного API працює, прийняті вхідні чати позначаються як прочитані, а в особистих чатах індикатор введення з’являється щойно запит прийнято, поки агент готує контекст і генерує відповідь. Щоб вимкнути позначення як прочитаного, використовуйте:

    json5
    {  channels: {    imessage: {      sendReadReceipts: false,    },  },}

    У старіших збірках imsg, створених до появи списку можливостей для окремих методів, введення тексту та сповіщення про прочитання мовчки вимикаються; OpenClaw записує одноразове попередження після кожного перезапуску, щоб можна було визначити причину відсутності сповіщення.

    Вхідні реакції

    OpenClaw підписується на реакції iMessage та маршрутизує прийняті реакції як системні події, а не як звичайний текст повідомлення, тому реакція користувача не запускає звичайний цикл відповідей.

    Режим сповіщень визначає channels.imessage.reactionNotifications:

    • "own" (типово): сповіщати лише тоді, коли користувачі реагують на повідомлення, створені ботом.
    • "all": сповіщати про всі вхідні реакції від авторизованих відправників.
    • "off": ігнорувати вхідні реакції.

    Перевизначення для окремих облікових записів використовують channels.imessage.accounts.<id>.reactionNotifications.

    Реакції для схвалення (👍 / 👎)

    Коли approvals.exec.enabled або approvals.plugin.enabled має значення true, а запит маршрутизується до iMessage, Gateway доставляє запит на схвалення в нативному форматі та приймає реакцію для його вирішення:

    • 👍 (реакція Like) → allow-once
    • 👎 (реакція Dislike) → deny
    • allow-always залишається ручним запасним варіантом: надішліть /approve <id> allow-always як звичайну відповідь.

    Для обробки реакції ідентифікатор користувача, який її поставив, має бути явно вказаний серед осіб, уповноважених схвалювати запити. Список таких осіб зчитується з channels.imessage.allowFrom (або channels.imessage.accounts.<id>.allowFrom); додайте номер телефону користувача у форматі E.164 або адресу електронної пошти його Apple ID (цілі чату, як-от chat_id:*, не є допустимими записами цього списку). Запис із символом узагальнення "*" підтримується, але дає змогу будь-якому відправнику схвалювати запити; порожній список повністю вимикає швидке схвалення за допомогою реакції. Цей спосіб навмисно обходить reactionNotifications, dmPolicy і groupAllowFrom, оскільки для вирішення запиту на схвалення має значення лише явний список дозволених осіб.

    Авторизація текстової команди /approve використовує той самий список: коли channels.imessage.allowFrom не порожній, /approve <id> <decision> авторизується за цим списком осіб, уповноважених схвалювати запити (а не за ширшим списком дозволених особистих повідомлень), і відправники, яким дозволено надсилати особисті повідомлення, але яких немає в allowFrom, отримують явну відмову. Коли allowFrom порожній, продовжує діяти запасний механізм у межах того самого чату, а /approve авторизує всіх, кому дозволено надсилати особисті повідомлення. Додайте кожного оператора, який повинен мати змогу схвалювати запити — через /approve або за допомогою реакцій, — до allowFrom.

    Примітки для оператора:

    • Прив’язка реакції зберігається як у пам’яті, так і в постійному сховищі Gateway із ключами (TTL відповідає терміну дії схвалення), а Gateway також опитує запити, що очікують, щодо реакцій tapback, тож реакція tapback, яка надходить невдовзі після перезапуску Gateway, усе одно завершує схвалення.
    • Власна реакція tapback оператора is_from_me=true (наприклад, зі спареного пристрою Apple) завершує схвалення, якщо цей ідентифікатор явно вказано як схвалювача.
    • Запити на схвалення спрямовуються до групової розмови лише тоді, коли явно налаштовано схвалювачів; інакше схвалити міг би будь-який учасник групи.
    • Застарілі текстові реакції tapback (Liked "…" у вигляді звичайного тексту з дуже старих клієнтів Apple) не можуть завершувати схвалення, оскільки не містять GUID повідомлення; для визначення реакції потрібні структуровані метадані tapback, які надсилають сучасні клієнти macOS / iOS.

    Запис конфігурації

    iMessage за замовчуванням дозволяє ініційований каналом запис конфігурації (для /config set|unset, коли commands.config: true).

    Щоб вимкнути:

    json5
    {  channels: {    imessage: {      configWrites: false,    },  },}

    Об’єднання розділених надсилань у приватних повідомленнях (команда + URL в одному введенні)

    Коли користувач вводить разом команду та URL — наприклад, Dump https://example.com/article — застосунок Apple Messages розділяє надсилання на два окремі рядки chat.db:

    1. Текстове повідомлення ("Dump").
    2. Бульбашка попереднього перегляду URL ("https://...") із зображеннями попереднього перегляду OG як вкладеннями.

    У більшості конфігурацій ці два рядки надходять до OpenClaw з інтервалом ~0.8-2.0 s. Без об’єднання агент отримує лише команду в ході 1 (і часто відповідає «надішліть мені URL») до того, як URL надійде в ході 2. Це конвеєр надсилання Apple, а не поведінка, яку додає OpenClaw або imsg.

    channels.imessage.coalesceSameSenderDms вмикає для приватної розмови буферизацію послідовних рядків від одного відправника. Коли imsg надає структурний маркер попереднього перегляду URL balloon_bundle_id: "com.apple.messages.URLBalloonProvider" в одному з вихідних рядків, OpenClaw об’єднує лише це справжнє розділене надсилання, а всі інші буферизовані рядки залишає окремими ходами. У старіших збірках imsg, які взагалі не надають метаданих бульбашки, OpenClaw не може відрізнити розділене надсилання від окремих надсилань, тому натомість об’єднує весь пакет. Це зберігає поведінку до появи метаданих і не допускає регресії, за якої розділені надсилання Dump <url> знову оброблялися б у два ходи. Групові чати й надалі обробляють кожне повідомлення окремо, щоб зберегти структуру ходів за участю кількох користувачів.

    Коли вмикати

    Увімкніть, якщо:

    • Ви постачаєте Skills, які очікують command + payload в одному повідомленні (dump, paste, save, queue тощо).
    • Ваші користувачі вставляють URL разом із командами.
    • Для вас прийнятна додаткова затримка ходу в приватній розмові (див. нижче).

    Залиште вимкненим, якщо:

    • Вам потрібна мінімальна затримка команд для однослівних тригерів у приватних повідомленнях.
    • Усі ваші потоки — одноразові команди без подальшого надсилання корисного навантаження.

    Увімкнення

    json5
    {  channels: {    imessage: {      coalesceSameSenderDms: true, // увімкнення за бажанням (за замовчуванням: false)    },  },}

    Якщо прапорець увімкнено й явно не задано messages.inbound.byChannel.imessage або глобальний messages.inbound.debounceMs, вікно усунення брязкоту розширюється до 7000 ms (застаріле значення за замовчуванням — 0 ms, тобто без усунення брязкоту). Ширше вікно потрібне, оскільки інтервал розділеного надсилання попереднього перегляду URL від Apple може сягати кількох секунд, поки Messages.app створює рядок попереднього перегляду.

    Щоб налаштувати вікно самостійно:

    json5
    {  messages: {    inbound: {      byChannel: {        // 7000 ms охоплює спостережувані затримки попереднього перегляду URL у Messages.app.        imessage: 7000,      },    },  },}

    Компроміси

    • Для точного об’єднання потрібні актуальні метадані корисного навантаження imsg. За наявності balloon_bundle_id об’єднується лише справжнє розділене надсилання; описане вище резервне об’єднання без метаданих є тимчасовою зворотною сумісністю й буде вилучене, коли imsg почне об’єднувати розділені надсилання на попередньому рівні.
    • Додаткова затримка приватних повідомлень. Коли прапорець увімкнено, кожне приватне повідомлення (зокрема окремі керівні команди та подальші одиничні текстові повідомлення) очікує до завершення вікна усунення брязкоту перед обробкою на випадок, якщо надходить рядок попереднього перегляду URL. Повідомлення групових чатів обробляються миттєво.
    • Об’єднаний результат має обмеження. Об’єднаний текст обмежено 4000 символами з явним маркером …[truncated]; кількість вкладень — 20; кількість вихідних записів — 10 (понад цю межу зберігаються перший і найновіші). Кожен вихідний GUID відстежується в coalescedMessageGuids для подальшої телеметрії.
    • Лише для приватних повідомлень. Групові чати обробляють кожне повідомлення окремо, щоб бот залишався оперативним, коли вводять текст кілька людей.
    • Вмикається окремо для кожного каналу. Інші канали (Discord, Slack, Telegram, WhatsApp, …) не зазнають змін. У застарілих конфігураціях BlueBubbles, де задано channels.bluebubbles.coalesceSameSenderDms, це значення слід перенести до channels.imessage.coalesceSameSenderDms.

    Сценарії та те, що бачить агент

    Стовпець «Прапорець увімкнено» показує поведінку збірки imsg, яка надає balloon_bundle_id. У старіших збірках imsg, які взагалі не надають метаданих бульбашки, позначені нижче рядки «Два ходи» / «N ходів» натомість використовують застаріле об’єднання (один хід): OpenClaw не може структурно відрізнити розділене надсилання від окремих надсилань, тому зберігає об’єднання, що застосовувалося до появи метаданих. Точне розділення активується, коли збірка починає надавати метадані бульбашки.

    Введення користувача Результат chat.db Прапорець вимкнено (за замовчуванням) Прапорець увімкнено + вікно (imsg надає метадані бульбашки)
    Dump https://example.com (одне надсилання) 2 рядки з інтервалом ~1 s Два ходи агента: лише «Dump», потім URL Один хід: об’єднаний текст Dump https://example.com
    Save this 📎image.jpg caption (вкладення + текст) 2 рядки без метаданих бульбашки URL Два ходи Два ходи після виявлення метаданих; один об’єднаний хід у старих сеансах або сеансах до фіксації без метаданих
    /status (окрема команда) 1 рядок Миттєва обробка Очікування до завершення вікна, потім обробка
    Лише вставлений URL 1 рядок Миттєва обробка Очікування до завершення вікна, потім обробка
    Текст + URL, навмисно надіслані двома окремими повідомленнями з інтервалом у кілька хвилин 2 рядки поза вікном Два ходи Два ходи (між ними спливає вікно)
    Швидкий потік (>10 малих приватних повідомлень у межах вікна) N рядків без метаданих бульбашки URL N ходів N ходів після виявлення метаданих; один обмежений об’єднаний хід у старих сеансах або сеансах до фіксації без метаданих
    Двоє людей вводять текст у груповому чаті N рядків від M відправників M+ ходів (по одному для кожного пакета відправника) M+ ходів — групові чати не об’єднуються

    Відновлення вхідних повідомлень після перезапуску мосту або Gateway

    iMessage відновлює повідомлення, пропущені під час простою Gateway, і водночас пригнічує застарілу «лавину накопичених повідомлень», яку Apple може надіслати після відновлення Push. Ця типова поведінка завжди ввімкнена й побудована на усуненні дублікатів вхідних повідомлень.

    • Усунення дублікатів повторного відтворення. Кожне оброблене вхідне повідомлення записується за його Apple GUID у постійному стані Plugin (imessage.inbound-dedupe): резервується під час приймання та фіксується після обробки (звільняється в разі тимчасової помилки, щоб повторити спробу). Усе вже оброблене відкидається замість повторної обробки. Завдяки цьому відновлення може активно повторно відтворювати повідомлення без окремого обліку кожного з них.
    • Відновлення після простою. Під час запуску монітор пам’ятає останній оброблений rowid chat.db (збережений курсор для кожного облікового запису) і передає його до imsg watch.subscribe як since_rowid, тому imsg повторно відтворює рядки, що надійшли під час простою Gateway, а потім переходить до відстеження в реальному часі. Повторне відтворення обмежене 500 найновішими рядками та повідомленнями віком до ~2 годин, а механізм усунення дублікатів відкидає все вже оброблене.
    • Часова межа для застарілих накопичених повідомлень. Рядки вище початкової межі справді надходять у реальному часі; якщо дата надсилання одного з них більш ніж на ~15 хвилин передує часу його надходження, це накопичені повідомлення після Push-відновлення, і вони пригнічуються. Для повторно відтворених рядків (на межі або нижче неї) натомість використовується ширше вікно відновлення, тому нещодавно пропущене повідомлення доставляється, а давня історія — ні.

    Відновлення працює як у локальних, так і у віддалених конфігураціях cliPath, оскільки повторне відтворення since_rowid виконується через те саме RPC-з’єднання imsg. Відмінність полягає у вікні: коли Gateway може читати chat.db (локально), він прив’язується до початкової межі rowid, обмежує діапазон повторного відтворення й доставляє пропущені повідомлення віком до кількох годин. Через віддалений SSH cliPath він не може читати базу даних, тому повторне відтворення не обмежується, а до кожного рядка застосовується часова межа реального часу — нещодавно пропущені повідомлення все одно відновлюються, а старі накопичені повідомлення пригнічуються, але з вужчим вікном реального часу. Для ширшого вікна відновлення запускайте Gateway на комп’ютері Mac із Messages.

    Сигнал, видимий оператору

    Пригнічені накопичені повідомлення реєструються на типовому рівні й ніколи не відкидаються без повідомлення (прапорець recovery указує, яке вікно застосовано):

    text
    imessage: пригнічено застарілі вхідні накопичені повідомлення account=<id> sent=<iso> recovery=<bool> (&lt;N&gt; пригнічено від запуску)

    Міграція

    channels.imessage.catchup.* застарів — відновлення після простою виконується автоматично й не потребує конфігурації для нових установок. Наявні конфігурації з catchup.enabled: true і надалі підтримуються як профіль сумісності для вікна повторного відтворення під час відновлення. Вимкнені блоки наздоганяння (enabled: false або без enabled: true) вилучено; openclaw doctor --fix видаляє їх.

    Усунення несправностей

    imsg не знайдено або RPC не підтримується

    Перевірте двійковий файл і підтримку RPC:

    bash
    imsg rpc --helpimsg status --jsonopenclaw channels status --probe

    Якщо перевірка повідомляє, що RPC не підтримується, оновіть imsg. Якщо дії приватного API недоступні, запустіть imsg launch у сеансі користувача macOS, який увійшов у систему, і повторіть перевірку. Якщо Gateway не працює в macOS, використовуйте описану вище конфігурацію віддаленого Mac через SSH замість типового локального шляху imsg.

    Повідомлення надсилаються, але вхідні iMessage не надходять

    Спочатку перевірте, чи надійшло повідомлення на локальний Mac. Якщо chat.db не змінюється, OpenClaw не може отримати повідомлення, навіть якщо imsg status --json повідомляє про справний міст.

    bash
    imsg chats --limit 10 --jsonimsg watch --chat-id <chat-id> --jsonsqlite3 ~/Library/Messages/chat.db \"select datetime(max(date)/1000000000 + 978307200, 'unixepoch', 'localtime'), max(ROWID) from message;"

    Якщо повідомлення, надіслані з телефону, не створюють нових рядків, відновіть роботу Messages у macOS і рівня Apple Push, перш ніж змінювати конфігурацію OpenClaw. Часто достатньо одноразового оновлення служби:

    bash
    launchctl kickstart -k system/com.apple.apsdlaunchctl kickstart -k gui/$(id -u)/com.apple.CommCenterlaunchctl kickstart -k gui/$(id -u)/com.apple.identityservicesdlaunchctl kickstart -k gui/$(id -u)/com.apple.imagentimsg launchopenclaw gateway restart

    Надішліть нове повідомлення iMessage з телефона та переконайтеся, що з’явився новий рядок chat.db або подія imsg watch, перш ніж налагоджувати сеанси OpenClaw. Не запускайте це як періодичний цикл повторного запуску моста; повторні imsg launch разом із перезапусками Gateway під час активної роботи можуть перервати доставлення та залишити незавершені запуски каналу в завислому стані.

    Gateway не запущено в macOS

    Стандартний cliPath: "imsg" має виконуватися на Mac, на якому здійснено вхід у Messages. У Linux або Windows задайте для channels.imessage.cliPath сценарій-обгортку, який підключається до цього Mac через SSH і запускає imsg "$@".

    bash
    #!/usr/bin/env bashexec ssh -T messages-mac imsg "$@"

    Потім виконайте:

    bash
    openclaw channels status --probe --channel imessage
    Приватні повідомлення ігноруються

    Перевірте:

    • channels.imessage.dmPolicy
    • channels.imessage.allowFrom
    • схвалення сполучення (openclaw pairing list imessage)
    Групові повідомлення ігноруються

    Перевірте:

    • channels.imessage.groupPolicy
    • channels.imessage.groupAllowFrom
    • channels.imessage.groups поведінку списку дозволених
    • налаштування шаблону згадок (agents.list[].groupChat.mentionPatterns)
    Віддалені вкладення не завантажуються

    Перевірте:

    • channels.imessage.remoteHost
    • channels.imessage.remoteAttachmentRoots
    • автентифікацію за ключем SSH/SCP з хоста Gateway
    • наявність ключа хоста в ~/.ssh/known_hosts на хості Gateway
    • доступність віддаленого шляху для читання на Mac, де працює Messages
    Запити дозволів macOS було пропущено

    Повторно запустіть команди в інтерактивному терміналі з графічним інтерфейсом у контексті того самого користувача й сеансу та схваліть запити:

    bash
    imsg chats --limit 1imsg send <handle> "test"

    Переконайтеся, що для контексту процесу, у якому працює OpenClaw/imsg, надано повний доступ до диска й дозвіл на автоматизацію.

    Посилання на довідник із налаштування

    Пов’язані матеріали

    Was this useful?
    On this page

    On this page