chore(i18n): refresh uk translations

This commit is contained in:
openclaw-docs-i18n[bot] 2026-05-03 22:35:34 +00:00
parent 57a5138791
commit 1aa8923922
3 changed files with 551 additions and 554 deletions

View File

@ -1,46 +1,46 @@
---
read_when:
- Налаштування каналу BlueBubbles
- Усунення несправностей сполучення Webhook
- Усунення несправностей під час сполучення Webhook
- Налаштування iMessage на macOS
sidebarTitle: BlueBubbles
summary: iMessage через macOS-сервер BlueBubbles (надсилання/отримання через REST, набір тексту, реакції, сполучення, розширені дії).
summary: iMessage через сервер BlueBubbles для macOS (надсилання/отримання через REST, введення тексту, реакції, сполучення, розширені дії).
title: BlueBubbles
x-i18n:
generated_at: "2026-05-01T05:05:03Z"
generated_at: "2026-05-03T22:33:25Z"
model: gpt-5.5
provider: openai
source_hash: 499cc2a46db6e0eddfb897e96ec4b3e4a39ba9f2f6da8e7485c1c46562de4145
source_hash: 78a054da0c7c32b161997acd05914896259dd1a050e736a4c9e438a452ab6a51
source_path: channels/bluebubbles.md
workflow: 16
---
Статус: bundled plugin, який взаємодіє з macOS-сервером BlueBubbles через HTTP. **Рекомендовано для інтеграції з iMessage** завдяки багатшому API та простішому налаштуванню порівняно із застарілим каналом imsg.
Status: bundled plugin, який взаємодіє із сервером BlueBubbles macOS через HTTP. **Рекомендовано для інтеграції з iMessage** завдяки багатшому API та простішому налаштуванню порівняно із застарілим каналом imsg.
<Note>
Поточні випуски OpenClaw постачають BlueBubbles у комплекті, тому звичайні пакетовані збірки не потребують окремого кроку `openclaw plugins install`.
Поточні випуски OpenClaw постачають BlueBubbles у складі пакета, тому звичайні пакетовані збірки не потребують окремого кроку `openclaw plugins install`.
</Note>
## Огляд
- Працює на macOS через допоміжний застосунок BlueBubbles ([bluebubbles.app](https://bluebubbles.app)).
- Рекомендовано/перевірено: macOS Sequoia (15). macOS Tahoe (26) працює; редагування наразі зламане на Tahoe, а оновлення іконок груп можуть повідомляти про успіх, але не синхронізуватися.
- OpenClaw взаємодіє з ним через REST API (`GET /api/v1/ping`, `POST /message/text`, `POST /chat/:id/*`).
- Вхідні повідомлення надходять через webhooks; вихідні відповіді, індикатори набору, сповіщення про прочитання та tapbacks виконуються REST-викликами.
- Вкладення та стікери приймаються як вхідні медіа (і, коли можливо, передаються agent).
- Автоматичні TTS-відповіді, що синтезують MP3 або CAF-аудіо, доставляються як бульбашки голосових нотаток iMessage замість звичайних файлових вкладень.
- Сполучення/allowlist працює так само, як і в інших каналах (`/channels/pairing` тощо), з `channels.bluebubbles.allowFrom` + кодами сполучення.
- Реакції передаються як системні події, так само як у Slack/Telegram, щоб agents могли "згадати" їх перед відповіддю.
- Розширені можливості: редагування, скасування надсилання, гілки відповідей, ефекти повідомлень, керування групами.
- Рекомендовано/протестовано: macOS Sequoia (15). macOS Tahoe (26) працює; редагування наразі зламане на Tahoe, а оновлення значків груп можуть повідомляти про успіх, але не синхронізуватися.
- OpenClaw взаємодіє з ним через його REST API (`GET /api/v1/ping`, `POST /message/text`, `POST /chat/:id/*`).
- Вхідні повідомлення надходять через webhooks; вихідні відповіді, індикатори набору, сповіщення про прочитання та tapbacks виконуються як REST-виклики.
- Вкладення та стікери приймаються як вхідні медіа (і за можливості передаються агенту).
- Автоматичні TTS-відповіді, що синтезують MP3 або CAF-аудіо, доставляються як голосові нотатки iMessage, а не як звичайні файлові вкладення.
- Звʼязування/allowlist працює так само, як і для інших каналів (`/channels/pairing` тощо), з `channels.bluebubbles.allowFrom` + кодами звʼязування.
- Реакції подаються як системні події так само, як у Slack/Telegram, щоб агенти могли "згадувати" їх перед відповіддю.
- Розширені функції: редагування, скасування надсилання, гілки відповідей, ефекти повідомлень, керування групами.
## Швидкий старт
<Steps>
<Step title="Install BlueBubbles">
Установіть сервер BlueBubbles на ваш Mac (дотримуйтесь інструкцій на [bluebubbles.app/install](https://bluebubbles.app/install)).
Установіть сервер BlueBubbles на ваш Mac (дотримуйтеся інструкцій на [bluebubbles.app/install](https://bluebubbles.app/install)).
</Step>
<Step title="Enable the web API">
У конфігурації BlueBubbles увімкніть web API та встановіть пароль.
У конфігурації BlueBubbles увімкніть web API і встановіть пароль.
</Step>
<Step title="Configure OpenClaw">
Запустіть `openclaw onboard` і виберіть BlueBubbles або налаштуйте вручну:
@ -63,7 +63,7 @@ x-i18n:
Спрямуйте webhooks BlueBubbles на ваш gateway (приклад: `https://your-gateway-host:3000/bluebubbles-webhook?password=<password>`).
</Step>
<Step title="Start the gateway">
Запустіть gateway; він зареєструє обробник webhook і почне сполучення.
Запустіть gateway; він зареєструє обробник webhook і почне звʼязування.
</Step>
</Steps>
@ -71,14 +71,14 @@ x-i18n:
**Безпека**
- Завжди встановлюйте пароль webhook.
- Автентифікація webhook завжди обовязкова. OpenClaw відхиляє webhook-запити BlueBubbles, якщо вони не містять пароль/guid, що відповідає `channels.bluebubbles.password` (наприклад, `?password=<password>` або `x-password`), незалежно від топології loopback/proxy.
- Автентифікація паролем перевіряється перед читанням/розбором повних тіл webhook.
- Автентифікація webhook завжди обовʼязкова. OpenClaw відхиляє webhook-запити BlueBubbles, якщо вони не містять password/guid, що збігається з `channels.bluebubbles.password` (наприклад, `?password=<password>` або `x-password`), незалежно від топології loopback/proxy.
- Автентифікація паролем перевіряється до читання/розбору повних тіл webhook.
</Warning>
## Підтримання Messages.app активним (VM / headless-налаштування)
У деяких VM macOS / постійно ввімкнених налаштуваннях Messages.app може переходити в стан "idle" (вхідні події зупиняються, доки застосунок не відкриють або не виведуть на передній план). Простий обхідний шлях — **підштовхувати Messages кожні 5 хвилин** за допомогою AppleScript + LaunchAgent.
Деякі macOS VM / постійно ввімкнені налаштування можуть призводити до того, що Messages.app переходить у стан "idle" (вхідні події зупиняються, доки застосунок не буде відкрито/виведено на передній план). Простий обхідний шлях — **торкатися Messages кожні 5 хвилин** за допомогою AppleScript + LaunchAgent.
<Steps>
<Step title="Save the AppleScript">
@ -132,7 +132,7 @@ x-i18n:
</plist>
```
Це запускається **кожні 300 секунд** і **під час входу в систему**. Перший запуск може спричинити запити macOS **Automation** (`osascript` → Messages). Схваліть їх у тому самому сеансі користувача, у якому працює LaunchAgent.
Це запускається **кожні 300 секунд** і **під час входу в систему**. Перший запуск може спричинити запити macOS **Automation** (`osascript` → Messages). Підтвердьте їх у тій самій користувацькій сесії, у якій працює LaunchAgent.
</Step>
<Step title="Load it">
@ -143,9 +143,9 @@ x-i18n:
</Step>
</Steps>
## Онбординг
## Onboarding
BlueBubbles доступний в інтерактивному онбордингу:
BlueBubbles доступний в інтерактивному onboarding:
```
openclaw onboard
@ -157,16 +157,16 @@ openclaw onboard
Адреса сервера BlueBubbles (наприклад, `http://192.168.1.100:1234`).
</ParamField>
<ParamField path="Password" type="string" required>
Пароль API з налаштувань BlueBubbles Server.
API-пароль із налаштувань BlueBubbles Server.
</ParamField>
<ParamField path="Webhook path" type="string" default="/bluebubbles-webhook">
Шлях кінцевої точки webhook.
Шлях endpoint webhook.
</ParamField>
<ParamField path="DM policy" type="string">
`pairing`, `allowlist`, `open` або `disabled`.
</ParamField>
<ParamField path="Allow list" type="string[]">
Номери телефонів, електронні адреси або цілі чату.
Телефонні номери, електронні адреси або цілі чатів.
</ParamField>
Ви також можете додати BlueBubbles через CLI:
@ -175,33 +175,33 @@ openclaw onboard
openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --password <password>
```
## Контроль доступу (DM + групи)
## Контроль доступу (DMs + групи)
<Tabs>
<Tab title="DMs">
- За замовчуванням: `channels.bluebubbles.dmPolicy = "pairing"`.
- Невідомі відправники отримують код сполучення; повідомлення ігноруються, доки їх не буде схвалено (коди спливають через 1 годину).
- Невідомі відправники отримують код звʼязування; повідомлення ігноруються, доки їх не схвалять (коди спливають через 1 годину).
- Схвалити через:
- `openclaw pairing list bluebubbles`
- `openclaw pairing approve bluebubbles <CODE>`
- Сполучення є типовим обміном токенами. Докладніше: [Сполучення](/uk/channels/pairing)
- Звʼязування є типовим обміном токенами. Докладніше: [Звʼязування](/uk/channels/pairing)
</Tab>
<Tab title="Groups">
- `channels.bluebubbles.groupPolicy = open | allowlist | disabled` (за замовчуванням: `allowlist`).
- `channels.bluebubbles.groupAllowFrom` контролює, хто може запускати agent у групах, коли встановлено `allowlist`.
- `channels.bluebubbles.groupAllowFrom` керує тим, хто може запускати дії в групах, коли встановлено `allowlist`.
</Tab>
</Tabs>
### Збагачення імен контактів (macOS, необовязково)
### Збагачення імен контактів (macOS, необовʼязково)
Групові webhooks BlueBubbles часто містять лише сирі адреси учасників. Якщо ви хочете, щоб контекст `GroupMembers` натомість показував локальні імена контактів, ви можете ввімкнути збагачення локальними Contacts на macOS:
Групові webhooks BlueBubbles часто містять лише сирі адреси учасників. Якщо ви хочете, щоб контекст `GroupMembers` натомість показував локальні імена контактів, ви можете ввімкнути локальне збагачення Contacts на macOS:
- `channels.bluebubbles.enrichGroupParticipantsFromContacts = true` вмикає пошук. За замовчуванням: `false`.
- Пошуки запускаються лише після того, як доступ до групи, авторизація команди та mention gating пропустили повідомлення.
- Пошуки виконуються лише після того, як доступ до групи, авторизація команд і фільтрація згадок пропустили повідомлення.
- Збагачуються лише учасники з телефонними номерами без імен.
- Сирі номери телефонів залишаються fallback-значенням, коли локальний збіг не знайдено.
- Сирі телефонні номери залишаються fallback, коли локальний збіг не знайдено.
```json5
{
@ -213,13 +213,13 @@ openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --passwor
}
```
### Mention gating (групи)
### Фільтрація згадок (групи)
BlueBubbles підтримує mention gating для групових чатів, що відповідає поведінці iMessage/WhatsApp:
BlueBubbles підтримує фільтрацію згадок для групових чатів, відповідно до поведінки iMessage/WhatsApp:
- Використовує `agents.list[].groupChat.mentionPatterns` (або `messages.groupChat.mentionPatterns`) для виявлення згадок.
- Коли `requireMention` увімкнено для групи, agent відповідає лише тоді, коли його згадали.
- Команди керування від авторизованих відправників обходять mention gating.
- Коли для групи ввімкнено `requireMention`, агент відповідає лише тоді, коли його згадали.
- Контрольні команди від авторизованих відправників обходять фільтрацію згадок.
Конфігурація для окремої групи:
@ -238,15 +238,15 @@ BlueBubbles підтримує mention gating для групових чатів
}
```
### Command gating
### Фільтрація команд
- Команди керування (наприклад, `/config`, `/model`) потребують авторизації.
- Використовує `allowFrom` і `groupAllowFrom` для визначення авторизації команд.
- Авторизовані відправники можуть запускати команди керування навіть без згадування в групах.
- Контрольні команди (наприклад, `/config`, `/model`) потребують авторизації.
- Використовує `allowFrom` і `groupAllowFrom`, щоб визначити авторизацію команд.
- Авторизовані відправники можуть запускати контрольні команди навіть без згадки в групах.
### Системний prompt для окремої групи
Кожен запис у `channels.bluebubbles.groups.*` приймає необов’язковий рядок `systemPrompt`. Значення додається до системного prompt agent на кожному ході, який обробляє повідомлення в цій групі, тож ви можете задати persona або поведінкові правила для окремої групи без редагування prompt agent:
Кожен запис у `channels.bluebubbles.groups.*` приймає необовʼязковий рядок `systemPrompt`. Значення вставляється в системний prompt агента на кожному ході, який обробляє повідомлення в цій групі, щоб ви могли встановлювати persona або правила поведінки для окремої групи без редагування prompt агента:
```json5
{
@ -262,11 +262,11 @@ BlueBubbles підтримує mention gating для групових чатів
}
```
Ключ відповідає тому, що BlueBubbles повідомляє як `chatGuid` / `chatIdentifier` / числовий `chatId` для групи, а wildcard-запис `"*"` задає значення за замовчуванням для кожної групи без точного збігу (той самий шаблон, що використовується `requireMention` і політиками інструментів для окремих груп). Точні збіги завжди мають пріоритет над wildcard. DM ігнорують це поле; натомість використовуйте налаштування prompt на рівні agent або облікового запису.
Ключ відповідає тому, що BlueBubbles повідомляє як `chatGuid` / `chatIdentifier` / числовий `chatId` для групи, а wildcard-запис `"*"` задає стандартне значення для кожної групи без точного збігу (той самий патерн, що використовується `requireMention` і політиками інструментів для окремих груп). Точні збіги завжди мають перевагу над wildcard. DMs ігнорують це поле; натомість використовуйте налаштування prompt на рівні агента або облікового запису.
#### Робочий приклад: гілковані відповіді та tapback-реакції (Private API)
Коли увімкнено BlueBubbles Private API, вхідні повідомлення надходять із короткими ідентифікаторами повідомлень (наприклад, `[[reply_to:5]]`), а agent може викликати `action=reply`, щоб відповісти в гілці конкретного повідомлення, або `action=react`, щоб залишити tapback. `systemPrompt` для окремої групи — надійний спосіб змусити agent вибирати правильний інструмент:
Коли BlueBubbles Private API увімкнено, вхідні повідомлення надходять із короткими ідентифікаторами повідомлень (наприклад, `[[reply_to:5]]`), а агент може викликати `action=reply`, щоб відповісти в гілці конкретного повідомлення, або `action=react`, щоб додати tapback. `systemPrompt` для окремої групи — надійний спосіб змусити агента вибирати правильний інструмент:
```json5
{
@ -274,15 +274,7 @@ BlueBubbles підтримує mention gating для групових чатів
bluebubbles: {
groups: {
"iMessage;+;chat-family": {
systemPrompt: [
"When replying in this group, always call action=reply with the",
"[[reply_to:N]] messageId from context so your response threads",
"under the triggering message. Never send a new unlinked message.",
"",
"For short acknowledgements ('ok', 'got it', 'on it'), use",
"action=react with an appropriate tapback emoji (❤️, 👍, 😂, ‼️, ❓)",
"instead of sending a text reply.",
].join(" "),
systemPrompt: "When replying in this group, always call action=reply with the [[reply_to:N]] messageId from context so your response threads under the triggering message. Never send a new unlinked message. For short acknowledgements ('ok', 'got it', 'on it'), use action=react with an appropriate tapback emoji (❤️, 👍, 😂, ‼️, ❓) instead of sending a text reply.",
},
},
},
@ -290,20 +282,20 @@ BlueBubbles підтримує mention gating для групових чатів
}
```
Tapback-реакції та гілковані відповіді обидві потребують BlueBubbles Private API; див. [Розширені дії](#advanced-actions) і [Ідентифікатори повідомлень](#message-ids-short-vs-full), щоб дізнатися про базову механіку.
Tapback-реакції та гілковані відповіді обидві потребують BlueBubbles Private API; див. [Розширені дії](#advanced-actions) і [Ідентифікатори повідомлень](#message-ids-short-vs-full) щодо базових механік.
## Привязки розмов ACP
## Привʼязки розмов ACP
Чати BlueBubbles можна перетворити на довговічні робочі простори ACP без зміни транспортного шару.
Чати BlueBubbles можна перетворити на сталі робочі простори ACP без зміни транспортного шару.
Швидкий потік оператора:
- Запустіть `/acp spawn codex --bind here` усередині DM або дозволеного групового чату.
- Майбутні повідомлення в тій самій розмові BlueBubbles маршрутизуються до створеного сеансу ACP.
- `/new` і `/reset` скидають той самий прив’язаний сеанс ACP на місці.
- `/acp close` закриває сеанс ACP і видаляє прив’язку.
- Майбутні повідомлення в тій самій розмові BlueBubbles спрямовуються до створеної сесії ACP.
- `/new` і `/reset` скидають ту саму привʼязану сесію ACP на місці.
- `/acp close` закриває сесію ACP і видаляє привʼязку.
Налаштовані постійні прив’язки також підтримуються через записи верхнього рівня `bindings[]` з `type: "acp"` і `match.channel: "bluebubbles"`.
Налаштовані сталі привʼязки також підтримуються через записи верхнього рівня `bindings[]` з `type: "acp"` і `match.channel: "bluebubbles"`.
`match.peer.id` може використовувати будь-яку підтримувану форму цілі BlueBubbles:
@ -312,7 +304,7 @@ Tapback-реакції та гілковані відповіді обидві
- `chat_guid:<guid>`
- `chat_identifier:<identifier>`
Для стабільних групових привязок віддавайте перевагу `chat_id:*` або `chat_identifier:*`.
Для стабільних групових привʼязок віддавайте перевагу `chat_id:*` або `chat_identifier:*`.
Приклад:
@ -344,13 +336,13 @@ Tapback-реакції та гілковані відповіді обидві
}
```
Див. [ACP Agents](/uk/tools/acp-agents) щодо спільної поведінки привязок ACP.
Див. [Агенти ACP](/uk/tools/acp-agents) щодо спільної поведінки привʼязок ACP.
## Набір тексту + сповіщення про прочитання
- **Індикатори набору**: надсилаються автоматично перед і під час генерації відповіді.
- **Підтвердження прочитання**: керуються `channels.bluebubbles.sendReadReceipts` (типово: `true`).
- **Індикатори набору**: OpenClaw надсилає події початку набору; BlueBubbles автоматично очищає стан набору під час надсилання або після тайм-ауту (ручна зупинка через DELETE ненадійна).
- **Сповіщення про прочитання**: керуються `channels.bluebubbles.sendReadReceipts` (за замовчуванням: `true`).
- **Індикатори набору**: OpenClaw надсилає події початку набору; BlueBubbles автоматично очищає набір під час надсилання або після тайм-ауту (ручна зупинка через DELETE ненадійна).
```json5
{
@ -390,7 +382,7 @@ BlueBubbles підтримує розширені дії з повідомлен
<AccordionGroup>
<Accordion title="Доступні дії">
- **react**: додати/видалити tapback-реакції (`messageId`, `emoji`, `remove`). Нативний набір tapback в iMessage: `love`, `like`, `dislike`, `laugh`, `emphasize` і `question`. Коли агент вибирає emoji поза цим набором (наприклад `👀`), інструмент реакцій повертається до `love`, щоб tapback усе одно відобразився, а не зірвав увесь запит. Налаштовані ack-реакції й далі проходять сувору валідацію та дають помилку для невідомих значень.
- **react**: додати або прибрати реакції tapback (`messageId`, `emoji`, `remove`). Власний набір tapback в iMessage: `love`, `like`, `dislike`, `laugh`, `emphasize` і `question`. Коли агент вибирає емодзі поза цим набором (наприклад, `👀`), інструмент реакцій повертається до `love`, щоб tapback усе одно відобразився, а не зірвав увесь запит. Налаштовані ack-реакції й надалі перевіряються суворо та дають помилку для невідомих значень.
- **edit**: редагувати надіслане повідомлення (`messageId`, `text`).
- **unsend**: скасувати надсилання повідомлення (`messageId`).
- **reply**: відповісти на конкретне повідомлення (`messageId`, `text`, `to`).
@ -401,53 +393,53 @@ BlueBubbles підтримує розширені дії з повідомлен
- **removeParticipant**: видалити когось із групи (`chatGuid`, `address`).
- **leaveGroup**: вийти з групового чату (`chatGuid`).
- **upload-file**: надіслати медіа/файли (`to`, `buffer`, `filename`, `asVoice`).
- Голосові нотатки: установіть `asVoice: true` з аудіо **MP3** або **CAF**, щоб надіслати як голосове повідомлення iMessage. BlueBubbles перетворює MP3 → CAF під час надсилання голосових нотаток.
- Застарілий псевдонім: `sendAttachment` і далі працює, але `upload-file` є канонічною назвою дії.
- Голосові нотатки: установіть `asVoice: true` з аудіо **MP3** або **CAF**, щоб надіслати голосове повідомлення iMessage. BlueBubbles перетворює MP3 → CAF під час надсилання голосових нотаток.
- Застарілий псевдонім: `sendAttachment` досі працює, але `upload-file` є канонічною назвою дії.
</Accordion>
</AccordionGroup>
### ID повідомлень (короткі й повні)
### ID повідомлень (короткі та повні)
OpenClaw може показувати ороткі_ ID повідомлень (наприклад, `1`, `2`), щоб заощаджувати токени.
- `MessageSid` / `ReplyToId` можуть бути короткими ID.
- `MessageSidFull` / `ReplyToIdFull` містять повні ID провайдера.
- Короткі ID зберігаються в пам’яті; вони можуть застаріти після перезапуску або витіснення з кешу.
- Дії приймають короткий або повний `messageId`, але короткі ID спричинять помилку, якщо вони більше недоступні.
- Короткі ID зберігаються в пам’яті; вони можуть ставати недійсними після перезапуску або витіснення з кешу.
- Дії приймають короткий або повний `messageId`, але короткі ID дадуть помилку, якщо більше недоступні.
Використовуйте повні ID для довготривалих автоматизацій і зберігання:
- Шаблони: `{{MessageSidFull}}`, `{{ReplyToIdFull}}`
- Контекст: `MessageSidFull` / `ReplyToIdFull` у вхідних payload
Див. [Конфігурація](/uk/gateway/configuration) щодо змінних шаблонів.
Див. [Конфігурацію](/uk/gateway/configuration) для змінних шаблонів.
<a id="coalescing-split-send-dms-command--url-in-one-composition"></a>
## Об’єднання split-send DM (команда + URL в одному складанні)
## Об’єднання розділених DM-надсилань (команда + URL в одному повідомленні)
Коли користувач вводить команду й URL разом в iMessage — наприклад `Dump https://example.com/article` — Apple розділяє надсилання на **дві окремі доставки Webhook**:
Коли користувач вводить команду й URL разом в iMessage — наприклад, `Dump https://example.com/article` — Apple розділяє надсилання на **дві окремі доставки webhook**:
1. Текстове повідомлення (`"Dump"`).
2. Бульбашка URL-прев’ю (`"https://..."`) із зображеннями OG-прев’ю як вкладеннями.
2. Бульбашка попереднього перегляду URL (`"https://..."`) з OG-preview зображеннями як вкладеннями.
У більшості налаштувань два Webhook надходять в OpenClaw з інтервалом приблизно 0,8-2,0 с. Без об’єднання агент отримує лише команду на ході 1, відповідає (часто «надішліть мені URL») і бачить URL лише на ході 2 — коли контекст команди вже втрачено.
Два webhook надходять до OpenClaw з інтервалом приблизно 0.8-2.0 с у більшості конфігурацій. Без об’єднання агент отримує лише команду на кроці 1, відповідає (часто "надішліть мені URL") і бачить URL лише на кроці 2 — коли контекст команди вже втрачено.
`channels.bluebubbles.coalesceSameSenderDms` вмикає для DM об’єднання послідовних Webhook від того самого відправника в один хід агента. Групові чати й далі прив’язуються до окремих повідомлень, щоб зберегти структуру ходів кількох користувачів.
`channels.bluebubbles.coalesceSameSenderDms` вмикає для DM об’єднання послідовних webhook від того самого відправника в один крок агента. Групові чати й надалі прив’язуються до окремих повідомлень, щоб зберегти структуру кроків для кількох користувачів.
<Tabs>
<Tab title="Коли вмикати">
Увімкніть, коли:
- Ви постачаєте Skills, які очікують `command + payload` в одному повідомленні (dump, paste, save, queue тощо).
- Ваші користувачі вставляють URL, зображення або довгий вміст разом із командами.
- Ви можете прийняти додаткову затримку ходу DM (див. нижче).
- Ваші користувачі вставляють URL, зображення або довгий вміст поруч із командами.
- Ви можете прийняти додаткову затримку кроку DM (див. нижче).
Залиште вимкненим, коли:
- Вам потрібна мінімальна затримка команд для однословних тригерів DM.
- Усі ваші потоки є одноразовими командами без наступних payload.
- Вам потрібна мінімальна затримка команд для однословних DM-тригерів.
- Усі ваші потоки — це одноразові команди без подальших payload.
</Tab>
<Tab title="Увімкнення">
@ -461,7 +453,7 @@ OpenClaw може показувати _короткі_ ID повідомлен
}
```
Коли прапорець увімкнено й немає явного `messages.inbound.byChannel.bluebubbles`, debounce-вікно розширюється до **2500 мс** (типово для режиму без об’єднання — 500 мс). Ширше вікно потрібне, бо cadence split-send від Apple у 0,8-2,0 с не вкладається в тісніше типове значення.
Коли прапорець увімкнено і немає явного `messages.inbound.byChannel.bluebubbles`, вікно debounce розширюється до **2500 мс** (за замовчуванням для режиму без об’єднання — 500 мс). Ширше вікно потрібне — каденція розділеного надсилання Apple у 0.8-2.0 с не вкладається у вужче значення за замовчуванням.
Щоб налаштувати вікно самостійно:
@ -481,39 +473,39 @@ OpenClaw може показувати _короткі_ ID повідомлен
</Tab>
<Tab title="Компроміси">
- **Додана затримка для керівних команд DM.** Коли прапорець увімкнено, повідомлення керівних команд DM (наприклад `Dump`, `Save` тощо) тепер чекають до завершення debounce-вікна перед dispatch, на випадок якщо надходить Webhook із payload. Команди групового чату зберігають миттєвий dispatch.
- **Об’єднаний вивід обмежений** — об’єднаний текст обмежується 4000 символами з явним маркером `…[truncated]`; вкладення обмежуються 20; записи джерел обмежуються 10 (понад це зберігаються перший і найновіший). Кожен вихідний `messageId` усе одно доходить до inbound-dedupe, тож пізніший replay MessagePoller будь-якої окремої події розпізнається як дублікат.
- **Opt-in, для окремого каналу.** Інші канали (Telegram, WhatsApp, Slack, …) не зачіпаються.
- **Додаткова затримка для керівних команд DM.** Коли прапорець увімкнено, повідомлення з керівними командами DM (наприклад, `Dump`, `Save` тощо) тепер чекають до завершення вікна debounce перед dispatch, на випадок якщо надходить webhook з payload. Команди в групових чатах зберігають миттєвий dispatch.
- **Об’єднаний вивід обмежений** — об’єднаний текст обмежено 4000 символами з явним маркером `…[truncated]`; вкладення обмежено 20; записи джерел обмежено 10 (понад це зберігаються перший і найновіший). Кожен вихідний `messageId` усе одно потрапляє до inbound-dedupe, тож пізніше повторне відтворення будь-якої окремої події MessagePoller розпізнається як дублікат.
- **Опційно, для окремого каналу.** Інші канали (Telegram, WhatsApp, Slack, …) не зачіпаються.
</Tab>
</Tabs>
### Сценарії й те, що бачить агент
### Сценарії та що бачить агент
| Користувач складає | Apple доставляє | Прапорець вимкнено (типово) | Прапорець увімкнено + вікно 2500 мс |
| ------------------------------------------------------------------ | ------------------------------ | --------------------------------------- | ----------------------------------------------------------------------- |
| `Dump https://example.com` (одне надсилання) | 2 Webhook з інтервалом ~1 с | Два ходи агента: лише "Dump", потім URL | Один хід: об’єднаний текст `Dump https://example.com` |
| `Save this 📎image.jpg caption` (вкладення + текст) | 2 Webhook | Два ходи | Один хід: текст + зображення |
| `/status` (окрема команда) | 1 Webhook | Миттєвий dispatch | **Чекати до вікна, потім dispatch** |
| URL, вставлений окремо | 1 Webhook | Миттєвий dispatch | Миттєвий dispatch (лише один запис у bucket) |
| Текст + URL, надіслані як два навмисно окремі повідомлення, з різницею в хвилини | 2 Webhook поза вікном | Два ходи | Два ходи (вікно завершується між ними) |
| Швидкий потік (>10 малих DM у межах вікна) | N Webhook | N ходів | Один хід, обмежений вивід (перший + найновіший, застосовані обмеження тексту/вкладень) |
| Користувач складає повідомлення | Apple доставляє | Прапорець вимкнено (за замовчуванням) | Прапорець увімкнено + вікно 2500 мс |
| ------------------------------------------------------------------ | ------------------------- | ------------------------------------------ | ----------------------------------------------------------------------- |
| `Dump https://example.com` (одне надсилання) | 2 webhook з інтервалом ~1 с | Два кроки агента: лише "Dump", потім URL | Один крок: об’єднаний текст `Dump https://example.com` |
| `Save this 📎image.jpg caption` (вкладення + текст) | 2 webhook | Два кроки | Один крок: текст + зображення |
| `/status` (самостійна команда) | 1 webhook | Миттєвий dispatch | **Очікування до завершення вікна, потім dispatch** |
| URL вставлено окремо | 1 webhook | Миттєвий dispatch | Миттєвий dispatch (лише один запис у bucket) |
| Текст + URL надіслано як два навмисно окремі повідомлення з інтервалом у хвилини | 2 webhook поза вікном | Два кроки | Два кроки (вікно спливає між ними) |
| Швидкий потік (>10 малих DM у межах вікна) | N webhook | N кроків | Один крок, обмежений вивід (перший + найновіший, застосовано обмеження тексту/вкладень) |
### Усунення несправностей об’єднання split-send
### Усунення несправностей об’єднання розділених надсилань
Якщо прапорець увімкнено, але split-send і далі надходять як два ходи, перевірте кожен рівень:
Якщо прапорець увімкнено, але розділені надсилання все одно надходять як два кроки, перевірте кожен рівень:
<AccordionGroup>
<Accordion title="Конфігурацію справді завантажено">
<Accordion title="Конфігурацію фактично завантажено">
```
grep coalesceSameSenderDms ~/.openclaw/openclaw.json
```
Потім `openclaw gateway restart` — прапорець зчитується під час створення debouncer-registry.
Потім `openclaw gateway restart` — прапорець читається під час створення debouncer-registry.
</Accordion>
<Accordion title="Debounce-вікно достатньо широке для вашого налаштування">
Перегляньте журнал сервера BlueBubbles у `~/Library/Logs/bluebubbles-server/main.log`:
<Accordion title="Вікно debounce достатньо широке для вашої конфігурації">
Подивіться журнал сервера BlueBubbles у `~/Library/Logs/bluebubbles-server/main.log`:
```
grep -E "Dispatching event to webhook" main.log | tail -20
@ -522,20 +514,20 @@ OpenClaw може показувати _короткі_ ID повідомлен
Виміряйте проміжок між dispatch тексту в стилі `"Dump"` і наступним dispatch `"https://..."; Attachments:`. Збільште `messages.inbound.byChannel.bluebubbles`, щоб із запасом покрити цей проміжок.
</Accordion>
<Accordion title="Позначки часу Session JSONL ≠ надходження Webhook">
Позначки часу подій сеансу (`~/.openclaw/agents/<id>/sessions/*.jsonl`) відображають момент, коли Gateway передає повідомлення агенту, **а не** момент надходження Webhook. Друге повідомлення в черзі, позначене `[Queued messages while agent was busy]`, означає, що перший хід усе ще виконувався, коли надійшов другий Webhook — bucket об’єднання вже було скинуто. Налаштовуйте вікно за журналом сервера BB, а не за журналом сеансу.
<Accordion title="Мітки часу JSONL сесії ≠ надходження webhook">
Мітки часу подій сесії (`~/.openclaw/agents/<id>/sessions/*.jsonl`) відображають, коли Gateway передає повідомлення агенту, **а не** коли надійшов webhook. Друге повідомлення в черзі з позначкою `[Queued messages while agent was busy]` означає, що перший крок ще виконувався, коли надійшов другий webhook — bucket об’єднання вже було скинуто. Налаштовуйте вікно за журналом сервера BB, а не за журналом сесії.
</Accordion>
<Accordion title="Тиск пам’яті сповільнює dispatch відповіді">
На менших машинах (8 ГБ) ходи агента можуть тривати достатньо довго, щоб bucket об’єднання скинувся до завершення відповіді, і URL потрапив як другий хід у черзі. Перевірте `memory_pressure` і `ps -o rss -p $(pgrep openclaw-gateway)`; якщо Gateway використовує понад ~500 МБ RSS і compressor активний, закрийте інші важкі процеси або перейдіть на більший хост.
<Accordion title="Тиск на пам’ять сповільнює dispatch відповіді">
На менших машинах (8 ГБ) кроки агента можуть тривати достатньо довго, щоб bucket об’єднання скинувся до завершення відповіді, і URL потрапив як другий крок у черзі. Перевірте `memory_pressure` і `ps -o rss -p $(pgrep openclaw-gateway)`; якщо Gateway перевищує ~500 МБ RSS і compressor активний, закрийте інші важкі процеси або перейдіть на більший хост.
</Accordion>
<Accordion title="Надсилання reply-quote йдуть іншим шляхом">
Якщо користувач натиснув `Dump` як **відповідь** на наявну URL-бульбашку (iMessage показує бейдж "1 Reply" на бульбашці Dump), URL міститься в `replyToBody`, а не в другому Webhook. Об’єднання не застосовується — це питання skill/prompt, а не debouncer.
<Accordion title="Надсилання з цитуванням відповіді йдуть іншим шляхом">
Якщо користувач натиснув `Dump` як **відповідь** на наявну URL-бульбашку (iMessage показує бейдж "1 Reply" на бульбашці Dump), URL міститься в `replyToBody`, а не в другому webhook. Об’єднання не застосовується — це питання skill/prompt, а не debouncer.
</Accordion>
</AccordionGroup>
## Блокове потокове передавання
## Потокове надсилання блоками
Керує тим, чи відповіді надсилаються як одне повідомлення, чи потоково блоками:
Керуйте тим, чи відповіді надсилаються одним повідомленням, чи потоком блоків:
```json5
{
@ -549,46 +541,46 @@ OpenClaw може показувати _короткі_ ID повідомлен
## Медіа + обмеження
- Вхідні вкладення завантажуються та зберігаються в кеші медіа.
- Обмеження медіа через `channels.bluebubbles.mediaMaxMb` для вхідних і вихідних медіа (типово: 8 МБ).
- Вихідний текст розбивається на частини за `channels.bluebubbles.textChunkLimit` (типово: 4000 символів).
- Вхідні вкладення завантажуються й зберігаються в кеші медіа.
- Обмеження медіа через `channels.bluebubbles.mediaMaxMb` для вхідних і вихідних медіа (за замовчуванням: 8 МБ).
- Вихідний текст розбивається на фрагменти відповідно до `channels.bluebubbles.textChunkLimit` (за замовчуванням: 4000 символів).
## Довідник конфігурації
Повна конфігурація: [Конфігурація](/uk/gateway/configuration)
<AccordionGroup>
<Accordion title="Підключення та Webhook">
<Accordion title="Підключення та webhook">
- `channels.bluebubbles.enabled`: увімкнути/вимкнути канал.
- `channels.bluebubbles.serverUrl`: базовий URL REST API BlueBubbles.
- `channels.bluebubbles.password`: пароль API.
- `channels.bluebubbles.webhookPath`: шлях endpoint Webhook (типово: `/bluebubbles-webhook`).
- `channels.bluebubbles.webhookPath`: шлях endpoint webhook (за замовчуванням: `/bluebubbles-webhook`).
</Accordion>
<Accordion title="Політика доступу">
- `channels.bluebubbles.dmPolicy`: `pairing | allowlist | open | disabled` (типово: `pairing`).
- `channels.bluebubbles.allowFrom`: allowlist DM (handles, email, номери E.164, `chat_id:*`, `chat_guid:*`).
- `channels.bluebubbles.groupPolicy`: `open | allowlist | disabled` (типово: `allowlist`).
- `channels.bluebubbles.groupAllowFrom`: allowlist відправників групи.
- `channels.bluebubbles.enrichGroupParticipantsFromContacts`: на macOS, за бажанням доповнювати безіменних учасників групи з локальних Contacts після проходження gating. Типово: `false`.
- `channels.bluebubbles.dmPolicy`: `pairing | allowlist | open | disabled` (за замовчуванням: `pairing`).
- `channels.bluebubbles.allowFrom`: allowlist для DM (handles, emails, E.164 numbers, `chat_id:*`, `chat_guid:*`).
- `channels.bluebubbles.groupPolicy`: `open | allowlist | disabled` (за замовчуванням: `allowlist`).
- `channels.bluebubbles.groupAllowFrom`: allowlist відправників груп.
- `channels.bluebubbles.enrichGroupParticipantsFromContacts`: на macOS, за бажанням, збагачувати неназваних учасників групи з локальних Contacts після проходження gating. За замовчуванням: `false`.
- `channels.bluebubbles.groups`: конфігурація для окремих груп (`requireMention` тощо).
</Accordion>
<Accordion title="Доставка та фрагментація">
- `channels.bluebubbles.sendReadReceipts`: Надсилати підтвердження прочитання (типово: `true`).
- `channels.bluebubbles.blockStreaming`: Увімкнути блокове потокове передавання (типово: `false`; потрібно для потокових відповідей).
<Accordion title="Доставка та поділ на фрагменти">
- `channels.bluebubbles.sendReadReceipts`: Надсилати сповіщення про прочитання (типово: `true`).
- `channels.bluebubbles.blockStreaming`: Увімкнути потокову передачу блоками (типово: `false`; потрібно для потокових відповідей).
- `channels.bluebubbles.textChunkLimit`: Розмір вихідного фрагмента в символах (типово: 4000).
- `channels.bluebubbles.sendTimeoutMs`: Тайм-аут на запит у мс для надсилання вихідного тексту через `/api/v1/message/text` (типово: 30000). Збільште для налаштувань macOS 26, де надсилання iMessage через Private API може зависати на 60+ секунд усередині фреймворку iMessage; наприклад `45000` або `60000`. Зондування, пошук чатів, реакції, редагування та перевірки стану наразі зберігають коротше типове значення 10 с; розширення покриття на реакції та редагування заплановано як наступний крок. Перевизначення для окремого облікового запису: `channels.bluebubbles.accounts.<accountId>.sendTimeoutMs`.
- `channels.bluebubbles.chunkMode`: `length` (типово) розбиває лише за перевищення `textChunkLimit`; `newline` розбиває за порожніми рядками (межами абзаців) перед розбиттям за довжиною.
- `channels.bluebubbles.sendTimeoutMs`: Тайм-аут на запит у мс для вихідного надсилання тексту через `/api/v1/message/text` (типово: 30000). Збільшіть для конфігурацій macOS 26, де надсилання iMessage через Private API може зависати на 60+ секунд усередині фреймворку iMessage; наприклад `45000` або `60000`. Зондування, пошук чатів, реакції, редагування та перевірки працездатності наразі зберігають коротше типове значення 10 с; розширення покриття на реакції та редагування заплановано як подальший крок. Перевизначення для облікового запису: `channels.bluebubbles.accounts.<accountId>.sendTimeoutMs`.
- `channels.bluebubbles.chunkMode`: `length` (типово) ділить лише за перевищення `textChunkLimit`; `newline` ділить за порожніми рядками (межами абзаців) перед поділом за довжиною.
</Accordion>
<Accordion title="Медіа та історія">
- `channels.bluebubbles.mediaMaxMb`: Ліміт вхідних/вихідних медіа в МБ (типово: 8).
- `channels.bluebubbles.mediaLocalRoots`: Явний список дозволених абсолютних локальних каталогів, дозволених для вихідних локальних шляхів медіа. Надсилання локальних шляхів типово заборонено, якщо це не налаштовано. Перевизначення для окремого облікового запису: `channels.bluebubbles.accounts.<accountId>.mediaLocalRoots`.
- `channels.bluebubbles.coalesceSameSenderDms`: Об’єднувати послідовні DM-вебхуки від того самого відправника в один хід агента, щоб Apple-розділення текст+URL надходило як одне повідомлення (типово: `false`). Див. [Об’єднання розділених DM](#coalescing-split-send-dms-command--url-in-one-composition) для сценаріїв, налаштування вікна та компромісів. Розширює типове вікно debounce для вхідних повідомлень із 500 мс до 2500 мс, якщо ввімкнено без явного `messages.inbound.byChannel.bluebubbles`.
- `channels.bluebubbles.historyLimit`: Максимальна кількість групових повідомлень для контексту (0 вимикає).
- `channels.bluebubbles.mediaLocalRoots`: Явний список дозволених абсолютних локальних каталогів, дозволених для вихідних локальних шляхів до медіа. Надсилання локальних шляхів типово заборонене, якщо це не налаштовано. Перевизначення для облікового запису: `channels.bluebubbles.accounts.<accountId>.mediaLocalRoots`.
- `channels.bluebubbles.coalesceSameSenderDms`: Об’єднувати послідовні DM Webhook від того самого відправника в один хід агента, щоб розділене Apple надсилання текст+URL надходило як одне повідомлення (типово: `false`). Див. [Об’єднання розділених DM](#coalescing-split-send-dms-command--url-in-one-composition) для сценаріїв, налаштування вікна та компромісів. Якщо ввімкнено без явного `messages.inbound.byChannel.bluebubbles`, розширює типове вікно debounce для вхідних повідомлень із 500 мс до 2500 мс.
- `channels.bluebubbles.historyLimit`: Максимум групових повідомлень для контексту (0 вимикає).
- `channels.bluebubbles.dmHistoryLimit`: Ліміт історії DM.
- `channels.bluebubbles.replyContextApiFallback`: Коли вхідна відповідь надходить без `replyToBody`/`replyToSender` і кеш контексту відповіді в пам’яті не спрацьовує, отримувати оригінальне повідомлення з BlueBubbles HTTP API як резервний варіант best-effort (типово: `false`). Корисно для розгортань із кількома екземплярами, що спільно використовують один обліковий запис BlueBubbles, після перезапусків процесу або після витіснення з довготривалого кешу TTL/LRU. Отримання захищене від SSRF тією самою політикою, що й кожен інший запит клієнта BlueBubbles, ніколи не кидає виняток і заповнює кеш, щоб подальші відповіді амортизували витрати. Перевизначення для окремого облікового запису: `channels.bluebubbles.accounts.<accountId>.replyContextApiFallback`. Налаштування рівня каналу поширюється на облікові записи, які пропускають цей прапорець.
- `channels.bluebubbles.replyContextApiFallback`: Коли вхідна відповідь надходить без `replyToBody`/`replyToSender`, а кеш контексту відповіді в пам’яті не спрацьовує, отримати початкове повідомлення з HTTP API BlueBubbles як резервний варіант best-effort (типово: `false`). Корисно для розгортань із кількома інстансами, що спільно використовують один обліковий запис BlueBubbles, після перезапусків процесу або після витіснення довгоживучого кешу TTL/LRU. Отримання захищене від SSRF тією самою політикою, що й кожен інший клієнтський запит BlueBubbles, ніколи не викидає помилку та заповнює кеш, щоб наступні відповіді амортизували витрати. Перевизначення для облікового запису: `channels.bluebubbles.accounts.<accountId>.replyContextApiFallback`. Налаштування на рівні каналу поширюється на облікові записи, де цей прапорець не задано.
</Accordion>
<Accordion title="Дії та облікові записи">
@ -605,7 +597,7 @@ OpenClaw може показувати _короткі_ ID повідомлен
## Адресація / цілі доставки
Віддавайте перевагу `chat_guid` для стабільної маршрутизації:
Надавайте перевагу `chat_guid` для стабільної маршрутизації:
- `chat_guid:iMessage;-;+15555550123` (бажано для груп)
- `chat_id:123`
@ -613,34 +605,34 @@ OpenClaw може показувати _короткі_ ID повідомлен
- Прямі дескриптори: `+15555550123`, `user@example.com`
- Якщо прямий дескриптор не має наявного DM-чату, OpenClaw створить його через `POST /api/v1/chat/new`. Для цього потрібно ввімкнути BlueBubbles Private API.
### Маршрутизація iMessage проти SMS
### Маршрутизація iMessage і SMS
Коли той самий дескриптор має і iMessage, і SMS-чат на Mac (наприклад номер телефону, зареєстрований в iMessage, але який також отримував зелені fallback-повідомлення), OpenClaw віддає перевагу чату iMessage і ніколи безшумно не понижує до SMS. Щоб примусово використати SMS-чат, застосуйте явний цільовий префікс `sms:` (наприклад `sms:+15555550123`). Дескриптори без відповідного iMessage-чату все одно надсилаються через будь-який чат, який повідомляє BlueBubbles.
Коли той самий дескриптор має на Mac і iMessage, і SMS-чат (наприклад, номер телефону, зареєстрований в iMessage, але який також отримував резервні green-bubble повідомлення), OpenClaw надає перевагу чату iMessage і ніколи непомітно не понижує маршрут до SMS. Щоб примусово використати SMS-чат, застосуйте явний префікс цілі `sms:` (наприклад `sms:+15555550123`). Дескриптори без відповідного iMessage-чату все одно надсилаються через будь-який чат, який повідомляє BlueBubbles.
## Безпека
- Webhook-запити автентифікуються шляхом порівняння query-параметрів або заголовків `guid`/`password` із `channels.bluebubbles.password`.
- Зберігайте пароль API та кінцеву точку Webhook у таємниці (ставтеся до них як до облікових даних).
- Для автентифікації Webhook BlueBubbles немає обходу через localhost. Якщо ви проксіюєте Webhook-трафік, зберігайте пароль BlueBubbles у запиті наскрізно. `gateway.trustedProxies` тут не замінює `channels.bluebubbles.password`. Див. [Безпека Gateway](/uk/gateway/security#reverse-proxy-configuration).
- Увімкніть HTTPS і правила firewall на сервері BlueBubbles, якщо відкриваєте його за межі своєї LAN.
- Запити Webhook автентифікуються шляхом порівняння query params або заголовків `guid`/`password` із `channels.bluebubbles.password`.
- Тримайте пароль API та кінцеву точку Webhook у секреті (ставтеся до них як до облікових даних).
- Для автентифікації Webhook BlueBubbles немає обходу через localhost. Якщо ви проксіюєте Webhook-трафік, зберігайте пароль BlueBubbles у запиті від початку до кінця. `gateway.trustedProxies` тут не замінює `channels.bluebubbles.password`. Див. [Безпека Gateway](/uk/gateway/security#reverse-proxy-configuration).
- Увімкніть HTTPS + правила firewall на сервері BlueBubbles, якщо відкриваєте його за межі своєї LAN.
## Усунення несправностей
## Усунення неполадок
- Якщо події введення/прочитання перестали працювати, перевірте журнали Webhook BlueBubbles і переконайтеся, що шлях Gateway відповідає `channels.bluebubbles.webhookPath`.
- Якщо події введення/прочитання перестають працювати, перевірте журнали Webhook BlueBubbles і переконайтеся, що шлях Gateway відповідає `channels.bluebubbles.webhookPath`.
- Коди сполучення спливають через одну годину; використовуйте `openclaw pairing list bluebubbles` і `openclaw pairing approve bluebubbles <code>`.
- Для реакцій потрібен приватний API BlueBubbles (`POST /api/v1/message/react`); переконайтеся, що версія сервера його надає.
- Для редагування/скасування надсилання потрібні macOS 13+ і сумісна версія сервера BlueBubbles. На macOS 26 (Tahoe) редагування наразі зламане через зміни private API.
- Оновлення іконки групи може бути нестабільним на macOS 26 (Tahoe): API може повернути успіх, але нова іконка не синхронізується.
- OpenClaw автоматично приховує відомо зламані дії на основі версії macOS сервера BlueBubbles. Якщо редагування все ще відображається на macOS 26 (Tahoe), вимкніть його вручну за допомогою `channels.bluebubbles.actions.edit=false`.
- `coalesceSameSenderDms` увімкнено, але розділені надсилання (наприклад `Dump` + URL) усе ще надходять як два ходи: див. контрольний список [усунення несправностей об’єднання розділених надсилань](#split-send-coalescing-troubleshooting) — поширені причини: занадто вузьке debounce-вікно, часові позначки журналу сесії помилково сприйняті як надходження Webhook, або надсилання цитати-відповіді (яке використовує `replyToBody`, а не другий Webhook).
- Для інформації про статус/стан: `openclaw status --all` або `openclaw status --deep`.
- Для реакцій потрібен private API BlueBubbles (`POST /api/v1/message/react`); переконайтеся, що версія сервера його надає.
- Для редагування/скасування надсилання потрібні macOS 13+ і сумісна версія сервера BlueBubbles. У macOS 26 (Tahoe) редагування наразі зламане через зміни private API.
- Оновлення групової іконки можуть бути нестабільними на macOS 26 (Tahoe): API може повернути успіх, але нова іконка не синхронізується.
- OpenClaw автоматично приховує відомо зламані дії на основі версії macOS сервера BlueBubbles. Якщо редагування все ще з’являється на macOS 26 (Tahoe), вимкніть його вручну за допомогою `channels.bluebubbles.actions.edit=false`.
- `coalesceSameSenderDms` увімкнено, але розділені надсилання (наприклад `Dump` + URL) все одно надходять як два ходи: див. контрольний список [усунення неполадок об’єднання розділених надсилань](#split-send-coalescing-troubleshooting) — поширені причини: занадто коротке вікно debounce, часові позначки журналу сеансу помилково сприйняті як надходження Webhook або надсилання цитати відповіді (яке використовує `replyToBody`, а не другий Webhook).
- Для інформації про статус/працездатність: `openclaw status --all` або `openclaw status --deep`.
Загальну довідку щодо робочого процесу каналів див. у [Канали](/uk/channels) та посібнику [Plugins](/uk/tools/plugin).
Загальну довідку щодо workflow каналів див. у [Канали](/uk/channels) та посібнику [Plugins](/uk/tools/plugin).
## Пов’язане
- [Маршрутизація каналів](/uk/channels/channel-routing) — маршрутизація сесій для повідомлень
- [Маршрутизація каналів](/uk/channels/channel-routing) — маршрутизація сеансів для повідомлень
- [Огляд каналів](/uk/channels) — усі підтримувані канали
- [Групи](/uk/channels/groups) — поведінка групового чату та контроль згадок
- [Сполучення](/uk/channels/pairing) — автентифікація DM і процес сполучення
- [Групи](/uk/channels/groups) — поведінка групових чатів і обмеження згадок
- [Сполучення](/uk/channels/pairing) — автентифікація DM і потік сполучення
- [Безпека](/uk/gateway/security) — модель доступу та посилення захисту

View File

@ -1,26 +1,26 @@
---
read_when:
- Ви хочете підключити OpenClaw до QQ
- Потрібно налаштувати облікові дані QQ Bot
- Вам потрібна підтримка групового або приватного чату QQ Bot
summary: Налаштування, конфігурація та використання QQ Bot
title: бот QQ
- Потрібне налаштування облікових даних QQ Bot
- Вам потрібна підтримка групових або приватних чатів QQ Bot
summary: Налаштування, конфігурація та використання бота QQ
title: QQ бот
x-i18n:
generated_at: "2026-05-03T11:35:25Z"
generated_at: "2026-05-03T22:33:30Z"
model: gpt-5.5
provider: openai
source_hash: 471c24110bf0ab8896d22f5bb5932ac4e03ff5169560c99ba6b9d1ca4025d9a8
source_hash: e17fa0da2f6939ed28cac5f13b3e37e6c63b87a10250ff213f7a86685a6141d6
source_path: channels/qqbot.md
workflow: 16
---
QQ Bot підключається до OpenClaw через офіційний QQ Bot API (WebSocket gateway). Plugin підтримує приватний чат C2C, групові @повідомлення та повідомлення в каналах guild із rich media (зображення, голос, відео, файли).
QQ Bot підключається до OpenClaw через офіційний QQ Bot API (WebSocket gateway). Plugin підтримує приватний чат C2C, групові @повідомлення та повідомлення каналів гільдій із розширеними медіа (зображення, голос, відео, файли).
Стан: Plugin доступний для завантаження. Прямі повідомлення, групові чати, канали guild і медіа підтримуються. Реакції та треди не підтримуються.
Стан: завантажуваний Plugin. Підтримуються прямі повідомлення, групові чати, канали гільдій і медіа. Реакції та треди не підтримуються.
## Встановлення
## Установлення
Встановіть QQ Bot перед налаштуванням:
Установіть QQ Bot перед налаштуванням:
```bash
openclaw plugins install @openclaw/qqbot
@ -28,9 +28,10 @@ openclaw plugins install @openclaw/qqbot
## Налаштування
1. Перейдіть на [QQ Open Platform](https://q.qq.com/) і відскануйте QR-код за допомогою QQ на телефоні, щоб зареєструватися / увійти.
2. Натисніть **Create Bot**, щоб створити нового QQ bot.
3. Знайдіть **AppID** і **AppSecret** на сторінці налаштувань bot і скопіюйте їх.
1. Перейдіть на [QQ Open Platform](https://q.qq.com/) і відскануйте QR-код своїм
телефоном із QQ, щоб зареєструватися / увійти.
2. Натисніть **Створити бота**, щоб створити нового QQ-бота.
3. Знайдіть **AppID** і **AppSecret** на сторінці налаштувань бота та скопіюйте їх.
> AppSecret не зберігається у відкритому тексті — якщо ви залишите сторінку, не зберігши його,
> вам доведеться згенерувати новий.
@ -71,7 +72,7 @@ openclaw configure --section channels
- `QQBOT_APP_ID`
- `QQBOT_CLIENT_SECRET`
AppSecret на основі файлу:
AppSecret із файлу:
```json5
{
@ -85,7 +86,7 @@ AppSecret на основі файлу:
}
```
AppSecret через Env SecretRef:
AppSecret Env SecretRef:
```json5
{
@ -101,16 +102,16 @@ AppSecret через Env SecretRef:
Примітки:
- Резервне значення з env застосовується лише до облікового запису QQ Bot за замовчуванням.
- Резервний варіант через змінні середовища застосовується лише до облікового запису QQ Bot за замовчуванням.
- `openclaw channels add --channel qqbot --token-file ...` надає лише
AppSecret; AppID вже має бути заданий у конфігурації або `QQBOT_APP_ID`.
- `clientSecret` також приймає вхідні дані SecretRef, а не лише відкритий текстовий рядок.
AppSecret; AppID уже має бути встановлено в конфігурації або `QQBOT_APP_ID`.
- `clientSecret` також приймає вхідні дані SecretRef, а не лише рядок у відкритому тексті.
- Застарілі рядки-маркери `secretref:/...` не є допустимими значеннями `clientSecret`;
використовуйте структуровані об'єкти SecretRef, як у прикладі вище.
### Налаштування кількох облікових записів
Запускайте кілька QQ bot в одному екземплярі OpenClaw:
Запустіть кілька QQ-ботів в одному екземплярі OpenClaw:
```json5
{
@ -134,7 +135,7 @@ AppSecret через Env SecretRef:
Кожен обліковий запис запускає власне WebSocket-з'єднання та підтримує незалежний
кеш токенів (ізольований за `appId`).
Додайте другого bot через CLI:
Додайте другого бота через CLI:
```bash
openclaw channels add --channel qqbot --account bot2 --token "222222222:secret-of-bot-2"
@ -142,7 +143,7 @@ openclaw channels add --channel qqbot --account bot2 --token "222222222:secret-o
### Групові чати
Підтримка групових чатів QQ Bot використовує OpenID груп QQ, а не відображувані імена. Додайте bot
Підтримка групових чатів QQ Bot використовує OpenID груп QQ, а не відображувані імена. Додайте бота
до групи, а потім згадайте його або налаштуйте групу для роботи без згадки.
```json5
@ -170,30 +171,30 @@ openclaw channels add --channel qqbot --account bot2 --token "222222222:secret-o
}
```
`groups["*"]` задає стандартні значення для кожної групи, а конкретний
запис `groups.GROUP_OPENID` перевизначає ці значення для однієї групи. Налаштування
групи містять:
`groups["*"]` задає стандартні параметри для кожної групи, а конкретний
запис `groups.GROUP_OPENID` перевизначає ці параметри для однієї групи. Налаштування
групи включають:
- `requireMention`: вимагати @згадку перед тим, як bot відповість. За замовчуванням: `true`.
- `ignoreOtherMentions`: відкидати повідомлення, які згадують когось іншого, але не bot.
- `historyLimit`: зберігати останні групові повідомлення без згадки як контекст для наступного ходу зі згадкою. Установіть `0`, щоб вимкнути.
- `requireMention`: вимагати @згадку перед тим, як бот відповість. За замовчуванням: `true`.
- `ignoreOtherMentions`: відкидати повідомлення, які згадують когось іншого, але не бота.
- `historyLimit`: зберігати нещодавні групові повідомлення без згадок як контекст для наступного ходу зі згадкою. Установіть `0`, щоб вимкнути.
- `toolPolicy`: `full`, `restricted` або `none` для інструментів у межах групи.
- `name`: зручна мітка, що використовується в журналах і контексті групи.
- `prompt`: запит поведінки для окремої групи, що додається до контексту агента.
- `name`: зрозуміла мітка, що використовується в журналах і контексті групи.
- `prompt`: підказка поведінки для окремої групи, додана до контексту агента.
Режими активації: `mention` і `always`. `requireMention: true` відповідає
`mention`; `requireMention: false` відповідає `always`. Перевизначення активації
на рівні сеансу, якщо воно наявне, має пріоритет над конфігурацією.
на рівні сеансу, якщо воно є, має пріоритет над конфігурацією.
Вхідна черга є окремою для кожного учасника. Групові учасники отримують більший ліміт черги, зберігають людські
повідомлення попереду повідомлень, створених bot, коли черга заповнена, і об'єднують серії звичайних
Вхідна черга створюється для кожного однорангового учасника. Групові учасники отримують більший ліміт черги, зберігають людські
повідомлення попереду повідомлень, написаних ботом, коли черга заповнена, і об'єднують сплески звичайних
групових повідомлень в один атрибутований хід. Slash-команди все одно виконуються по одній.
### Голос (STT / TTS)
Підтримка STT і TTS має дворівневу конфігурацію з пріоритетним резервним варіантом:
| Налаштування | Специфічне для Plugin | Резервний варіант framework |
| Параметр | Специфічно для Plugin | Резервний варіант фреймворку |
| ------- | -------------------------------------------------------- | ----------------------------- |
| STT | `channels.qqbot.stt` | `tools.media.audio.models[0]` |
| TTS | `channels.qqbot.tts`, `channels.qqbot.accounts.<id>.tts` | `messages.tts` |
@ -212,7 +213,7 @@ openclaw channels add --channel qqbot --account bot2 --token "222222222:secret-o
voice: "your-voice",
},
accounts: {
qq-main: {
"qq-main": {
tts: {
providers: {
openai: { voice: "shimmer" },
@ -226,15 +227,15 @@ openclaw channels add --channel qqbot --account bot2 --token "222222222:secret-o
```
Установіть `enabled: false` для будь-якого з них, щоб вимкнути.
Перевизначення TTS на рівні облікового запису використовують таку саму форму, як `messages.tts`, і глибоко об'єднуються
Перевизначення TTS на рівні облікового запису використовують ту саму форму, що й `messages.tts`, і виконують глибоке злиття
поверх конфігурації TTS каналу/глобальної конфігурації.
Вхідні голосові вкладення QQ доступні агентам як метадані аудіомедіа, тоді як
сирі голосові файли не потрапляють до загальних `MediaPaths`. Відповіді звичайним
Вхідні голосові вкладення QQ надаються агентам як метадані аудіомедіа, водночас
сирі голосові файли не потрапляють до загальних `MediaPaths`. Відповіді відкритим
текстом `[[audio_as_voice]]` синтезують TTS і надсилають нативне голосове повідомлення QQ, коли TTS
налаштовано.
Поведінку вихідного завантаження/transcode аудіо також можна налаштувати за допомогою
Поведінку вихідного завантаження/транскодування аудіо також можна налаштувати за допомогою
`channels.qqbot.audioFormatPolicy`:
- `sttDirectFormats`
@ -247,66 +248,66 @@ openclaw channels add --channel qqbot --account bot2 --token "222222222:secret-o
| -------------------------- | ------------------ |
| `qqbot:c2c:OPENID` | Приватний чат (C2C) |
| `qqbot:group:GROUP_OPENID` | Груповий чат |
| `qqbot:channel:CHANNEL_ID` | Канал guild |
| `qqbot:channel:CHANNEL_ID` | Канал гільдії |
> Кожен bot має власний набір OpenID користувачів. OpenID, отриманий Bot A, **не можна**
> використовувати для надсилання повідомлень через Bot B.
> Кожен бот має власний набір OpenID користувачів. OpenID, отриманий Ботом A, **не можна**
> використовувати для надсилання повідомлень через Бота B.
## Slash-команди
Вбудовані команди, що перехоплюються перед чергою AI:
Вбудовані команди, що перехоплюються перед чергою ШІ:
| Команда | Опис |
| -------------- | -------------------------------------------------------------------------------------------------------- |
| `/bot-ping` | Тест затримки |
| `/bot-version` | Показати версію framework OpenClaw |
| `/bot-help` | Показати список усіх команд |
| `/bot-me` | Показати QQ user ID (openid) відправника для налаштування `allowFrom`/`groupAllowFrom` |
| `/bot-version` | Показати версію фреймворку OpenClaw |
| `/bot-help` | Перелічити всі команди |
| `/bot-me` | Показати QQ ID користувача відправника (openid) для налаштування `allowFrom`/`groupAllowFrom` |
| `/bot-upgrade` | Показати посилання на посібник з оновлення QQBot |
| `/bot-logs` | Експортувати останні журнали gateway як файл |
| `/bot-approve` | Схвалити очікувану дію QQ Bot (наприклад, підтвердження завантаження C2C або групового завантаження) через нативний потік. |
| `/bot-logs` | Експортувати нещодавні журнали Gateway як файл |
| `/bot-approve` | Схвалити дію QQ Bot, що очікує на підтвердження (наприклад, підтвердження завантаження C2C або групового завантаження), через нативний потік. |
Додайте `?` до будь-якої команди, щоб отримати довідку з використання (наприклад, `/bot-upgrade ?`).
Команди адміністратора (`/bot-me`, `/bot-upgrade`, `/bot-logs`, `/bot-clear-storage`, `/bot-streaming`, `/bot-approve`) доступні лише в прямих повідомленнях і вимагають openid відправника в явному списку `allowFrom` без wildcard. Wildcard `allowFrom: ["*"]` дозволяє чат, але не надає доступ до команд адміністратора. Групові повідомлення спочатку зіставляються з `groupAllowFrom`, а потім використовують резервний `allowFrom`. Запуск команди адміністратора в групі повертає підказку, а не мовчки відкидається.
Адміністративні команди (`/bot-me`, `/bot-upgrade`, `/bot-logs`, `/bot-clear-storage`, `/bot-streaming`, `/bot-approve`) доступні лише в прямих повідомленнях і вимагають openid відправника в явному списку `allowFrom` без wildcard. Wildcard `allowFrom: ["*"]` дозволяє чат, але не надає доступу до адміністративних команд. Групові повідомлення спочатку звіряються з `groupAllowFrom`, а потім використовують резервний варіант `allowFrom`. Запуск адміністративної команди в групі повертає підказку, а не мовчки відкидає її.
## Архітектура рушія
QQ Bot постачається як самодостатній рушій усередині Plugin:
- Кожен обліковий запис має ізольований стек ресурсів (WebSocket-з'єднання, API-клієнт, кеш токенів, корінь сховища медіа), прив'язаний до `appId`. Облікові записи ніколи не спільно використовують вхідний/вихідний стан.
- Логер для кількох облікових записів позначає рядки журналу обліковим записом-власником, щоб діагностика залишалася відокремленою, коли ви запускаєте кілька bot під одним gateway.
- Вхідні, вихідні та gateway bridge шляхи спільно використовують один корінь медіаданих у `~/.openclaw/media`, тому завантаження, вивантаження та кеші transcode потрапляють в один захищений каталог замість дерева для кожної підсистеми.
- Доставка rich media проходить через один шлях `sendMedia` для цілей C2C і груп. Локальні файли та буфери, що перевищують поріг великого файлу, використовують chunked upload endpoints QQ, тоді як менші payload використовують одноразовий media API.
- Облікові дані можна створювати в резервних копіях і відновлювати як частину стандартних snapshot облікових даних OpenClaw; рушій повторно приєднує стек ресурсів кожного облікового запису під час відновлення без потреби в новій QR-code pair.
- Кожен обліковий запис володіє ізольованим стеком ресурсів (WebSocket-з'єднання, API-клієнт, кеш токенів, корінь сховища медіа), ключованим за `appId`. Облікові записи ніколи не спільно використовують вхідний/вихідний стан.
- Журналювач для кількох облікових записів позначає рядки журналу обліковим записом-власником, щоб діагностика залишалася роздільною, коли ви запускаєте кілька ботів під одним Gateway.
- Вхідні, вихідні та bridge-шляхи Gateway спільно використовують один корінь медіанавантажень у `~/.openclaw/media`, тому завантаження, вивантаження та кеші транскодування потрапляють в один захищений каталог замість дерева для кожної підсистеми.
- Доставка розширених медіа проходить через один шлях `sendMedia` для цілей C2C і груп. Локальні файли та буфери, що перевищують поріг великих файлів, використовують chunked upload endpoints QQ, тоді як менші навантаження використовують одноразовий media API.
- Облікові дані можна резервно копіювати та відновлювати як частину стандартних знімків облікових даних OpenClaw; рушій повторно приєднує стек ресурсів кожного облікового запису під час відновлення без потреби в новій парі QR-кодом.
## Онбординг через QR-код
## Онбординг за QR-кодом
Як альтернативу ручному вставленню `AppID:AppSecret`, рушій підтримує потік онбордингу через QR-код для прив'язування QQ Bot до OpenClaw:
Як альтернативу ручному вставленню `AppID:AppSecret`, рушій підтримує потік онбордингу за QR-кодом для зв'язування QQ Bot з OpenClaw:
1. Запустіть шлях налаштування QQ Bot (наприклад, `openclaw channels add --channel qqbot`) і виберіть потік QR-коду, коли буде запропоновано.
2. Відскануйте згенерований QR-код за допомогою телефонного застосунку, прив'язаного до цільового QQ Bot.
3. Підтвердьте сполучення на телефоні. OpenClaw зберігає повернені облікові дані в `credentials/` у правильній області облікового запису.
1. Запустіть шлях налаштування QQ Bot (наприклад, `openclaw channels add --channel qqbot`) і виберіть потік QR-коду, коли з'явиться запит.
2. Відскануйте згенерований QR-код телефонним застосунком, прив'язаним до цільового QQ Bot.
3. Схваліть сполучення на телефоні. OpenClaw зберігає повернуті облікові дані в `credentials/` у правильній області облікового запису.
Запити на схвалення, згенеровані самим bot (наприклад, потоки "allow this action?", доступні через QQ Bot API), відображаються як нативні запити OpenClaw, які можна прийняти за допомогою `/bot-approve`, а не відповідати через сирий клієнт QQ.
Запити на схвалення, згенеровані самим ботом (наприклад, потоки "дозволити цю дію?", надані QQ Bot API), відображаються як нативні запити OpenClaw, які можна прийняти за допомогою `/bot-approve`, а не відповідаючи через сирий клієнт QQ.
## Усунення несправностей
## Усунення неполадок
- **Bot replies "gone to Mars":** облікові дані не налаштовано або Gateway не запущено.
- **Немає вхідних повідомлень:** перевірте, що `appId` і `clientSecret` правильні, і що
bot увімкнено на QQ Open Platform.
- **Повторні відповіді самому собі:** OpenClaw записує вихідні ref indexes QQ як
створені bot і ігнорує вхідні події, чий поточний `msgIdx` збігається з тим
самим обліковим записом bot. Це запобігає echo loops платформи, водночас дозволяючи користувачам
цитувати або відповідати на попередні повідомлення bot.
- **Налаштування з `--token-file` все одно показує, що конфігурація відсутня:** `--token-file` задає лише
- **Бот відповідає "gone to Mars":** облікові дані не налаштовано або Gateway не запущено.
- **Немає вхідних повідомлень:** перевірте, що `appId` і `clientSecret` правильні, а
бот увімкнений на QQ Open Platform.
- **Повторювані самовідповіді:** OpenClaw записує індекси вихідних посилань QQ як
написані ботом і ігнорує вхідні події, поточний `msgIdx` яких збігається з тим
самим обліковим записом бота. Це запобігає циклам відлуння платформи, водночас дозволяючи користувачам
цитувати попередні повідомлення бота або відповідати на них.
- **Налаштування з `--token-file` все ще показує, що не налаштовано:** `--token-file` встановлює лише
AppSecret. Вам усе ще потрібен `appId` у конфігурації або `QQBOT_APP_ID`.
- **Проактивні повідомлення не надходять:** QQ може перехоплювати повідомлення, ініційовані bot, якщо
користувач останнім часом не взаємодіяв.
- **Голос не транскрибується:** переконайтеся, що STT налаштовано, а provider доступний.
- **Проактивні повідомлення не надходять:** QQ може перехоплювати повідомлення, ініційовані ботом, якщо
користувач не взаємодіяв нещодавно.
- **Голос не транскрибується:** переконайтеся, що STT налаштовано, а провайдер доступний.
## Пов'язане
- [Сполучення](/uk/channels/pairing)
- [Групи](/uk/channels/groups)
- [Усунення несправностей каналу](/uk/channels/troubleshooting)
- [Усунення неполадок каналу](/uk/channels/troubleshooting)

File diff suppressed because it is too large Load Diff