Mainstream messaging
iMessage
Статус: нативная интеграция с внешним CLI. Gateway запускает imsg rpc и обменивается данными по JSON-RPC через стандартные потоки ввода-вывода — отдельный демон или порт не требуется. Для полноценного канала iMessage настоятельно рекомендуется режим Private API; ответы, реакции Tapback, эффекты, опросы, ответы с вложениями и групповые действия требуют imsg launch и успешной проверки Private API.
При распространенной локальной настройке мастер OpenClaw может предложить подтверждаемую пользователем установку или обновление imsg через Homebrew на Mac с выполненным входом в Messages. Ручная настройка и топологии с SSH-оберткой остаются в ведении оператора: устанавливайте или обновляйте imsg в том же пользовательском контексте, в котором будет запускаться Gateway или обертка.
Ответы, реакции Tapback, эффекты, опросы, вложения и управление группами.
Для личных сообщений iMessage по умолчанию используется режим сопряжения.
Используйте SSH-обертку, если Gateway работает не на Mac с Messages.
Полный справочник по полям iMessage.
Быстрая настройка
Локальный Mac (быстрый вариант)
Установите и проверьте imsg
brew install steipete/tap/imsgbrew update && brew upgrade imsgimsg rpc --helpimsg launchopenclaw channels status --probeКогда локальный мастер настройки обнаруживает отсутствие команды imsg по умолчанию, он может предложить установить steipete/tap/imsg через Homebrew. Если он обнаруживает управляемый Homebrew экземпляр imsg, то может предложить переустановить или обновить его. Пользовательские обертки cliPath не изменяются.
Настройте OpenClaw
{channels: {imessage: {enabled: true,cliPath: "/usr/local/bin/imsg",dbPath: "/Users/user/Library/Messages/chat.db",},},}Запустите Gateway
openclaw gatewayПодтвердите первое сопряжение для личного сообщения (dmPolicy по умолчанию)
openclaw pairing list imessageopenclaw pairing approve imessage <CODE>Срок действия запросов на сопряжение истекает через 1 час.
Удаленный Mac через SSH
В большинстве конфигураций SSH не требуется. Используйте эту топологию, только если Gateway невозможно запустить на Mac с выполненным входом в Messages. OpenClaw требуется только совместимый со стандартными потоками ввода-вывода cliPath, поэтому в cliPath можно указать сценарий-обертку, который подключается по SSH к удаленному Mac и запускает imsg.
Устанавливайте и обновляйте imsg на этом удаленном Mac, а не на хосте Gateway:
ssh messages-mac 'brew install steipete/tap/imsg && brew update && brew upgrade imsg'#!/usr/bin/env bashexec ssh -T messages-mac imsg "$@"Рекомендуемая конфигурация при включенных вложениях:
{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, требуется полный доступ к диску (для доступа к базе данных Messages). - Для отправки сообщений через Messages.app требуется разрешение на автоматизацию.
- Для расширенных действий (реакции / редактирование / отмена отправки / ответы в ветке / эффекты / опросы / групповые операции) необходимо отключить System Integrity Protection — см. Включение Private API imsg. Базовая отправка и получение текста и медиафайлов работают без этого.
Отправка через SSH-обертку завершается ошибкой AppleEvents -1743
В конфигурации с удаленным подключением по SSH чтение чатов, прохождение channels status --probe и обработка входящих сообщений могут работать, тогда как исходящие сообщения по-прежнему завершаются ошибкой авторизации AppleEvents:
Нет разрешения на отправку событий Apple в Messages. (-1743)Проверьте базу данных TCC пользователя удаленного Mac с выполненным входом или откройте System Settings > Privacy & Security > Automation. Если запись Automation зарегистрирована для /usr/libexec/sshd-keygen-wrapper, а не для imsg или процесса локальной оболочки, macOS может не предоставлять пригодный переключатель Messages для этого серверного клиента SSH:
kTCCServiceAppleEvents | /usr/libexec/sshd-keygen-wrapper | auth_value=0 | com.apple.MobileSMSВ таком состоянии повторный запуск tccutil reset AppleEvents или imsg send через ту же SSH-обертку может продолжать завершаться ошибкой, поскольку разрешение на автоматизацию Messages требуется контексту процесса SSH-обертки, а не приложению, которому интерфейс может его предоставить.
Вместо этого используйте один из поддерживаемых контекстов процесса imsg:
- Запускайте Gateway или хотя бы мост
imsgв локальном сеансе пользователя, вошедшего в Messages. - Запускайте Gateway через LaunchAgent этого пользователя после предоставления полного доступа к диску и разрешения на автоматизацию из того же сеанса.
- Если вы сохраняете топологию SSH с двумя пользователями, перед включением канала убедитесь, что фактическая исходящая отправка
imsg sendуспешно выполняется через конкретную обертку. Если предоставить ей разрешение на автоматизацию невозможно, вместо отправки через SSH-обертку перейдите на однопользовательскую конфигурациюimsg.
Включение Private API imsg
imsg поставляется с двумя режимами работы. Для OpenClaw рекомендуется режим Private API, поскольку он предоставляет каналу нативные действия iMessage, ожидаемые пользователями. Базовый режим по-прежнему удобен для установок с низким уровнем риска, первоначальной проверки или хостов, где невозможно отключить SIP.
- Базовый режим (по умолчанию, изменения SIP не требуются): исходящий текст и медиафайлы через
send, наблюдение за входящими сообщениями и история, список чатов. Именно это доступно сразу после новой установкиbrew install steipete/tap/imsgи предоставления стандартных разрешений macOS, перечисленных выше. - Режим Private API:
imsgвнедряет вспомогательную динамическую библиотеку в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 и внедрить вспомогательную динамическую библиотеку вMessages.app.imsg launchотказывается выполнять внедрение, если SIP включен.
Метод внедрения вспомогательной библиотеки использует собственную динамическую библиотеку imsg для доступа к закрытым API Messages. В тракте iMessage OpenClaw отсутствует сторонний сервер или среда выполнения BlueBubbles.
Настройка
-
Установите (или обновите)
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для каждого метода, чтобы перед началом работы можно было узнать, что поддерживает текущая сборка. -
Отключите System Integrity Protection и (в современных версиях macOS) Library Validation. Для внедрения вспомогательной библиотеки dylib не от Apple в подписанный Apple процесс
Messages.appнеобходимо отключить SIP и ослабить проверку библиотек. Шаг с SIP в режиме восстановления зависит от версии macOS:- macOS 10.13–10.15 (Sierra–Catalina): отключите Library Validation через Терминал, перезагрузитесь в режим восстановления, выполните
csrutil disable, затем перезапустите систему. - macOS 11+ (Big Sur и более поздние версии), Intel: загрузитесь в режим восстановления (или Internet Recovery), выполните
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 truemacOS 26 (Tahoe), проверено на 26.5.1: отключённого SIP вместе с приведённой выше командой
DisableLibraryValidationдостаточно для внедрения вспомогательного модуля во всех версиях с 26.0 по 26.5.x. Параметры boot-args не требуются. Файл 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, не ослабляя дополнительные общесистемные средства защиты. - macOS 10.13–10.15 (Sierra–Catalina): отключите Library Validation через Терминал, перезагрузитесь в режим восстановления, выполните
-
Внедрите вспомогательный модуль. При отключённом SIP и выполненном входе в Messages.app:
bash imsg launchimsg launchотказывается выполнять внедрение, если SIP всё ещё включён, поэтому эта команда также подтверждает выполнение шага 2. -
Проверьте мост из OpenClaw:
bash openclaw channels status --probeЗапись iMessage должна сообщать
works, аimsg status --json | jq '{rpc_methods, selectors}'должен показывать возможности, предоставляемые вашей сборкой macOS. Для создания опросов требуетсяselectors.pollPayloadMessage; для голосования требуются иselectors.pollVoteMessage, и метод RPCpoll.vote. Плагин OpenClaw объявляет только действия, поддерживаемые кэшированным результатом проверки, а при пустом кэше действует оптимистично и выполняет проверку при первой отправке.
Если openclaw channels status --probe сообщает, что канал находится в состоянии works, но отдельные действия при отправке вызывают ошибку "Для iMessage <action> требуется мост закрытого API imsg", снова выполните imsg launch — вспомогательный модуль может выгрузиться (после перезапуска Messages.app, обновления ОС и т. п.), а кэшированный статус available: true продолжит объявлять действия до следующего обновления проверки.
Если SIP остаётся включённым
Если отключение SIP неприемлемо для вашей модели угроз:
imsgпереходит в базовый режим — только текст, медиафайлы и получение сообщений.- Плагин OpenClaw по-прежнему объявляет отправку текста и медиафайлов, а также мониторинг входящих сообщений; он скрывает
react,edit,unsend,reply,sendWithEffectи групповые операции из набора действий (согласно проверке возможностей для каждого метода). - Можно использовать отдельный Mac без Apple Silicon (или выделенный Mac для бота) с отключённым SIP для рабочей нагрузки iMessage, сохранив 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(по умолчанию)opendisabled
Список разрешённых отправителей групп: 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:
- Системный промпт конкретной группы (
groups["<chat_id>"].systemPrompt): используется, если запись конкретной группы присутствует в карте и в ней определён ключsystemPrompt. ЕслиsystemPromptявляется пустой строкой (""), подстановочный знак подавляется и системный промпт к этой группе не применяется. - Системный промпт для подстановочного знака группы (
groups["*"].systemPrompt): используется, если запись конкретной группы полностью отсутствует в карте либо существует, но не определяет ключsystemPrompt.
{ 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>
Пример:
{ 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.
Типичная процедура:
- Создайте отдельного пользователя macOS или войдите в его учётную запись.
- Войдите в Messages с Apple ID бота от имени этого пользователя.
- Установите
imsgдля этого пользователя. - Создайте оболочку SSH, чтобы OpenClaw мог запускать
imsgв контексте этого пользователя. - Укажите в
channels.imessage.accounts.<id>.cliPathи.dbPathпрофиль этого пользователя.
При первом запуске может потребоваться предоставить разрешения через графический интерфейс (Automation и Full Disk Access) в сеансе пользователя бота.
Удалённый Mac через Tailscale (пример)
Типичная топология:
- Gateway работает на Linux/виртуальной машине
- iMessage и
imsgработают на Mac в вашей сети tailnet - оболочка
cliPathиспользует SSH для запускаimsg remoteHostвключает получение вложений через SCP
Пример:
{ 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", }, },}#!/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 МБ)
Исходящий текст и разбиение
- ограничение размера фрагмента текста:
channels.imessage.textChunkLimit(по умолчанию 4000) - режим разбиения:
channels.imessage.streaming.chunkModelength(по умолчанию)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
imsg chats --limit 20Действия закрытого API
Когда imsg launch работает, а openclaw channels status --probe сообщает privateApi.available: true, инструмент сообщений может использовать встроенные действия iMessage в дополнение к обычной отправке текста.
Все действия включены по умолчанию; используйте channels.imessage.actions, чтобы отключать отдельные действия:
{ 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+ видят его и голосуют во встроенном интерфейсе; в более ранних версиях ОС вместо него отображается текст «Отправлен опрос». Требуетсяselectors.pollPayloadMessage. - poll-vote: голосование в существующем опросе (
pollIdилиmessageId, а также ровно один изpollOptionIndex,pollOptionIdилиpollOptionText). Требуютсяselectors.pollVoteMessageи метод RPCpoll.vote.
Принятые входящие опросы отображаются агенту с вопросом, пронумерованными вариантами ответа, количеством голосов и идентификатором сообщения опроса, необходимым для poll-vote.
Идентификаторы сообщений
Контекст входящего сообщения iMessage содержит как короткие значения MessageSid, так и полные GUID сообщений (MessageSidFull), если они доступны. Короткие идентификаторы действуют только в недавнем кэше ответов на базе SQLite и перед использованием сверяются с текущим чатом. Если срок действия короткого идентификатора истёк или он относится к другому чату, повторите попытку с полным MessageSidFull.
Определение возможностей
OpenClaw скрывает действия закрытого API, только когда кэшированное состояние проверки указывает на недоступность моста. Если состояние неизвестно, действия остаются видимыми, а при их выполнении проверки запускаются отложенно, поэтому первое действие может успешно выполниться после imsg launch без отдельного ручного обновления состояния.
Отчёты о прочтении и индикатор набора
Когда мост закрытого API работает, принятые входящие чаты помечаются как прочитанные, а в личных чатах сразу после принятия запроса отображается индикатор набора, пока агент подготавливает контекст и формирует ответ. Чтобы отключить отметку о прочтении, используйте:
{ 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 доставляет запрос подтверждения через встроенный интерфейс и принимает реакцию для его обработки:
👍(реакция «Нравится») →allow-once👎(реакция «Не нравится») →denyallow-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).
Чтобы отключить:
{ channels: { imessage: { configWrites: false, }, },}Объединение разделённых личных сообщений (команда + URL в одном сообщении)
Когда пользователь вводит команду вместе с URL — например, Dump https://example.com/article — приложение Apple Messages разделяет отправку на две отдельные строки chat.db:
- Текстовое сообщение (
"Dump"). - Карточка предпросмотра URL (
"https://...") с изображениями предпросмотра OG в виде вложений.
В большинстве конфигураций эти две строки поступают в OpenClaw с интервалом ~0.8-2.0 с. Без объединения агент получает только команду в ходе 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в одном сообщении (выгрузка, вставка, сохранение, постановка в очередь и т. д.). - Ваши пользователи вставляют URL вместе с командами.
- Для вас приемлема дополнительная задержка хода в личных сообщениях (см. ниже).
Оставьте отключённым, если:
- Вам нужна минимальная задержка команды для однословных триггеров в личных сообщениях.
- Все ваши сценарии представляют собой однократные команды без последующей отправки полезной нагрузки.
Включение
{ channels: { imessage: { coalesceSameSenderDms: true, // включение (по умолчанию: false) }, },}Если флаг включён и явно не заданы messages.inbound.byChannel.imessage или глобальный messages.inbound.debounceMs, окно устранения дребезга расширяется до 7000 мс (устаревшее значение по умолчанию — 0 мс, то есть без устранения дребезга). Более широкое окно необходимо, поскольку интервал между частями разделённой отправки с предпросмотром URL от Apple может достигать нескольких секунд, пока Messages.app создаёт строку предпросмотра.
Чтобы настроить окно самостоятельно:
{ messages: { inbound: { byChannel: { // 7000 мс охватывают наблюдаемые задержки предпросмотра 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 с | Два хода агента: только «Выгрузить», затем 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 в постоянное состояние плагина (
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 показывает, какое окно применялось):
imessage: подавлены устаревшие входящие накопившиеся сообщения account=<id> sent=<iso> recovery=<bool> (<N> подавлено с момента запуска)Миграция
channels.imessage.catchup.* устарел — восстановление после простоя выполняется автоматически и не требует настройки в новых конфигурациях. Существующие конфигурации с catchup.enabled: true продолжают поддерживаться как профиль совместимости для окна повторного воспроизведения при восстановлении. Отключённые блоки наверстывания (enabled: false или без enabled: true) выведены из эксплуатации; openclaw doctor --fix удаляет их.
Устранение неполадок
imsg не найден или RPC не поддерживается
Проверьте исполняемый файл и поддержку RPC:
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 сообщает об исправном мосте.
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;"Если сообщения, отправленные с телефона, не создают новых строк, восстановите работу macOS Messages и слоя Apple Push, прежде чем изменять конфигурацию OpenClaw. Часто достаточно однократного обновления служб:
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 с телефона и, прежде чем отлаживать сеансы OpenClaw, убедитесь, что появилась новая строка chat.db или событие imsg watch. Не запускайте это как периодический цикл перезапуска моста: повторные imsg launch и перезапуски Gateway во время активной работы могут прерывать доставку и оставлять выполняющиеся операции канала в зависшем состоянии.
Gateway не запущен в macOS
Стандартный cliPath: "imsg" должен выполняться на компьютере Mac, где выполнен вход в Messages. В Linux или Windows задайте для channels.imessage.cliPath скрипт-обёртку, который подключается к этому Mac по SSH и запускает imsg "$@".
#!/usr/bin/env bashexec ssh -T messages-mac imsg "$@"Затем выполните:
openclaw channels status --probe --channel imessageЛичные сообщения игнорируются
Проверьте:
channels.imessage.dmPolicychannels.imessage.allowFrom- подтверждения сопряжения (
openclaw pairing list imessage)
Групповые сообщения игнорируются
Проверьте:
channels.imessage.groupPolicychannels.imessage.groupAllowFromchannels.imessage.groupsповедение списка разрешённых пользователей- настройку шаблона упоминаний (
agents.list[].groupChat.mentionPatterns)
Не удаётся получить удалённые вложения
Проверьте:
channels.imessage.remoteHostchannels.imessage.remoteAttachmentRoots- аутентификацию по ключу SSH/SCP с хоста Gateway
- наличие ключа хоста в
~/.ssh/known_hostsна хосте Gateway - доступность удалённого пути для чтения на компьютере Mac, где запущен Messages
Запросы разрешений macOS были пропущены
Повторно выполните команды в интерактивном терминале с графическим интерфейсом в контексте того же пользователя и сеанса, затем подтвердите запросы:
imsg chats --limit 1imsg send <handle> "test"Убедитесь, что разрешения Full Disk Access + Automation предоставлены контексту процесса, в котором выполняется OpenClaw/imsg.
Ссылки на справочник по конфигурации
Связанные материалы
- Обзор каналов — все поддерживаемые каналы
- Удаление BlueBubbles и использование iMessage через imsg — объявление и краткое описание миграции
- Переход с BlueBubbles — таблица преобразования конфигурации и пошаговое переключение
- Сопряжение — аутентификация в личных сообщениях и процесс сопряжения
- Группы — поведение групповых чатов и ограничение по упоминаниям
- Маршрутизация каналов — маршрутизация сеансов для сообщений
- Безопасность — модель доступа и усиление защиты