---
read_when:
    - Настройка поддержки iMessage
    - Отладка отправки и получения сообщений в iMessage
summary: Встроенная поддержка iMessage через imsg (JSON-RPC поверх stdio) с действиями приватного API для ответов, реакций Tapback, эффектов, опросов, вложений и управления группами. Рекомендуется для новых конфигураций OpenClaw с iMessage, если хост соответствует требованиям.
title: iMessage
x-i18n:
    generated_at: "2026-07-16T16:35:57Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 32
    provider: openai
    source_hash: 78b7ff7621e66e3b0122b5581c097140b7f62998b78981741bd3edbc0e1608bd
    source_path: channels/imessage.md
    workflow: 16
---

<Note>
Для обычного развертывания OpenClaw с iMessage запускайте Gateway и `imsg` на одном и том же хосте macOS с выполненным входом в Messages. Если Gateway работает в другом месте, укажите в `channels.imessage.cliPath` прозрачную SSH-обертку, которая запускает `imsg` на Mac.

**Восстановление входящих сообщений выполняется автоматически.** После перезапуска моста или Gateway iMessage повторно воспроизводит сообщения, пропущенные во время простоя, и подавляет устаревший «взрыв очереди», который Apple может выдать после восстановления Push, устраняя дубликаты, чтобы ничего не отправлялось дважды. Включать это в конфигурации не требуется — см. [Восстановление входящих сообщений после перезапуска моста или Gateway](#inbound-recovery-after-a-bridge-or-gateway-restart).
</Note>

<Warning>
Поддержка BlueBubbles удалена. Перенесите конфигурации `channels.bluebubbles` на `channels.imessage`; OpenClaw поддерживает iMessage только через `imsg`. Начните с [Удаление BlueBubbles и путь iMessage через imsg](/ru/announcements/bluebubbles-imessage), чтобы прочитать краткое объявление, или с [Переход с BlueBubbles](/ru/channels/imessage-from-bluebubbles), чтобы ознакомиться с полной таблицей миграции.
</Warning>

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

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

<CardGroup cols={3}>
  <Card title="Действия Private API" icon="wand-sparkles" href="#private-api-actions">
    Ответы, реакции tapback, эффекты, опросы, вложения и управление группами.
  </Card>
  <Card title="Сопряжение" icon="link" href="/ru/channels/pairing">
    По умолчанию личные сообщения iMessage используют режим сопряжения.
  </Card>
  <Card title="Удаленный Mac" icon="terminal" href="#remote-mac-over-ssh">
    Используйте SSH-обертку, если Gateway работает не на Mac с Messages.
  </Card>
  <Card title="Справочник по конфигурации" icon="settings" href="/ru/gateway/config-channels#imessage">
    Полный справочник по полям iMessage.
  </Card>
</CardGroup>

## Быстрая настройка

<Tabs>
  <Tab title="Локальный Mac (быстрый способ)">
    <Steps>
      <Step title="Установка и проверка imsg">

```bash
brew install steipete/tap/imsg
brew update && brew upgrade imsg
imsg rpc --help
imsg launch
openclaw channels status --probe
```

        Когда локальный мастер настройки обнаруживает отсутствие команды `imsg` по умолчанию, он может предложить установить `steipete/tap/imsg` через Homebrew. Если обнаружен управляемый Homebrew экземпляр `imsg`, мастер может предложить переустановить или обновить его. Пользовательские обертки `cliPath` не изменяются.

      </Step>

      <Step title="Настройка OpenClaw">

```json5
{
  channels: {
    imessage: {
      enabled: true,
      cliPath: "/usr/local/bin/imsg",
      dbPath: "/Users/user/Library/Messages/chat.db",
    },
  },
}
```

      </Step>

      <Step title="Запуск Gateway">

```bash
openclaw gateway
```

      </Step>

      <Step title="Подтверждение сопряжения для первого личного сообщения (dmPolicy по умолчанию)">

```bash
openclaw pairing list imessage
openclaw pairing approve imessage <CODE>
```

        Срок действия запросов на сопряжение истекает через 1 час.
      </Step>
    </Steps>

  </Tab>

  <Tab title="Удаленный 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 bash
exec 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`).

<Warning>
Любая обертка `cliPath` или SSH-прокси перед `imsg` ДОЛЖНЫ работать как прозрачный канал stdio для долгоживущего соединения JSON-RPC. В течение всего времени работы канала OpenClaw обменивается через stdin/stdout обертки небольшими сообщениями JSON-RPC, разделенными символами новой строки:

- Пересылайте каждый фрагмент или строку из stdin **сразу после появления доступных байтов** — не ждите EOF.
- Оперативно пересылайте каждый фрагмент или строку из stdout в обратном направлении.
- Сохраняйте символы новой строки.
- Избегайте блокирующего чтения фиксированного размера (`read(4096)`, `cat | buffer`, стандартный `read` оболочки), которое может задерживать небольшие фреймы.
- Не смешивайте stderr с потоком stdout JSON-RPC.

Обертка, буферизующая stdin до заполнения крупного блока, вызывает симптомы, похожие на сбой iMessage, — `imsg rpc timeout (chats.list)` или повторные перезапуски канала, — хотя сам `imsg rpc` исправен. `ssh -T host imsg "$@"` (выше) безопасен, поскольку передает аргументы `cliPath` от OpenClaw, например `rpc` и `--db`. Конвейеры наподобие `ssh host imsg | grep -v '^DEBUG'` НЕ безопасны: даже инструменты с построчной буферизацией могут задерживать фреймы; если фильтрация необходима, используйте `stdbuf -oL -eL` на каждом этапе.
</Warning>

  </Tab>
</Tabs>

## Требования и разрешения (macOS)

- На Mac, где работает `imsg`, должен быть выполнен вход в Messages.
- Для контекста процесса, в котором работает OpenClaw/`imsg`, требуется полный доступ к диску (для доступа к базе данных Messages).
- Для отправки сообщений через Messages.app требуется разрешение на автоматизацию.
- Для расширенных действий (реакция / редактирование / отмена отправки / ответ в ветке / эффекты / опросы / групповые операции) необходимо отключить System Integrity Protection — см. [Включение Private API imsg](#enabling-the-imsg-private-api). Базовая отправка и получение текста и медиафайлов работают без этого.

<Tip>
Разрешения предоставляются отдельно для каждого контекста процесса. Если Gateway работает без графического сеанса (LaunchAgent/SSH), один раз выполните интерактивную команду в том же контексте, чтобы вызвать запросы разрешений:

```bash
imsg chats --limit 1
# или
imsg send <handle> "test"
```

</Tip>

<Accordion title="Отправка через 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-обертку могут по-прежнему завершаться ошибкой, поскольку разрешение на автоматизацию Messages требуется контексту процесса SSH-обертки, а не приложению, которому интерфейс может предоставить доступ.

Вместо этого используйте один из поддерживаемых контекстов процесса `imsg`:

- Запускайте Gateway или хотя бы мост `imsg` в локальном сеансе пользователя, вошедшего в Messages.
- Запускайте Gateway через LaunchAgent этого пользователя после предоставления полного доступа к диску и разрешения на автоматизацию из того же сеанса.
- Если сохраняется SSH-топология с двумя пользователями, перед включением канала убедитесь, что фактическая исходящая отправка `imsg send` успешно выполняется через точную используемую обертку. Если ей невозможно предоставить разрешение на автоматизацию, вместо использования SSH-обертки для отправки перенастройте систему на однопользовательскую конфигурацию `imsg`.

</Accordion>

## Включение 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.

<Warning>
**Отключение SIP — это реальный компромисс в области безопасности.** SIP является одним из основных механизмов защиты macOS от выполнения измененного системного кода; его отключение во всей системе расширяет поверхность атаки и может вызвать побочные эффекты. В частности, **отключение SIP на Mac с Apple Silicon также лишает возможности устанавливать и запускать приложения iOS на Mac**.

Рассматривайте это как осознанное эксплуатационное решение, особенно на основном личном Mac. Для качественного производственного развертывания OpenClaw с iMessage предпочтительно использовать выделенный Mac или отдельного пользователя-бота macOS, для которого приемлемо включение моста. Если ваша модель угроз не допускает отключения SIP ни на одном устройстве, встроенный iMessage ограничивается базовым режимом — только отправкой и получением текста и медиафайлов, без реакций / редактирования / отмены отправки / эффектов / групповых операций.
</Warning>

### Настройка

1. **Установите (или обновите) `imsg`** на Mac, где работает Messages.app:

   ```bash
   brew install steipete/tap/imsg
   brew update && brew upgrade imsg
   imsg --version
   imsg status --json
   ```

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

2. **Отключите защиту целостности системы (System Integrity Protection), а в современных версиях macOS — также проверку библиотек (Library Validation).** Для внедрения вспомогательной библиотеки dylib не от Apple в подписанный Apple процесс `Messages.app` необходимо отключить SIP **и** ослабить проверку библиотек. Порядок отключения SIP в режиме восстановления зависит от версии macOS:
   - **macOS 10.13–10.15 (Sierra–Catalina):** отключите Library Validation через 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` как к платформенному исполняемому файлу, поэтому вспомогательный компонент с подписью ad hoc отклоняется (`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:** для внедрения вспомогательного компонента во всех версиях от 26.0 до 26.5.x достаточно отключённого SIP **вместе** с приведённой выше командой `DisableLibraryValidation`. **Параметры 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 отклоняет вспомогательный компонент с подписью ad hoc при загрузке, поэтому мост не переходит в состояние готовности, а запуск завершается по тайм-ауту. Именно с таким тайм-аутом чаще всего сталкиваются в 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`. Плагин OpenClaw объявляет только действия, поддерживаемые кэшированной проверкой, но при пустом кэше исходит из оптимистичных предположений и выполняет проверку при первой отправке.

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

### Если SIP остаётся включённым

Если отключение SIP неприемлемо для вашей модели угроз:

- `imsg` переходит в базовый режим — только текст, мультимедиа и получение сообщений.
- Плагин OpenClaw по-прежнему объявляет отправку текста и мультимедиа, а также мониторинг входящих сообщений; он скрывает `react`, `edit`, `unsend`, `reply`, `sendWithEffect` и групповые операции из набора действий в соответствии с проверкой возможностей каждого метода.
- Для нагрузки iMessage можно использовать отдельный Mac без Apple Silicon или выделенный Mac для бота с отключённым SIP, сохранив SIP включённым на основных устройствах. См. ниже раздел [Выделенный пользователь macOS для бота (отдельная учётная запись iMessage)](#deployment-patterns).

## Управление доступом и маршрутизация

<Tabs>
  <Tab title="Политика личных сообщений">
    `channels.imessage.dmPolicy` управляет личными сообщениями:

    - `pairing` (по умолчанию)
    - `allowlist` (требуется хотя бы одна запись `allowFrom`)
    - `open` (требуется, чтобы `allowFrom` содержал `"*"`)
    - `disabled`

    Поле списка разрешений: `channels.imessage.allowFrom`.

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

  </Tab>

  <Tab title="Политика групп и упоминания">
    `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`.

    <Warning>
    Маршрутизация групп при `groupPolicy: "allowlist"` последовательно применяет **две** проверки:

    1. **Список разрешённых отправителей** (`channels.imessage.groupAllowFrom`) — дескриптор, `accessGroup:<name>`, `chat_guid`, `chat_identifier` или `chat_id`. Пустой итоговый список (без `groupAllowFrom` и резервного `allowFrom`) блокирует всех отправителей групп.
    2. **Реестр групп** (`channels.imessage.groups`) — применяется, когда карта содержит записи: чат должен соответствовать явной записи для `chat_id` или подстановочному знаку `groups: { "*": { ... } }`. Если `groups` пуст или отсутствует, допуск определяется только списком разрешённых отправителей.

    Если итоговый список разрешённых отправителей групп не настроен, каждое групповое сообщение отбрасывается до проверки реестра. Каждая проверка имеет собственный сигнал уровня `warn` на стандартном уровне журналирования и указывает отдельное исправление:

    - один раз для каждой учётной записи при запуске, если итоговый список разрешённых отправителей групп пуст: `imessage: groupPolicy="allowlist" for account "<id>" but no group sender allowlist is configured ...` — исправьте, задав `channels.imessage.groupAllowFrom` (или `allowFrom`); добавление только записей `groups` не изменит ситуацию: проверка 1 продолжит блокировать всех отправителей.
    - один раз для каждого `chat_id` во время выполнения, если отправитель прошёл проверку 1, но чат отсутствует в заполненном реестре `groups`: `imessage: dropping group message from chat_id=<id> ...` — исправьте, добавив этот `chat_id` (или `"*"`) в `channels.imessage.groups`.

    Личные сообщения не затрагиваются — они обрабатываются другим путём кода.

    Рекомендуемая конфигурация группового потока при `groupPolicy: "allowlist"`:

    ```json5
    {
      channels: {
        imessage: {
          groupPolicy: "allowlist",
          groupAllowFrom: ["+15555550123"],
          groups: { "*": { "requireMention": true } },
        },
      },
    }
    ```

    Один `groupAllowFrom` допускает этих отправителей в любой группе; добавьте блок `groups`, чтобы ограничить разрешённые чаты и задать параметры отдельных чатов, например `requireMention`.
    </Warning>

    Проверка упоминаний в группах:

    - 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: "",
            },
          },
        },
      },
    }
    ```

    Запросы для отдельных групп применяются только к групповым сообщениям — личные сообщения не затрагиваются.

  </Tab>

  <Tab title="Сеансы и детерминированные ответы">
    - Для личных сообщений используется прямая маршрутизация, для групп — групповая.
    - При стандартном `session.dmScope=main` личные сообщения iMessage объединяются в основной сеанс агента.
    - Групповые сеансы изолированы (`agent:<agentId>:imessage:group:<chat_id>`).
    - Ответы направляются обратно в iMessage с использованием метаданных исходного канала и цели.

    Поведение веток, похожих на групповые:

    Некоторые ветки iMessage с несколькими участниками могут поступать с `is_group=false`.
    Если этот `chat_id` явно настроен в `channels.imessage.groups`, OpenClaw обрабатывает его как групповой трафик: применяет групповые проверки и изоляцию группового сеанса.

  </Tab>
</Tabs>

## Привязки бесед 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](/ru/tools/acp-agents).

## Схемы развёртывания

<AccordionGroup>
  <Accordion title="Выделенный пользователь 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) в сеансе пользователя бота.

  </Accordion>

  <Accordion title="Удалённый Mac через Tailscale (пример)">
    Типовая топология:

    - Gateway работает на Linux/виртуальной машине
    - 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 bash
    exec ssh -T bot@mac-mini.tailnet-1234.ts.net imsg "$@"
    ```

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

  </Accordion>

  <Accordion title="Схема с несколькими учётными записями">
    iMessage поддерживает настройку отдельных учётных записей в `channels.imessage.accounts`.

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

  </Accordion>

  <Accordion title="История личных сообщений">
    Задайте `channels.imessage.dmHistoryLimit`, чтобы при создании сеансов личных сообщений добавлять в них недавнюю декодированную историю `imsg` соответствующей беседы. Используйте `channels.imessage.dms["<sender>"].historyLimit` для переопределений по отправителям, включая `0`, чтобы отключить историю для определённого отправителя.

    История личных сообщений iMessage извлекается из `imsg` по запросу. Если `dmHistoryLimit` не задан, глобальное добавление истории личных сообщений отключено, однако положительное значение `channels.imessage.dms["<sender>"].historyLimit` для отдельного отправителя по-прежнему включает добавление истории для него.

  </Accordion>
</AccordionGroup>

## Медиафайлы, разбиение на части и адресаты доставки

<AccordionGroup>
  <Accordion title="Вложения и медиафайлы">
    - приём входящих вложений **по умолчанию отключён** — задайте `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)

  </Accordion>

  <Accordion title="Исходящий текст и разбиение на части">
    - ограничение размера текстовой части: `channels.imessage.textChunkLimit` (по умолчанию 4000)
    - режим разбиения на части: `channels.imessage.streaming.chunkMode`
      - `length` (по умолчанию)
      - `newline` (сначала разделение по абзацам)
    - выделение полужирным, курсивом, подчёркиванием и зачёркиванием в исходящем Markdown преобразуется во встроенное форматирование текста (получатели на macOS 15+ видят форматирование, а на более старых версиях — обычный текст без маркеров); таблицы Markdown преобразуются в соответствии с режимом таблиц Markdown канала
    - `channels.imessage.sendTransport` (по умолчанию `auto`, также `bridge`, `applescript`) определяет, как `imsg` выполняет отправку

  </Accordion>

  <Accordion title="Форматы адресации">
    Предпочтительные явные адресаты:

    - `chat_id:123` (рекомендуется для стабильной маршрутизации)
    - `chat_guid:...`
    - `chat_identifier:...`

    Также поддерживаются адресаты в виде идентификаторов:

    - `imessage:+1555...`
    - `sms:+1555...`
    - `user@example.com`

    ```bash
    imsg chats --limit 20
    ```

  </Accordion>
</AccordionGroup>

## Действия приватного 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,
      },
    },
  },
}
```

<AccordionGroup>
  <Accordion title="Доступные действия">
    - **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`.

  </Accordion>

  <Accordion title="Идентификаторы сообщений">
    Контекст входящего сообщения iMessage содержит как короткие значения `MessageSid`, так и полные GUID сообщений (`MessageSidFull`), когда они доступны. Короткие идентификаторы действуют только в пределах недавнего кэша ответов на основе SQLite и перед использованием проверяются на соответствие текущему чату. Если срок действия короткого идентификатора истёк, повторите попытку с его `MessageSidFull`, указав в качестве адресата беседу, из которой он был получен. Полные идентификаторы не обходят привязку к беседе или учётной записи, поэтому идентификатор из другого чата следует заменить идентификатором текущего адресата. Удалённо делегированные вызовы могут отклонять устаревшие полные идентификаторы, если отсутствуют подтверждающие данные о текущей беседе.

  </Accordion>

  <Accordion title="Определение возможностей">
    OpenClaw скрывает действия приватного API, только когда кэшированный результат проверки указывает, что мост недоступен. Если состояние неизвестно, действия остаются видимыми, а при их выполнении проверка запускается отложенно, поэтому первое действие может успешно выполниться после `imsg launch` без отдельного ручного обновления состояния.

  </Accordion>

  <Accordion title="Уведомления о прочтении и индикатор набора текста">
    Когда мост приватного API работает, принятые входящие чаты помечаются как прочитанные, а в личных чатах индикатор набора текста появляется сразу после принятия запроса, пока агент подготавливает контекст и генерирует ответ. Чтобы отключить отметку о прочтении, используйте:

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

    Более старые сборки `imsg`, выпущенные до появления списка возможностей по отдельным методам, без уведомления отключают набор текста и отметки о прочтении; OpenClaw регистрирует однократное предупреждение при каждом перезапуске, чтобы можно было определить причину отсутствия уведомления.

  </Accordion>

  <Accordion title="Входящие реакции">
    OpenClaw подписывается на реакции iMessage и маршрутизирует принятые реакции как системные события вместо обычного текста сообщения, поэтому реакция пользователя не запускает обычный цикл ответа.

    Режим уведомлений управляется параметром `channels.imessage.reactionNotifications`:

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

    Переопределения для отдельных учётных записей задаются через `channels.imessage.accounts.<id>.reactionNotifications`.

  </Accordion>

  <Accordion title="Реакции для подтверждения (👍 / 👎)">
    Когда `approvals.exec.enabled` или `approvals.plugin.enabled` имеет значение true и запрос направляется в iMessage, Gateway отправляет запрос на подтверждение во встроенном формате и принимает реакцию для его обработки:

    - `👍` (реакция «Нравится») → `allow-once`
    - `👎` (реакция «Не нравится») → `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.

  </Accordion>
</AccordionGroup>

## Запись конфигурации

По умолчанию iMessage разрешает запись конфигурации, инициированную каналом (для `/config set|unset`, когда `commands.config: true`).

Отключение:

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

<a id="coalescing-split-send-dms-command--url-in-one-composition"></a>

## Объединение разделённых личных сообщений (команда + URL в одном составленном сообщении)

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

1. Текстовое сообщение (`"Dump"`).
2. Пузырь предпросмотра 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>` в два хода. Групповые чаты по-прежнему обрабатывают каждое сообщение отдельно, чтобы сохранить структуру ходов нескольких пользователей.

<Tabs>
  <Tab title="Когда включать">
    Включайте, если:

    - Вы поставляете Skills, ожидающие `command + payload` в одном сообщении (дамп, вставка, сохранение, постановка в очередь и т. д.).
    - Ваши пользователи вставляют URL вместе с командами.
    - Для вас приемлема дополнительная задержка хода в личных сообщениях (см. ниже).

    Не включайте, если:

    - Вам нужна минимальная задержка выполнения команд для однословных триггеров в личных сообщениях.
    - Все ваши процессы состоят из однократных команд без последующей передачи полезной нагрузки.

  </Tab>
  <Tab title="Включение">
    ```json5
    {
      channels: {
        imessage: {
          coalesceSameSenderDms: true, // явное включение (по умолчанию: false)
        },
      },
    }
    ```

    Если флаг включён, но `messages.inbound.byChannel.imessage` или глобальный параметр `messages.inbound.debounceMs` явно не заданы, окно устранения дребезга увеличивается до **7000 мс** (устаревшее значение по умолчанию — 0 мс, то есть без устранения дребезга). Более широкое окно необходимо, поскольку интервал разделённой отправки предпросмотра URL в Apple может достигать нескольких секунд, пока Messages.app формирует строку предпросмотра.

    Чтобы настроить окно самостоятельно:

    ```json5
    {
      messages: {
        inbound: {
          byChannel: {
            // 7000 мс покрывают наблюдаемые задержки предпросмотра URL в Messages.app.
            imessage: 7000,
          },
        },
      },
    }
    ```

  </Tab>
  <Tab title="Компромиссы">
    - **Для точного объединения необходимы актуальные метаданные полезной нагрузки `imsg`.** При наличии `balloon_bundle_id` объединяется только фактическая разделённая отправка; описанное выше резервное объединение при отсутствии метаданных служит временной обратной совместимостью и будет удалено, когда `imsg` начнёт объединять разделённые отправки на своей стороне.
    - **Дополнительная задержка личных сообщений.** При включённом флаге каждое личное сообщение (включая отдельные управляющие команды и последующие одиночные текстовые сообщения) перед обработкой ожидает до истечения окна устранения дребезга на случай поступления строки предпросмотра URL. Сообщения групповых чатов обрабатываются немедленно.
    - **Размер объединённого результата ограничен.** Объединённый текст ограничен 4000 символами с явным маркером `…[truncated]`; количество вложений ограничено 20, а исходных записей — 10 (при превышении сохраняются первая и последние). GUID каждого источника отслеживается в `coalescedMessageGuids` для последующей телеметрии.
    - **Только для личных сообщений.** В групповых чатах каждое сообщение обрабатывается отдельно, чтобы бот сохранял отзывчивость, когда одновременно пишут несколько человек.
    - **Явное включение для каждого канала.** Другие каналы (Discord, Slack, Telegram, WhatsApp, …) не затрагиваются. В устаревших конфигурациях BlueBubbles, где задан `channels.bluebubbles.coalesceSameSenderDms`, это значение следует перенести в `channels.imessage.coalesceSameSenderDms`.

  </Tab>
</Tabs>

### Сценарии и данные, видимые агенту

Столбец «Флаг включён» показывает поведение сборки `imsg`, передающей `balloon_bundle_id`. В старых сборках `imsg`, которые вообще не передают метаданные пузыря, строки, помеченные ниже как «Два хода» / «N ходов», вместо этого объединяются по устаревшему механизму (один ход): OpenClaw не может структурно отличить разделённую отправку от отдельных сообщений, поэтому сохраняет объединение, применявшееся до появления метаданных. Точное разделение активируется, когда сборка начинает передавать метаданные пузыря.

| Пользователь составляет                                             | Результат `chat.db`                  | Флаг выключен (по умолчанию)             | Флаг включён + окно (imsg передаёт метаданные пузыря)                                                  |
| ------------------------------------------------------------------ | ----------------------------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `Dump https://example.com` (одна отправка)                              | 2 строки с интервалом около 1 с                   | Два хода агента: отдельно «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. Это поведение всегда включено по умолчанию и основано на устранении дубликатов входящих сообщений.

- **Устранение дубликатов при повторном воспроизведении.** Каждое обработанное входящее сообщение записывается по своему GUID Apple в постоянное состояние плагина (`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 при запуске, ограничивает диапазон повторного воспроизведения и доставляет пропущенные сообщения возрастом до пары часов. При удалённом подключении `cliPath` по SSH он не может читать базу данных, поэтому повторное воспроизведение не ограничивается, а для каждой строки применяется возрастной барьер новых сообщений — недавно пропущенные сообщения всё равно восстанавливаются, а старая очередь подавляется, но используется более узкое окно новых сообщений. Для более широкого окна восстановления запускайте Gateway на Mac, где работает Messages.

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

Подавление накопившихся сообщений регистрируется на стандартном уровне, а не выполняется без уведомления (флаг `recovery` показывает, какое окно было применено):

```text
imessage: подавлена устаревшая очередь входящих сообщений account=<id> sent=<iso> recovery=<bool> (<N> подавлено с момента запуска)
```

### Миграция

`channels.imessage.catchup.*` устарел — восстановление после простоя выполняется автоматически и не требует конфигурации для новых установок. Существующие конфигурации с `catchup.enabled: true` продолжают поддерживаться как профиль совместимости для окна повторного воспроизведения при восстановлении. Отключённые блоки наверстывания (`enabled: false` или без `enabled: true`) выведены из эксплуатации; `openclaw doctor --fix` удаляет их.

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

<AccordionGroup>
  <Accordion title="imsg не найден или RPC не поддерживается">
    Проверьте исполняемый файл и поддержку RPC:

    ```bash
    imsg rpc --help
    imsg status --json
    openclaw channels status --probe
    ```

    Если проверка сообщает, что RPC не поддерживается, обновите `imsg`. Если действия через закрытый API недоступны, запустите `imsg launch` в сеансе вошедшего в систему пользователя macOS и повторите проверку. Если Gateway работает не на macOS, вместо стандартного локального пути `imsg` используйте описанную выше конфигурацию удалённого Mac через SSH.

  </Accordion>

  <Accordion title="Сообщения отправляются, но входящие сообщения iMessage не поступают">
    Сначала убедитесь, что сообщение достигло локального Mac. Если `chat.db` не изменяется, OpenClaw не сможет получить сообщение, даже если `imsg status --json` сообщает об исправном состоянии моста.

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

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

```bash
launchctl kickstart -k system/com.apple.apsd
launchctl kickstart -k gui/$(id -u)/com.apple.CommCenter
launchctl kickstart -k gui/$(id -u)/com.apple.identityservicesd
launchctl kickstart -k gui/$(id -u)/com.apple.imagent
imsg launch
openclaw gateway restart
```

    Отправьте с телефона новое сообщение iMessage и, прежде чем отлаживать сеансы OpenClaw, убедитесь, что появилась новая строка `chat.db` или событие `imsg watch`. Не запускайте это как периодический цикл перезапуска моста: повторные `imsg launch` вместе с перезапусками Gateway во время активной работы могут прерывать доставку и оставлять выполняющиеся запуски канала в зависшем состоянии.

  </Accordion>

  <Accordion title="Gateway не запущен в macOS">
    Стандартный `cliPath: "imsg"` должен выполняться на Mac, где выполнен вход в Messages. В Linux или Windows задайте для `channels.imessage.cliPath` скрипт-обёртку, который подключается к этому Mac по SSH и запускает `imsg "$@"`.

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

    Затем выполните:

```bash
openclaw channels status --probe --channel imessage
```

  </Accordion>

  <Accordion title="Личные сообщения игнорируются">
    Проверьте:

    - `channels.imessage.dmPolicy`
    - `channels.imessage.allowFrom`
    - подтверждения сопряжения (`openclaw pairing list imessage`)

  </Accordion>

  <Accordion title="Групповые сообщения игнорируются">
    Проверьте:

    - `channels.imessage.groupPolicy`
    - `channels.imessage.groupAllowFrom`
    - `channels.imessage.groups` поведение списка разрешений
    - настройку шаблона упоминаний (`agents.list[].groupChat.mentionPatterns`)

  </Accordion>

  <Accordion title="Не удаётся получить удалённые вложения">
    Проверьте:

    - `channels.imessage.remoteHost`
    - `channels.imessage.remoteAttachmentRoots`
    - аутентификацию по ключу SSH/SCP с хоста Gateway
    - наличие ключа хоста в `~/.ssh/known_hosts` на хосте Gateway
    - доступность удалённого пути для чтения на Mac, где работает Messages

  </Accordion>

  <Accordion title="Запросы разрешений macOS были пропущены">
    Повторно выполните команды в интерактивном терминале с графическим интерфейсом в контексте того же пользователя и сеанса и подтвердите запросы:

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

    Убедитесь, что полный доступ к диску и разрешение на автоматизацию предоставлены контексту процесса, в котором работает OpenClaw/`imsg`.

  </Accordion>
</AccordionGroup>

## Ссылки на справочник по конфигурации

- [Справочник по конфигурации — iMessage](/ru/gateway/config-channels#imessage)
- [Конфигурация Gateway](/ru/gateway/configuration)
- [Сопряжение](/ru/channels/pairing)

## Связанные материалы

- [Обзор каналов](/ru/channels) — все поддерживаемые каналы
- [Удаление BlueBubbles и переход на путь iMessage через imsg](/ru/announcements/bluebubbles-imessage) — объявление и краткое описание миграции
- [Переход с BlueBubbles](/ru/channels/imessage-from-bluebubbles) — таблица преобразования конфигурации и пошаговый переход
- [Сопряжение](/ru/channels/pairing) — аутентификация в личных сообщениях и процесс сопряжения
- [Группы](/ru/channels/groups) — поведение групповых чатов и фильтрация по упоминаниям
- [Маршрутизация каналов](/ru/channels/channel-routing) — маршрутизация сеансов для сообщений
- [Безопасность](/ru/gateway/security) — модель доступа и усиление защиты
