@openclaw/signal). Gateway взаимодействует с signal-cli по HTTP: либо с нативным демоном (JSON-RPC + SSE), либо с контейнером bbernhard/signal-cli-rest-api (REST + WebSocket). OpenClaw не включает libsignal.
Модель номеров (прочитайте сначала)
- Gateway подключается к устройству Signal: учётной записи
signal-cli. - Если бот работает в вашей личной учётной записи Signal, он игнорирует ваши собственные сообщения (защита от зацикливания).
- Чтобы реализовать сценарий «я пишу боту, а он отвечает», используйте отдельный номер бота.
Установка
openclaw plugins install clawhub:@openclaw/signal или npm:@openclaw/signal. plugins install регистрирует и включает плагин; отдельный шаг enable не требуется. Общие правила установки см. в разделе Плагины.
Быстрая настройка
1
Выберите номер
Используйте для бота отдельный номер Signal (рекомендуется).
2
Установите плагин
3
Запустите пошаговую настройку
signal-cli в PATH, и при его отсутствии предлагает установить его: загружает официальную нативную сборку GraalVM для Linux x86-64 либо устанавливает через Homebrew в macOS и на других архитектурах. Затем он запрашивает номер бота и путь signal-cli.Для неинтерактивной настройки openclaw channels add --channel signal также принимает --signal-number <e164> для номера телефона бота, а также --http-host <host> и --http-port <port> для конечной точки демона Signal (по умолчанию 127.0.0.1:8080).4
5
Проверьте и выполните сопряжение
openclaw pairing approve signal <CODE>.
Поддержка нескольких учётных записей: используйте
channels.signal.accounts с конфигурацией для каждой учётной записи и необязательным name. Общий шаблон см. в разделе Каналы с несколькими учётными записями.
Что это такое
- Детерминированная маршрутизация: ответы всегда отправляются обратно в Signal.
- Личные сообщения используют основной сеанс агента совместно; группы изолированы (
agent:<agentId>:signal:group:<groupId>). - По умолчанию Signal может записывать изменения конфигурации, инициированные
/config set|unset(требуетсяcommands.config: true). Отключите это с помощьюchannels.signal.configWrites: false.
Вариант настройки A: привязка существующей учётной записи Signal (QR-код)
- Установите
signal-cli(сборку JVM или нативную сборку) либо позвольтеopenclaw channels addустановить её. - Привяжите учётную запись бота:
signal-cli link -n "OpenClaw", затем отсканируйте QR-код в Signal. - Настройте Signal и запустите Gateway.
Вариант настройки B: регистрация отдельного номера бота (SMS, Linux)
Используйте этот вариант для отдельного номера бота вместо привязки существующей учётной записи приложения Signal. Приведённый ниже процесс протестирован в Ubuntu 24.- Получите номер, способный принимать SMS (или голосовые вызовы для проверки стационарных номеров). Отдельный номер бота позволяет избежать конфликтов учётных записей и сеансов.
- Установите
signal-cliна хосте Gateway:
signal-cli-${VERSION}.tar.gz), сначала установите JRE. Своевременно обновляйте signal-cli; разработчики исходного проекта отмечают, что старые выпуски могут перестать работать по мере изменения серверных API Signal.
- Зарегистрируйте и подтвердите номер:
- Откройте
https://signalcaptchas.org/registration/generate.html. - Пройдите капчу и скопируйте целевой адрес ссылки
signalcaptcha://...из «Open Signal». - По возможности запускайте команду с того же внешнего IP-адреса, что и сеанс браузера (срок действия токенов капчи быстро истекает).
- Незамедлительно зарегистрируйте и подтвердите номер:
- Настройте OpenClaw, перезапустите Gateway и проверьте канал:
- Выполните сопряжение отправителя личных сообщений:
- Отправьте любое сообщение на номер бота.
- Подтвердите на сервере:
openclaw pairing approve signal <PAIRING_CODE>. - Сохраните номер бота в контактах телефона, чтобы избежать пометки «Unknown contact».
- README
signal-cli:https://github.com/AsamK/signal-cli - Процесс работы с капчей:
https://github.com/AsamK/signal-cli/wiki/Registration-with-captcha - Процесс привязки:
https://github.com/AsamK/signal-cli/wiki/Linking-other-devices-(Provisioning)
Режим внешнего демона (httpUrl)
Чтобы самостоятельно управлятьsignal-cli (медленный холодный запуск JVM, инициализация контейнера, общие ресурсы ЦП), запустите демон отдельно и укажите его адрес в OpenClaw:
channels.signal.startupTimeoutMs.
Режим контейнера (bbernhard/signal-cli-rest-api)
Вместо нативного запускаsignal-cli используйте Docker-контейнер bbernhard/signal-cli-rest-api, который предоставляет доступ к signal-cli через интерфейс REST + WebSocket.
Требования:
- Контейнер должен работать с
MODE=json-rpcдля получения сообщений в реальном времени. - Перед подключением OpenClaw зарегистрируйте или привяжите учётную запись Signal внутри контейнера.
docker-compose.yml:
apiMode определяет, какой протокол использует OpenClaw:
Когда
apiMode имеет значение "auto", OpenClaw кэширует обнаруженный режим на 30 секунд для каждого URL демона, чтобы избежать повторных проверок (если оба транспорта исправны, приоритет имеет нативный). Получение через контейнер выбирается для потоковой передачи только после перехода /v1/receive/{account} на WebSocket, для которого требуется MODE=json-rpc.
Режим контейнера поддерживает те же операции Signal, что и нативный режим, если контейнер предоставляет соответствующие API: отправку и получение сообщений, вложения, индикаторы набора текста, уведомления о прочтении и просмотре, реакции, группы и форматированный текст. OpenClaw преобразует нативные вызовы Signal RPC в полезные нагрузки REST контейнера, включая идентификаторы групп group.{base64(internal_id)} и text_mode: "styled" для форматированного текста.
Примечания по эксплуатации:
- В режиме контейнера используйте
autoStart: false; OpenClaw не должен запускать нативный демон, когда выбранapiMode: "container". - Для получения сообщений используйте
MODE=json-rpc.MODE=normalможет создавать впечатление, что/v1/aboutисправен, но/v1/receive/{account}не выполнит переход на WebSocket, поэтому OpenClaw не выберет потоковое получение через контейнер в режимеauto. - Задайте
apiMode: "container", когдаhttpUrlуказывает на REST API bbernhard,"native", когда он указывает на нативный JSON-RPC/SSEsignal-cli, и"auto", когда вариант развёртывания может меняться. - При загрузке вложений в режиме контейнера действуют те же ограничения на объём медиаданных в байтах, что и в нативном режиме. Если сервер отправляет
Content-Length, ответы чрезмерного размера отклоняются до полной буферизации, а в остальных случаях — во время потоковой передачи.
Управление доступом (личные сообщения и группы)
Личные сообщения:- По умолчанию:
channels.signal.dmPolicy = "pairing". - Неизвестные отправители получают код сопряжения; сообщения игнорируются до подтверждения (срок действия кодов истекает через 1 час).
- Подтвердите с помощью
openclaw pairing list signalиopenclaw pairing approve signal <CODE>. - Сопряжение — стандартный способ обмена токенами для личных сообщений Signal. Подробнее: Сопряжение
- Отправители, идентифицируемые только по UUID (из
sourceUuid), сохраняются какuuid:<id>вchannels.signal.allowFrom.
channels.signal.groupPolicy = open | allowlist | disabled.channels.signal.groupAllowFromопределяет, какие группы или отправители могут инициировать ответы в группах, когда заданallowlist; в качестве записей могут использоваться идентификаторы групп Signal (необработанные,group:<id>илиsignal:group:<id>), номера телефонов отправителей, значенияuuid:<id>или*.channels.signal.groups["<group-id>" | "*"]может переопределять поведение группы с помощьюrequireMention,toolsиtoolsBySender.- Для переопределений на уровне учётных записей в конфигурациях с несколькими учётными записями используйте
channels.signal.accounts.<id>.groups. - Добавление группы Signal в список разрешённых с помощью
groupAllowFromсамо по себе не отключает требование упоминания. Явно настроенная записьchannels.signal.groups["<group-id>"]обрабатывает каждое сообщение группы, если не заданrequireMention=true. - При
requireMention=trueнативные упоминания @ в Signal сопоставляются по структурированным метаданным упоминаний с номером телефона илиaccountUuidучётной записи бота. НастроенныеmentionPatternsостаются резервным вариантом на основе обычного текста. - Примечание о среде выполнения: если
channels.signalполностью отсутствует, среда выполнения используетgroupPolicy="allowlist"как резервный вариант для проверок групп (даже если заданchannels.defaults.groupPolicy).
Принцип работы (поведение)
- Нативный режим:
signal-cliработает как демон; Gateway считывает события через SSE. - Контейнерный режим: Gateway отправляет сообщения через REST API и получает их через WebSocket.
- Входящие сообщения нормализуются в общий конверт канала.
- Ответы всегда направляются на тот же номер или в ту же группу.
- Ответы на входящие сообщения содержат нативные метаданные цитирования Signal, если серверная часть принимает временную метку и автора входящего сообщения; если метаданные цитирования отсутствуют или отклонены, OpenClaw отправляет ответ как обычное сообщение.
- Настройте использование нативного цитирования с помощью
channels.signal.replyToMode = off | first | all | batchedилиchannels.signal.replyToModeByChatType.direct/groupдля переопределений по типу чата. Значения уровня учётной записи вchannels.signal.accounts.<id>имеют приоритет.
Медиафайлы и ограничения
- Исходящий текст разбивается на фрагменты размером
channels.signal.textChunkLimit(по умолчанию 4000). - Необязательное разбиение по переводам строк: задайте
channels.signal.streaming.chunkMode="newline", чтобы перед разбиением по длине разделять текст по пустым строкам (границам абзацев). - Вложения поддерживаются (данные base64 получаются из
signal-cli). - Для вложений с голосовыми заметками имя файла
signal-cliиспользуется как резервное значение MIME, еслиcontentTypeотсутствует, поэтому при расшифровке аудио голосовые заметки AAC всё равно можно классифицировать. - Ограничение медиафайлов по умолчанию:
channels.signal.mediaMaxMb(по умолчанию 8). - Используйте
channels.signal.ignoreAttachments, чтобы пропустить загрузку медиафайлов. - Контекст истории группы использует
channels.signal.historyLimit(илиchannels.signal.accounts.*.historyLimit), с резервным переходом кmessages.groupChat.historyLimit. Задайте0, чтобы отключить его (по умолчанию 50).
Индикаторы набора и уведомления о прочтении
- Индикаторы набора: OpenClaw отправляет сигналы набора через
signal-cli sendTypingи обновляет их во время формирования ответа. - Уведомления о прочтении: когда
channels.signal.sendReadReceiptsимеет значение true, OpenClaw пересылает уведомления о прочтении для разрешённых личных сообщений. signal-cliне предоставляет уведомления о прочтении для групп.
Реакции на состояния жизненного цикла
Задайтеmessages.statusReactions.enabled: true, чтобы Signal отображал общий жизненный цикл реакций «в очереди / обдумывание / инструмент / Compaction / завершено / ошибка» для входящих запросов. Signal использует временную метку входящего сообщения в качестве цели реакции; групповые реакции отправляются с идентификатором группы Signal и исходным отправителем в качестве целевого автора.
Для реакций на состояния также требуются реакция подтверждения и соответствующее значение messages.ackReactionScope (direct, group-all, group-mentions или all). Задайте channels.signal.reactionLevel: "off", чтобы отключить реакции Signal на состояния.
messages.removeAckAfterReply: true удаляет итоговую реакцию на состояние по истечении настроенного времени отображения. В противном случае Signal восстанавливает исходную реакцию подтверждения после итогового состояния завершения или ошибки.
Реакции (инструмент сообщений)
Используйтеmessage action=react с channel=signal.
- Цели: номер отправителя в формате E.164 или UUID (используйте
uuid:<id>из вывода сопряжения; UUID без префикса также поддерживается). messageId— временная метка Signal сообщения, на которое добавляется реакция.- Для групповых реакций требуется
targetAuthorилиtargetAuthorUuid.
channels.signal.actions.reactions: включить или отключить действия с реакциями (по умолчанию true).channels.signal.reactionLevel:off | ack | minimal | extensive(по умолчаниюminimal).off/ackотключает реакции агента (инструмент сообщенийreactвозвращает ошибки).minimal/extensiveвключает реакции агента и задаёт уровень рекомендаций.
- Переопределения для отдельных учётных записей:
channels.signal.accounts.<id>.actions.reactions,channels.signal.accounts.<id>.reactionLevel.
Реакции подтверждения
Запросы на подтверждение выполнения и плагинов Signal используют блоки маршрутизации верхнего уровняapprovals.exec и approvals.plugin. В Signal нет блока channels.signal.execApprovals.
👍подтверждает однократно.👎отклоняет.- Используйте
/approve <id> allow-always, если запрос предлагает постоянное подтверждение.
channels.signal.allowFrom, channels.signal.defaultTo или соответствующих полей уровня учётной записи. Прямые запросы на подтверждение выполнения в том же чате могут по-прежнему скрывать дублирующий локальный резервный вариант /approve без явно заданных подтверждающих пользователей; для групповых подтверждений без подтверждающих пользователей локальный резервный вариант остаётся видимым.
Цели доставки (CLI/Cron)
- Личные сообщения:
signal:+15551234567(или обычный номер E.164). - Личные сообщения по UUID:
uuid:<id>(или UUID без префикса). - Группы:
signal:group:<groupId>. - Имена пользователей:
username:<name>(если поддерживаются вашей учётной записью Signal).
Псевдонимы
Настройте псевдонимы для постоянных имён регулярно используемых целей Signal. Псевдонимы существуют только в конфигурации OpenClaw; они не создают и не изменяют контакты Signal.openclaw directory peers list --channel signal и openclaw directory groups list --channel signal выводят список настроенных псевдонимов. Каталог Signal формируется на основе конфигурации; он не запрашивает контакты Signal в реальном времени и не изменяет учётную запись Signal.
Устранение неполадок
Сначала выполните следующую последовательность:- Демон доступен, но ответов нет: проверьте настройки учётной записи и демона (
httpUrl,account), а также режим получения. - Личные сообщения игнорируются: отправитель ожидает подтверждения сопряжения.
- Групповые сообщения игнорируются: ограничения по отправителю группы или упоминанию блокируют доставку.
- Ошибки проверки конфигурации после изменений: выполните
openclaw doctor --fix. - Signal отсутствует в диагностике: проверьте
channels.signal.enabled: true.
Примечания по безопасности
signal-cliхранит ключи учётной записи локально (обычно в~/.local/share/signal-cli/data/).- Создайте резервную копию состояния учётной записи Signal перед переносом или повторным развёртыванием сервера.
- Сохраняйте значение
channels.signal.dmPolicy: "pairing", если более широкий доступ к личным сообщениям явно не требуется. - Подтверждение по SMS требуется только для регистрации или восстановления, однако утрата контроля над номером или учётной записью может усложнить повторную регистрацию.
Справочник по конфигурации (Signal)
Полная конфигурация: Конфигурация Параметры провайдера:channels.signal.enabled: включить или отключить запуск канала.channels.signal.apiMode:auto | native | container(по умолчанию: автоматически). См. Контейнерный режим.channels.signal.account: номер учётной записи бота в формате E.164.channels.signal.accountUuid: необязательный UUID учётной записи бота для обнаружения нативных @упоминаний и защиты от зацикливания.channels.signal.cliPath: путь кsignal-cli.channels.signal.configPath: необязательный каталогsignal-cli --config.channels.signal.httpUrl: полный URL демона (переопределяет хост и порт).channels.signal.httpHost,channels.signal.httpPort: адрес привязки демона (по умолчанию127.0.0.1:8080).channels.signal.autoStart: автоматически запускать демон (по умолчанию true, еслиhttpUrlне задан).channels.signal.startupTimeoutMs: время ожидания запуска в мс (минимум 1000, максимум 120000; по умолчанию 30000).channels.signal.receiveMode:on-start | manual.channels.signal.ignoreAttachments: пропускать загрузку вложений.channels.signal.ignoreStories: игнорировать истории от демона.channels.signal.sendReadReceipts: пересылать уведомления о прочтении.channels.signal.dmPolicy:pairing | allowlist | open | disabled(по умолчанию: сопряжение).channels.signal.allowFrom: список разрешённых отправителей личных сообщений (E.164 илиuuid:<id>). Дляopenтребуется"*". В Signal нет имён пользователей; используйте идентификаторы телефона или UUID.channels.signal.aliases: псевдонимы OpenClaw для целей доставки личных или групповых сообщений.channels.signal.groupPolicy:open | allowlist | disabled(по умолчанию: список разрешённых).channels.signal.groupAllowFrom: список разрешённых групп; принимает идентификаторы групп Signal (необработанные,group:<id>илиsignal:group:<id>), номера отправителей в формате E.164 или значенияuuid:<id>.channels.signal.groups: переопределения для отдельных групп с ключами в виде идентификатора группы Signal (или"*"). Поддерживаемые поля:requireMention,tools,toolsBySender.channels.signal.accounts.<id>.groups: версияchannels.signal.groupsдля отдельных учётных записей в конфигурациях с несколькими учётными записями.channels.signal.accounts.<id>.aliases: псевдонимы отдельных учётных записей, объединяемые с псевдонимами верхнего уровня.channels.signal.replyToMode: режим нативного цитирования в ответах,off | first | all | batched(по умолчанию:all).channels.signal.replyToModeByChatType.direct,channels.signal.replyToModeByChatType.group: переопределения нативного цитирования в ответах по типу чата.channels.signal.accounts.<id>.replyToMode,channels.signal.accounts.<id>.replyToModeByChatType.direct,channels.signal.accounts.<id>.replyToModeByChatType.group: переопределения цитирования в ответах для отдельных учётных записей.channels.signal.historyLimit: максимальное количество групповых сообщений, включаемых в контекст (0 отключает).channels.signal.dmHistoryLimit: ограничение истории личных сообщений в пользовательских запросах. Переопределения для отдельных пользователей:channels.signal.dms["<phone_or_uuid>"].historyLimit.channels.signal.textChunkLimit: размер исходящего фрагмента в символах (по умолчанию 4000).channels.signal.streaming.chunkMode:length(по умолчанию) илиnewline, чтобы перед разбиением по длине разделять текст по пустым строкам (границам абзацев).channels.signal.mediaMaxMb: ограничение входящих и исходящих медиафайлов в МБ (по умолчанию 8).channels.signal.reactionLevel:off | ack | minimal | extensive(по умолчаниюminimal). См. Реакции.channels.signal.reactionNotifications:off | own | all | allowlist(по умолчаниюown) — когда агент получает уведомления о входящих реакциях других пользователей.channels.signal.reactionAllowlist: отправители, чьи реакции уведомляют агента приreactionNotifications: "allowlist".channels.signal.streaming.block.enabled,channels.signal.streaming.block.coalesce: общие для каналов элементы управления потоковой передачей в блочном режиме. См. Потоковая передача.
agents.list[].groupChat.mentionPatterns(резервный вариант в виде обычного текста; нативные @упоминания Signal определяются по структурированным метаданным, когда настроена идентификация учётной записи бота).messages.groupChat.mentionPatterns(глобальный резервный вариант).messages.responsePrefix.
Связанные материалы
- Обзор каналов — все поддерживаемые каналы
- Сопряжение — аутентификация в личных сообщениях и процесс сопряжения
- Группы — поведение групповых чатов и обработка только при упоминании
- Маршрутизация каналов — маршрутизация сеансов для сообщений
- Безопасность — модель доступа и усиление защиты