Mainstream messaging
Статус: готово до промислової експлуатації через WhatsApp Web (Baileys). Gateway керує пов’язаними сеансами; окремого каналу Twilio WhatsApp немає.
Установлення
openclaw onboard і openclaw channels add --channel whatsapp пропонують установити Plugin під час першого вибору; openclaw channels login --channel whatsapp пропонує такий самий процес установлення, якщо Plugin відсутній. Середовища розробки використовують локальний шлях до Plugin; стабільні та бета-версії спочатку встановлюють @openclaw/whatsapp із ClawHub, а в разі невдачі використовують npm. Середовище виконання WhatsApp постачається поза основним npm-пакетом OpenClaw, тому його залежності середовища виконання залишаються із зовнішнім Plugin. Установлення вручну:
openclaw plugins install clawhub:@openclaw/whatsappВикористовуйте простий пакет npm (@openclaw/whatsapp) лише як резервний варіант реєстру; закріплюйте точну версію лише для відтворюваного встановлення.
Типова політика особистих повідомлень для невідомих відправників — сполучення.
Міжканальна діагностика та сценарії відновлення.
Повні шаблони й приклади конфігурації каналів.
Швидке налаштування
Налаштуйте політику доступу
{channels: {whatsapp: { dmPolicy: "pairing", allowFrom: ["+15551234567"], groupPolicy: "allowlist", groupAllowFrom: ["+15551234567"],},},}Пов’яжіть WhatsApp (QR-код)
openclaw channels login --channel whatsappВхід можливий лише за QR-кодом. На віддалених хостах або хостах без графічного інтерфейсу перед початком входу забезпечте надійний спосіб доставити актуальний QR-код на телефон; QR-коди, відображені в терміналі, знімки екрана або вкладення в чаті можуть стати недійсними під час передавання.
Для певного облікового запису:
openclaw channels login --channel whatsapp --account workЩоб підключити наявний або власний каталог автентифікації перед входом:
openclaw channels add --channel whatsapp --account work --auth-dir /path/to/wa-authopenclaw channels login --channel whatsapp --account workЗапустіть Gateway
openclaw gatewayСхваліть перший запит на сполучення (режим сполучення)
openclaw pairing list whatsappopenclaw pairing approve whatsapp <CODE>Термін дії запитів на сполучення спливає через 1 годину; кількість запитів в очікуванні обмежена до 3 на обліковий запис.
Схеми розгортання
Окремий номер (рекомендовано)
- окрема ідентичність WhatsApp для OpenClaw
- чіткіші списки дозволених відправників особистих повідомлень і межі маршрутизації
- нижча ймовірність плутанини з чатом із самим собою
{ channels: { whatsapp: { dmPolicy: "allowlist", allowFrom: ["+15551234567"], }, },}Резервний варіант з особистим номером
Початкове налаштування підтримує режим особистого номера та записує базову конфігурацію, придатну для чату із самим собою: dmPolicy: "allowlist", allowFrom, що містить ваш власний номер, selfChatMode: true. Захист чату із самим собою під час виконання спирається на пов’язаний власний номер і allowFrom.
Модель середовища виконання
- Gateway керує сокетом WhatsApp і циклом повторного підключення.
- Сторожовий процес незалежно відстежує два сигнали: активність необробленого транспорту WhatsApp Web та активність повідомлень застосунку. Тихий, але підключений сеанс не перезапускається лише через те, що останнім часом не надходили повідомлення; повторне підключення виконується примусово, тільки якщо транспортні кадри не надходять протягом фіксованого внутрішнього проміжку часу (користувач не може його налаштувати) або повідомлення застосунку не надходять довше ніж 4-кратний звичайний час очікування повідомлення. Відразу після повторного підключення нещодавно активного сеансу для першого проміжку використовується коротший звичайний час очікування повідомлення замість 4-кратного проміжку. OpenClaw може автоматично відповідати на офлайн-повідомлення, які Baileys доставляє на початку такого повторного підключення, у межах часу життя дедуплікації ідентифікаторів вхідних повідомлень; під час початкового запуску зберігається короткий захист від застарілої історії.
- Часові параметри сокета Baileys явно задаються в
web.whatsapp.*:keepAliveIntervalMs(інтервал перевірки доступності застосунку),connectTimeoutMs(час очікування початкового рукостискання),defaultQueryTimeoutMs(очікування запитів Baileys, а також час очікування вихідного надсилання, присутності та вхідних підтверджень прочитання в OpenClaw). - Для вихідного надсилання потрібен активний слухач WhatsApp для цільового облікового запису; інакше надсилання негайно завершується помилкою.
- До групових повідомлень додаються нативні метадані згадок для токенів
@+<digits>і@<digits>(у тексті та підписах до медіафайлів), коли токен відповідає поточним метаданим учасника, зокрема в групах на основі LID. - Чати статусів і трансляцій (
@status,@broadcast) ігноруються. - Прямі чати використовують правила сеансів особистих повідомлень (
session.dmScope; типове значенняmainоб’єднує особисті повідомлення в основному сеансі агента). Групові сеанси ізольовані для кожного JID (agent:<agentId>:whatsapp:group:<jid>). - Канали/розсилки WhatsApp можуть бути явними цілями вихідного надсилання через власний JID
@newsletter, використовуючи метадані сеансу каналу (agent:<agentId>:whatsapp:channel:<jid>), а не семантику особистих повідомлень. - Транспорт WhatsApp Web враховує стандартні змінні середовища проксі на хості Gateway (
HTTPS_PROXY,HTTP_PROXY,NO_PROXYта варіанти в нижньому регістрі). Надавайте перевагу налаштуванню проксі на рівні хоста, а не окремого каналу. - Якщо ввімкнено
messages.removeAckAfterReply, OpenClaw прибирає реакцію-підтвердження після доставки видимої відповіді.
Виклик поточного запитувача через MeowCaller (експериментальна функція)
Plugin може надавати whatsapp_call у зверненнях агента, що надходять із WhatsApp. Він використовує MeowCaller, щоб здійснити голосовий виклик WhatsApp поточному авторизованому запитувачу та відтворити повідомлення TTS від OpenClaw після відповіді. Інструмент не має параметра номера призначення, тому запит не може переспрямувати виклик. Типово вимкнено.
Увімкніть експериментальні виклики
Додайте actions.calls: true до конфігурації каналу WhatsApp і перезапустіть Gateway:
{"channels": {"whatsapp": { "actions": { "calls": true }}}}Якщо значення відсутнє або дорівнює false, OpenClaw не надає інструмент whatsapp_call.
Установіть перевірений CLI MeowCaller
Адаптер очікує виконуваний файл meowcaller у PATH хоста Gateway. Поки PR MeowCaller № 7 не об’єднано, зберіть перевірену гілку:
git clone --branch feat/send-only-notify https://github.com/steipete/meowcaller.gitcd meowcallergit checkout 752050471fc2bf7a8cdfbf7dbd3cd4e865d85d3fmkdir -p "$HOME/.local/bin"go build -o "$HOME/.local/bin/meowcaller" ./cmd/meowcallerПереконайтеся, що $HOME/.local/bin входить до PATH служби Gateway. Ця ревізія має явні команди pair і notify лише для надсилання; notify не відкриває мікрофон, динамік, відеопристрій або діагностичне захоплення. Не замінюйте її командою play із прикладу CLI основного проєкту.
Сполучіть пов’язаний пристрій MeowCaller
Попросіть агента WhatsApp перевірити налаштування викликів (дія стану whatsapp_call повідомляє каталог стану для конкретного облікового запису та команду сполучення). Для типового облікового запису:
state_dir="$HOME/.openclaw/credentials/whatsapp-calls/default"mkdir -p "$state_dir"chmod 700 "$state_dir"meowcaller pair --store "$state_dir/wa-voip.db"Запустіть це інтерактивно, відскануйте QR-код у WhatsApp > Linked devices і дочекайтеся MeowCaller linked device ready. Зберігайте wa-voip.db у таємниці — це сеанс MeowCaller. Нетипові облікові записи отримують власний шлях до сховища від дії стану; у Windows виконайте відповідну команду PowerShell.
Налаштуйте TTS і здійсніть виклик із WhatsApp
Налаштуйте постачальника TTS, що підтримує телефонію, перезапустіть Gateway, а потім надішліть запит, наприклад Call me and say the build finished. Інструмент визначає відправника з довіреного вхідного контексту, синтезує тимчасовий приватний WAV-файл, запускає MeowCaller на обмежений проміжок виклику та після цього видаляє аудіофайл. OpenClaw явно передає сховище облікового запису, очікує нульового коду завершення після відповіді, відтворення та завершення виклику й вважає перевищення часу очікування або ненульовий код завершення невдалим викликом інструмента.
Обмеження: лише вихідні аудіовиклики один на один, без довільних номерів призначення, без спільної автентифікації зі з’єднанням чату, без викликів самого себе в режимі особистого номера або чату із самим собою, тривалість синтезованого аудіо обмежена 60 секундами, немає підтвердження чутності на телефоні понад завершення відповіді, відтворення та завершення виклику в MeowCaller, а OpenClaw зупиняє супровідний процес після обмеженого проміжку 115–175 секунд (що охоплює етапи підключення, відповіді, відтворення та завершення роботи MeowCaller).
Запити на схвалення
WhatsApp може відображати запити на схвалення виконання та Plugin як реакції 👍/👎, керовані конфігурацією пересилання схвалень верхнього рівня:
{ approvals: { exec: { enabled: true, mode: "session", }, plugin: { enabled: true, mode: "targets", targets: [{ channel: "whatsapp", to: "+15551234567" }], }, },}approvals.exec і approvals.plugin незалежні; увімкнення WhatsApp як каналу лише пов’язує транспорт і нічого не надсилає, якщо відповідну групу схвалень не ввімкнено та не спрямовано туди. Режим сеансу доставляє нативні схвалення за допомогою емодзі лише для схвалень, що походять із WhatsApp. Режим цілей використовує спільний конвеєр пересилання для явних цілей і не створює окремого розгалуження особистих повідомлень для осіб, які схвалюють.
Для реакцій схвалення WhatsApp потрібні явно вказані особи, які схвалюють, у allowFrom (або "*"). defaultTo задає звичайні типові цілі повідомлень, а не список осіб, які схвалюють. Команди /approve, введені вручну, перед визначенням схвалення все одно проходять звичайний шлях авторизації відправника WhatsApp.
Хуки Plugin і конфіденційність
Вхідні повідомлення WhatsApp можуть містити особистий вміст, номери телефонів, ідентифікатори груп, імена відправників і поля кореляції сеансів. WhatsApp не транслює вхідні дані хуків message_received до Plugin, якщо ви явно не погодилися:
{ channels: { whatsapp: { pluginHooks: { messageReceived: true, }, }, },}Обмежте цю згоду одним обліковим записом у channels.whatsapp.accounts.<id>.pluginHooks.messageReceived. Вмикайте це лише для Plugin, яким довіряєте вхідний вміст та ідентифікатори WhatsApp.
Керування доступом і активація
Політика особистих повідомлень
channels.whatsapp.dmPolicy:
| Значення | Поведінка |
|---|---|
pairing (типово) |
Невідомі відправники запитують сполучення; власник схвалює |
allowlist |
Допускаються лише відправники з allowFrom |
open |
Вимагає, щоб allowFrom містив "*" |
disabled |
Блокувати всі особисті повідомлення |
allowFrom приймає номери у форматі E.164 (із внутрішньою нормалізацією). Це лише список керування доступом відправників особистих повідомлень — він не обмежує явне вихідне надсилання до групових JID або JID каналів @newsletter.
Перевизначення для кількох облікових записів: channels.whatsapp.accounts.<id>.dmPolicy (і .allowFrom) мають пріоритет над типовими значеннями рівня каналу для відповідного облікового запису.
Примітки щодо середовища виконання:
- прив’язування зберігаються у сховищі дозволів каналу та об’єднуються з налаштованим
allowFrom - запланована автоматизація та резервне визначення одержувача Heartbeat використовують явні цілі доставки або налаштований
allowFrom; схвалення прив’язування приватних повідомлень не роблять їхніх учасників неявними одержувачами Cron/Heartbeat - якщо список дозволів не налаштовано, прив’язаний власний номер дозволено за замовчуванням
- OpenClaw ніколи автоматично не прив’язує вихідні приватні повідомлення
fromMe(повідомлення, які надсилаються самому собі з прив’язаного пристрою)
Політика груп і списки дозволів
Доступ до груп має два рівні:
- Список дозволених груп (
channels.whatsapp.groups): якщоgroupsпропущено, усі групи доступні; якщо вказано, він діє як список дозволених груп ("*"дозволяє всі). - Політика щодо відправників у групах (
channels.whatsapp.groupPolicy+groupAllowFrom):openобходить список дозволених відправників,allowlistвимагає відповідностіgroupAllowFrom(або*),disabledблокує всі вхідні повідомлення з груп.
Якщо groupAllowFrom не задано, перевірки відправників використовують як резервний allowFrom, коли він містить записи. Списки дозволених відправників перевіряються до активації згадкою або відповіддю.
Якщо блок channels.whatsapp взагалі відсутній, середовище виконання використовує як резервний groupPolicy: "allowlist" (із попередженням у журналі), навіть якщо channels.defaults.groupPolicy має інше значення.
Згадки та /activation
За замовчуванням для відповідей у групі потрібна згадка. Виявлення згадок охоплює:
- явні згадки ідентичності бота у WhatsApp
- налаштовані шаблони регулярних виразів для згадок (
agents.list[].groupChat.mentionPatterns, резервнийmessages.groupChat.mentionPatterns) - транскрипції вхідних голосових нотаток для авторизованих групових повідомлень
- неявне виявлення відповіді боту (відправник відповіді відповідає ідентичності бота)
Безпека: цитування або відповідь лише задовольняє вимогу згадки — воно не надає авторизацію відправнику. З groupPolicy: "allowlist" відправники поза списком дозволів залишаються заблокованими, навіть коли відповідають на повідомлення користувача зі списку дозволів.
Команда активації на рівні сеансу: /activation mention або /activation always. Вона оновлює стан сеансу (а не глобальну конфігурацію) і доступна лише власнику.
Налаштовані прив’язування ACP
WhatsApp підтримує постійні прив’язування ACP через bindings[] верхнього рівня:
{ bindings: [ { type: "acp", agentId: "codex", match: { channel: "whatsapp", accountId: "work", peer: { kind: "direct", id: "+15555550123" }, }, }, { type: "acp", agentId: "codex", match: { channel: "whatsapp", accountId: "work", peer: { kind: "group", id: "120363424282127706@g.us" }, }, }, ],}Прямі чати зіставляються з номерами E.164, а групи — з груповими JID WhatsApp. Списки дозволених груп, політика щодо відправників і перевірка активації згадкою виконуються до того, як OpenClaw забезпечить існування прив’язаного сеансу ACP. Зіставлене прив’язування володіє маршрутом — групи трансляції не розподіляють цей хід між звичайними сеансами WhatsApp.
Поведінка особистого номера та чату із собою
Коли прив’язаний власний номер також наявний у allowFrom, активуються запобіжники для чату із собою: пропускаються звіти про прочитання для ходів у чаті із собою, ігнорується автоматичне спрацювання за JID згадки, яке сповістило б вас самих, а відповіді за замовчуванням надсилаються до [{identity.name}] (або [openclaw]), коли messages.responsePrefix не задано.
Нормалізація повідомлень і контекст
Вхідний конверт і контекст відповіді
Вхідні повідомлення загортаються у спільний вхідний конверт. Цитована відповідь додає контекст у такому вигляді:
[Replying to <sender> id:<stanzaId>]<quoted body or media placeholder>[/Replying]Метадані відповіді (ReplyToId, ReplyToBody, ReplyToSender, JID/E.164 відправника) заповнюються, коли доступні. Якщо цитованим об’єктом є медіафайл, доступний для завантаження, OpenClaw зберігає його через звичайне сховище вхідних медіафайлів і надає MediaPath/MediaType, щоб агент міг перевірити його безпосередньо, а не бачити лише <media:image>.
Заповнювачі медіафайлів і видобування розташування/контактів
Повідомлення, що містять лише медіафайли, нормалізуються до заповнювачів: <media:image>, <media:video>, <media:audio>, <media:document>, <media:sticker>.
Авторизовані групові голосові нотатки транскрибуються до перевірки згадки, коли тіло містить лише <media:audio>, тому згадка бота в голосовій нотатці може спричинити відповідь. Якщо транскрипція все одно не згадує бота, вона залишається в історії групи, що очікує обробки, замість необробленого заповнювача.
Дані про розташування відображаються як стислий текст із координатами. Мітки/коментарі розташування та дані контактів/vCard відображаються як огороджені ненадійні метадані, а не як вбудований текст запиту.
Вставлення історії групи, що очікує обробки
Необроблені групові повідомлення буферизуються та вставляються як контекст, коли бот нарешті активується.
- обмеження за замовчуванням:
50 - конфігурація:
channels.whatsapp.historyLimit, резервнийmessages.groupChat.historyLimit 0вимикає
Маркери вставлення: [Chat messages since your last reply - for context] і [Current message - respond to this].
Звіти про прочитання
За замовчуванням увімкнено для прийнятих вхідних повідомлень. Глобальне вимкнення:
{ channels: { whatsapp: { sendReadReceipts: false } } }Перевизначення для окремого облікового запису: channels.whatsapp.accounts.<id>.sendReadReceipts. Для ходів у чаті із собою звіти про прочитання пропускаються, навіть якщо їх глобально ввімкнено.
Доставка, поділ на фрагменти та медіафайли
Поділ тексту на фрагменти
- обмеження фрагмента за замовчуванням:
channels.whatsapp.textChunkLimit = 4000 channels.whatsapp.streaming.chunkMode = "length" | "newline";newlineнадає перевагу межам абзаців (порожнім рядкам), а потім переходить до безпечного поділу за довжиною
Поведінка вихідних медіафайлів
- підтримує корисні навантаження зображень, відео, аудіо (голосових нотаток PTT) і документів
- аудіо надсилається як корисне навантаження Baileys
audioзptt: trueі відображається як голосова нотатка push-to-talk;audioAsVoiceзберігається в корисних навантаженнях відповіді, щоб виведення голосових нотаток TTS залишалося на цьому шляху незалежно від вихідного формату провайдера - власне аудіо Ogg/Opus надсилається як
audio/ogg; codecs=opus; усе інше (зокрема вихідні дані Microsoft Edge TTS у форматі MP3/WebM) перед доставкою PTT перекодовується за допомогоюffmpegу монофонічний Ogg/Opus із частотою 48 kHz /tts latestнадсилає останню відповідь асистента як одну голосову нотатку й запобігає повторному надсиланню тієї самої відповіді;/tts chat on|off|defaultкерує автоматичним TTS для поточного чатуgifPlayback: trueдля відео вмикає відтворення анімованого GIFforceDocument/asDocumentспрямовує вихідні зображення, GIF і відео через корисне навантаження документа Baileys, щоб уникнути стиснення медіафайлів у WhatsApp, зберігаючи визначене ім’я файлу та тип MIME- підписи застосовуються до першого медіафайлу у відповіді з кількома медіафайлами, крім голосових нотаток PTT: аудіо надсилається першим без підпису, а потім підпис надсилається окремим текстовим повідомленням (клієнти WhatsApp відображають підписи голосових нотаток непослідовно)
- джерелом медіафайлу може бути HTTP(S),
file://або локальний шлях
Обмеження розміру медіафайлів і резервна поведінка
- обмеження збереження вхідних і надсилання вихідних даних:
channels.whatsapp.mediaMaxMb(за замовчуванням50) - перевизначення для окремого облікового запису:
channels.whatsapp.accounts.<id>.mediaMaxMb - зображення автоматично оптимізуються (зміна розміру/перебір якості), щоб відповідати обмеженням, якщо
forceDocument/asDocumentне вимагає доставки як документа - у разі помилки надсилання медіафайлу резервна поведінка для першого елемента надсилає текстове попередження, а не мовчки відкидає відповідь
Цитування у відповідях
channels.whatsapp.replyToMode керує власним цитуванням у відповідях (вихідні відповіді помітно цитують вхідне повідомлення):
| Значення | Поведінка |
|---|---|
"off" (за замовчуванням) |
Ніколи не цитувати; надсилати як звичайне повідомлення |
"first" |
Цитувати лише перший фрагмент вихідної відповіді |
"all" |
Цитувати кожен фрагмент вихідної відповіді |
"batched" |
Цитувати згруповані відповіді з черги; негайні відповіді залишати без цитування |
Перевизначення для окремого облікового запису: channels.whatsapp.accounts.<id>.replyToMode.
{ channels: { whatsapp: { replyToMode: "first" } } }Рівень реакцій
channels.whatsapp.reactionLevel визначає, наскільки широко агент використовує реакції емодзі:
| Рівень | Реакції-підтвердження | Реакції, ініційовані агентом |
|---|---|---|
"off" |
Ні | Ні |
"ack" |
Так | Ні |
"minimal" (за замовчуванням) |
Так | Так, консервативні настанови |
"extensive" |
Так | Так, заохочувальні настанови |
Перевизначення для окремого облікового запису: channels.whatsapp.accounts.<id>.reactionLevel.
{ channels: { whatsapp: { reactionLevel: "ack" } } }Реакції-підтвердження
channels.whatsapp.ackReaction надсилає негайну реакцію після отримання вхідного повідомлення з урахуванням reactionLevel (не надсилається, коли "off"):
{ channels: { whatsapp: { ackReaction: { emoji: "👀", direct: true, group: "mentions", // always | mentions | never }, }, },}Примітки: надсилається одразу після прийняття вхідного повідомлення (до відповіді); якщо ackReaction наявний без emoji, WhatsApp використовує емодзі ідентичності спрямованого агента, а як резервний — "👀" (пропустіть ackReaction або задайте emoji: "", щоб не надсилати підтвердження); помилки реєструються в журналі, але не блокують доставку відповіді; груповий режим mentions реагує лише на ходи, активовані згадкою, а групова активація always обходить цю перевірку; WhatsApp використовує лише channels.whatsapp.ackReaction (застарілий messages.ackReaction тут не застосовується).
Реакції на стан життєвого циклу
Задайте messages.statusReactions.enabled: true, щоб WhatsApp замінював реакцію-підтвердження протягом ходу, а не залишав статичний емодзі отримання, циклічно переходячи між такими станами, як очікування в черзі, обмірковування, активність інструментів, Compaction, завершення та помилка:
{ messages: { statusReactions: { enabled: true, emojis: { deploy: "🛫", build: "🏗️", concierge: "💁", }, }, },}Примітки: channels.whatsapp.ackReaction і надалі визначає доступність для прямих повідомлень і груп; стан очікування в черзі використовує той самий ефективний емодзі, що й звичайні реакції-підтвердження; WhatsApp має одне місце для реакції бота на повідомлення, тому оновлення життєвого циклу замінюють поточну реакцію на місці; messages.removeAckAfterReply: true прибирає остаточну реакцію стану після налаштованого періоду утримання для завершення/помилки; категорії емодзі інструментів охоплюють tool, coding, web, deploy, build і concierge.
Кілька облікових записів і облікові дані
Вибір облікового запису та типові значення
Ідентифікатори облікових записів беруться з channels.whatsapp.accounts. Типово вибирається обліковий запис default, якщо він наявний; інакше — перший налаштований ідентифікатор облікового запису (за алфавітним сортуванням). Ідентифікатори облікових записів внутрішньо нормалізуються для пошуку.
Шляхи до облікових даних і сумісність із застарілими версіями
- поточний шлях автентифікації:
~/.openclaw/credentials/whatsapp/<accountId>/creds.json(резервна копія:creds.json.bak) - застаріла типова автентифікація в
~/.openclaw/credentials/усе ще розпізнається та мігрується для сценаріїв із типовим обліковим записом
Поведінка під час виходу
openclaw channels logout --channel whatsapp [--account <id>] очищає стан автентифікації WhatsApp для цього облікового запису. Коли gateway доступний, вихід спочатку зупиняє активний слухач для цього облікового запису, тому пов’язаний сеанс припиняє отримувати повідомлення ще до наступного перезапуску. openclaw channels remove --channel whatsapp також зупиняє активний слухач перед вимкненням або видаленням конфігурації облікового запису.
У застарілих каталогах автентифікації oauth.json зберігається, а файли автентифікації Baileys видаляються.
Інструменти, дії та запис конфігурації
- Підтримка інструментів агента охоплює дію реакції WhatsApp (
react). - Обмежувачі дій:
channels.whatsapp.actions.reactions,channels.whatsapp.actions.polls(типове значення для наявних дій —true),channels.whatsapp.actions.calls(типове значення —false, див. MeowCaller вище). - Запис конфігурації, ініційований каналом, типово ввімкнено; вимкніть його через
channels.whatsapp.configWrites: false.
Усунення несправностей
Не пов’язано (потрібен QR-код)
Ознака: стан каналу повідомляє, що зв’язок не встановлено.
openclaw channels login --channel whatsappopenclaw channels statusПов’язано, але від’єднано / цикл повторного підключення
Ознака: пов’язаний обліковий запис із повторюваними від’єднаннями або спробами повторного підключення.
Неактивні облікові записи можуть залишатися підключеними довше за звичайний тайм-аут повідомлень; сторожовий процес перезапускає з’єднання лише тоді, коли припиняється активність транспорту WhatsApp Web, закривається сокет або активність на рівні застосунку відсутня довше за збільшене захисне вікно (див. «Модель середовища виконання» вище).
Якщо журнали містять повторювані status=408 Request Time-out Connection was lost, налаштуйте часові параметри сокета Baileys у web.whatsapp. Спочатку зменште keepAliveIntervalMs до значення, нижчого за тайм-аут бездіяльності вашої мережі, і збільште connectTimeoutMs для повільних з’єднань або з’єднань із втратами:
{ web: { whatsapp: { keepAliveIntervalMs: 15000, connectTimeoutMs: 60000, defaultQueryTimeoutMs: 60000, }, },}Виправлення:
openclaw channels status --probeopenclaw doctoropenclaw logs --followopenclaw gateway statusЯкщо цикл зберігається після виправлення підключення хоста та часових параметрів, створіть резервну копію каталогу автентифікації облікового запису й повторно встановіть зв’язок:
cp -a ~/.openclaw/credentials/whatsapp/<accountId> \ ~/.openclaw/credentials/whatsapp/<accountId>.bakopenclaw channels logout --channel whatsapp --account <accountId>openclaw channels login --channel whatsapp --account <accountId>Якщо ~/.openclaw/logs/whatsapp-health.log повідомляє Gateway inactive, але openclaw gateway status і openclaw channels status --probe обидва показують справний стан, виконайте openclaw doctor. У Linux doctor попереджає про застарілі записи crontab, що викликають виведений з експлуатації скрипт ~/.openclaw/bin/ensure-whatsapp.sh; видаліть ці записи за допомогою crontab -e — у cron може бути відсутнє середовище користувацької шини systemd, через що старий скрипт неправильно повідомляє про стан gateway.
Час очікування входу за QR-кодом спливає за проксі-сервером
Ознака: openclaw channels login --channel whatsapp завершується помилкою до показу придатного для використання QR-коду з status=408 Request Time-out або від’єднанням TLS-сокета.
Вхід у WhatsApp Web використовує стандартне проксі-середовище хоста gateway (HTTPS_PROXY, HTTP_PROXY, варіанти в нижньому регістрі, NO_PROXY). Переконайтеся, що процес gateway успадковує змінні середовища проксі та що NO_PROXY не відповідає mmg.whatsapp.net.
Немає активного слухача під час надсилання
Вихідне надсилання негайно завершується помилкою, якщо для цільового облікового запису немає активного слухача gateway. Переконайтеся, що gateway запущено, а обліковий запис пов’язано.
Відповідь є в транскрипті, але відсутня у WhatsApp
Рядки транскрипту фіксують те, що згенерував агент; доставку у WhatsApp перевіряють окремо. OpenClaw вважає автоматичну відповідь надісланою лише після того, як Baileys поверне ідентифікатор вихідного повідомлення принаймні для одного видимого надсилання тексту або медіафайлу.
Реакції-підтвердження є незалежними квитанціями, що надсилаються до відповіді, — успішна реакція не доводить, що подальшу текстову або медіавідповідь було прийнято. Перевірте журнали gateway на наявність auto-reply delivery failed або auto-reply was not accepted by WhatsApp provider.
Повідомлення групи неочікувано ігноруються
Перевірте в такому порядку: groupPolicy, groupAllowFrom/allowFrom, записи списку дозволів groups, обмеження за згадкою (requireMention + шаблони згадок) і дублікати ключів у openclaw.json (у JSON5 пізніші записи перевизначають попередні — залишайте лише один groupPolicy для кожної області).
Якщо наявний channels.whatsapp.groups, WhatsApp усе ще може бачити повідомлення з інших груп, але OpenClaw відкидає їх до маршрутизації сеансу. Додайте JID групи до channels.whatsapp.groups або додайте groups["*"], щоб дозволити всі групи, зберігши авторизацію відправників через groupPolicy/groupAllowFrom.
Попередження середовища виконання Bun
Для gateway OpenClaw потрібен Node. Bun не надає API node:sqlite, який використовує канонічне сховище стану, а doctor мігрує застарілі служби Bun на Node.
Системні підказки
WhatsApp підтримує системні підказки в стилі Telegram для груп і прямих чатів через мапи groups та direct.
Визначення для групових повідомлень: спочатку визначається ефективна мапа groups — якщо обліковий запис узагалі визначає власний ключ groups, він повністю замінює кореневу мапу groups (без глибокого злиття). Потім пошук підказки виконується в цій єдиній отриманій мапі:
- Підказка для конкретної групи (
groups["<groupId>"].systemPrompt): використовується, коли запис групи існує і визначено його ключsystemPrompt. Порожній рядок ("") пригнічує шаблон і не застосовує жодної підказки. - Групова підказка-шаблон (
groups["*"].systemPrompt): використовується, коли запис конкретної групи відсутній або існує без ключаsystemPrompt.
Визначення для прямих повідомлень виконується за тією самою схемою для мапи direct і direct["*"].
Відмінність від Telegram: Telegram пригнічує кореневий groups для кожного облікового запису в конфігурації з кількома обліковими записами (навіть для облікових записів без власного groups), щоб бот не отримував групові повідомлення з груп, до яких він не належить. WhatsApp не застосовує цей захист — кореневі groups/direct успадковуються будь-яким обліковим записом без власного перевизначення незалежно від кількості облікових записів. У конфігурації WhatsApp із кількома обліковими записами явно визначте повну мапу для кожного облікового запису, якщо потрібні окремі підказки для кожного з них.
Важливі аспекти поведінки:
channels.whatsapp.groupsє одночасно мапою конфігурації для кожної групи та списком дозволів груп на рівні чату. На кореневому рівні або рівні облікового записуgroups["*"]означає «дозволено всі групи» для цієї області.- Додавайте шаблон
systemPromptлише тоді, коли вже потрібно дозволити всі групи в цій області. Щоб дозволити лише фіксований набір ідентифікаторів груп, повторіть підказку в кожному явно дозволеному записі замість використанняgroups["*"]. - Допуск груп і авторизація відправників є окремими перевірками.
groups["*"]розширює перелік груп, що потрапляють до обробки груп; він не авторизує кожного відправника в цих групах — це й надалі контролюється черезgroupPolicy/groupAllowFrom. channels.whatsapp.directне має аналогічного побічного ефекту для приватних повідомлень:direct["*"]лише надає типову конфігурацію після того, як приватне повідомлення вже допущено черезdmPolicyразом ізallowFromабо правилами сховища пов’язування.
Приклад:
{ channels: { whatsapp: { groups: { // Використовуйте лише тоді, коли на кореневому рівні потрібно дозволити всі групи. // Застосовується до всіх облікових записів, які не визначають власну мапу groups. "*": { systemPrompt: "Типова підказка для всіх груп." }, }, direct: { // Застосовується до всіх облікових записів, які не визначають власну мапу direct. "*": { systemPrompt: "Типова підказка для всіх прямих чатів." }, }, accounts: { work: { groups: { // Цей обліковий запис визначає власну мапу groups, тому кореневу мапу groups повністю // замінено. Щоб зберегти шаблон, явно визначте "*" також тут. "120363406415684625@g.us": { requireMention: false, systemPrompt: "Зосереджуйтеся на керуванні проєктами.", }, // Використовуйте лише тоді, коли в цьому обліковому записі потрібно дозволити всі групи. "*": { systemPrompt: "Типова підказка для робочих груп." }, }, direct: { // Цей обліковий запис визначає власну мапу direct, тому кореневі записи direct // повністю замінено. Щоб зберегти шаблон, явно визначте "*" також тут. "+15551234567": { systemPrompt: "Підказка для конкретного робочого прямого чату." }, "*": { systemPrompt: "Типова підказка для робочих прямих чатів." }, }, }, }, }, },}Посилання на довідник конфігурації
Основний довідник: Довідник конфігурації — WhatsApp
| Область | Поля |
|---|---|
| Доступ | dmPolicy, allowFrom, groupPolicy, groupAllowFrom, groups |
| Доставка | textChunkLimit, streaming.chunkMode, mediaMaxMb, sendReadReceipts, ackReaction, reactionLevel |
| Кілька облікових записів | accounts.<id>.enabled, accounts.<id>.authDir та інші перевизначення для кожного облікового запису |
| Операції | configWrites, debounceMs, web.enabled, web.heartbeatSeconds, web.reconnect.*, web.whatsapp.* |
| Поведінка сеансу | session.dmScope, historyLimit, dmHistoryLimit, dms.<id>.historyLimit |
| Підказки | groups.<id>.systemPrompt, groups["*"].systemPrompt, direct.<id>.systemPrompt, direct["*"].systemPrompt |