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 поточному авторизованому запитувачу та відтворити повідомлення 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.
Налаштуйте синтез мовлення та виклик із WhatsApp
Налаштуйте придатного для телефонії постачальника синтезу мовлення, перезапустіть Gateway, а потім надішліть запит на кшталт Зателефонуй мені та скажи, що збірку завершено. Інструмент визначає відправника з довіреного вхідного контексту, синтезує тимчасовий приватний файл 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 до плагінів, якщо ви явно не погодилися:
{ channels: { whatsapp: { pluginHooks: { messageReceived: true, }, }, },}Обмежте цю згоду одним обліковим записом у channels.whatsapp.accounts.<id>.pluginHooks.messageReceived. Вмикайте це лише для плагінів, яким ви довіряєте вхідний вміст та ідентифікатори 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 не задано.
Нормалізація повідомлень і контекст
Вхідний конверт і контекст відповіді
Вхідні повідомлення обгортаються у спільний вхідний конверт. Цитована відповідь додає контекст у такому вигляді:
[Відповідь для <sender> id:<stanzaId>]<цитований текст або заповнювач медіафайлу>[/Відповідь]Метадані відповіді (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вимикає
Маркери додавання: [Повідомлення чату після вашої останньої відповіді — для контексту] і [Поточне повідомлення — дайте відповідь на нього].
Сповіщення про прочитання
За замовчуванням увімкнені для прийнятих вхідних повідомлень. Щоб вимкнути глобально:
{ channels: { whatsapp: { sendReadReceipts: false } } }Перевизначення для окремого облікового запису: channels.whatsapp.accounts.<id>.sendReadReceipts. У чатах із собою сповіщення про прочитання пропускаються, навіть якщо вони глобально ввімкнені.
Доставка, поділ на частини та медіафайли
Поділ тексту на частини
- стандартне обмеження частини:
channels.whatsapp.textChunkLimit = 4000 channels.whatsapp.chunkMode = "length" | "newline";newlineнадає перевагу межам абзаців (порожнім рядкам), а потім переходить до безпечного поділу за довжиною
Поведінка вихідних медіафайлів
- підтримує зображення, відео, аудіо (голосові повідомлення PTT) і документи
- аудіо надсилається як корисне навантаження Baileys
audioзptt: trueі відтворюється як голосове повідомлення «натисни й говори»;audioAsVoiceзберігається в корисному навантаженні відповіді, щоб результат TTS у форматі голосового повідомлення залишався на цьому шляху незалежно від вихідного формату постачальника - нативне аудіо Ogg/Opus надсилається як
audio/ogg; codecs=opus; усе інше (включно з результатом TTS Microsoft Edge у форматі MP3/WebM) перед доставкою PTT перекодовується за допомогоюffmpegу монофонічний Ogg/Opus із частотою 48 кГц /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 для WhatsApp має використовувати Node. Bun позначено як несумісний зі стабільною роботою Gateway для WhatsApp/Telegram.
Системні підказки
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, 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 |