Signal (signal-cli)

Статус: интеграция внешнего CLI. Шлюз общается с signal-cli через HTTP JSON-RPC + SSE.

Быстрая настройка (для начинающих)

  1. Используйте отдельный номер Signal для бота (рекомендуется).
  2. Установите signal-cli (требуется Java).
  3. Привяжите устройство бота и запустите демон:
    • signal-cli link -n "OpenClaw"
  4. Настройте OpenClaw и запустите шлюз.

Минимальная конфигурация:

{
  channels: {
    signal: {
      enabled: true,
      account: "+15551234567",
      cliPath: "signal-cli",
      dmPolicy: "pairing",
      allowFrom: ["+15557654321"]
    }
  }
}

Что это

  • Канал Signal через signal-cli (не встроенный libsignal).
  • Детерминированная маршрутизация: ответы всегда возвращаются в Signal.
  • Личные сообщения используют основную сессию агента; группы изолированы (agent:<agentId>:signal:group:<groupId>).

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

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

Отключить:

{
  channels: { signal: { configWrites: false } }
}

Модель номера (важно)

  • Шлюз подключается к устройству Signal (учетная запись signal-cli).
  • Если вы запускаете бота на вашей личной учетной записи Signal, он будет игнорировать ваши собственные сообщения (защита от циклов).
  • Для "Я отправляю текст боту, и он отвечает" используйте отдельный номер бота.

Настройка (быстрый путь)

  1. Установите signal-cli (требуется Java).
  2. Привяжите учетную запись бота:
    • signal-cli link -n "OpenClaw" затем отсканируйте QR в Signal.
  3. Настройте Signal и запустите шлюз.

Пример:

{
  channels: {
    signal: {
      enabled: true,
      account: "+15551234567",
      cliPath: "signal-cli",
      dmPolicy: "pairing",
      allowFrom: ["+15557654321"]
    }
  }
}

Поддержка нескольких учетных записей: используйте channels.signal.accounts с конфигурацией для каждой учетной записи и необязательным name. См. gateway/configuration для общего паттерна.

Режим внешнего демона (httpUrl)

Если вы хотите управлять signal-cli самостоятельно (медленные холодные старты JVM, инициализация контейнера или общие CPU), запустите демон отдельно и направьте OpenClaw на него:

{
  channels: {
    signal: {
      httpUrl: "http://127.0.0.1:8080",
      autoStart: false
    }
  }
}

Это пропускает автозапуск и ожидание запуска внутри OpenClaw. Для медленных стартов при автозапуске установите channels.signal.startupTimeoutMs.

Контроль доступа (личные сообщения + группы)

Личные сообщения:

  • По умолчанию: 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-cli работает как демон; шлюз читает события через SSE.
  • Входящие сообщения нормализуются в общий конверт канала.
  • Ответы всегда направляются обратно на тот же номер или группу.

Медиа + лимиты

  • Исходящий текст делится на фрагменты до channels.signal.textChunkLimit (по умолчанию 4000).
  • Опциональное разделение по новой строке: установите channels.signal.chunkMode="newline" для разделения по пустым строкам (границы абзацев) перед разделением по длине.
  • Поддерживаются вложения (base64 извлекается из signal-cli).
  • Ограничение медиа по умолчанию: 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 истинно, OpenClaw пересылает уведомления о прочтении для разрешенных личных сообщений.
  • Signal-cli не предоставляет уведомления о прочтении для групп.

Реакции (инструмент message)

  • Используйте message action=react с channel=signal.
  • Цели: E.164 отправителя или UUID (используйте uuid:<id> из вывода сопряжения; также работает голый UUID).
  • messageId - это временная метка Signal для сообщения, на которое вы реагируете.
  • Реакции в группах требуют targetAuthor или targetAuthorUuid.

Примеры:

message action=react channel=signal target=uuid:123e4567-e89b-12d3-a456-426614174000 messageId=1737630212345 emoji=🔥
message action=react channel=signal target=+15551234567 messageId=1737630212345 emoji=🔥 remove=true
message action=react channel=signal target=signal:group:<groupId> targetAuthor=uuid:<sender-uuid> messageId=1737630212345 emoji=✅

Конфигурация:

  • channels.signal.actions.reactions: включить/отключить действия реакций (по умолчанию true).
  • channels.signal.reactionLevel: off | ack | minimal | extensive.
    • off/ack отключает реакции агента (инструмент message react вернет ошибку).
    • minimal/extensive включает реакции агента и устанавливает уровень руководства.
  • Переопределения для каждой учетной записи: channels.signal.accounts.<id>.actions.reactions, channels.signal.accounts.<id>.reactionLevel.

Цели доставки (CLI/cron)

  • Личные сообщения: signal:+15551234567 (или простой E.164).
  • Личные сообщения UUID: uuid:<id> (или голый UUID).
  • Группы: signal:group:<groupId>.
  • Имена пользователей: username:<name> (если поддерживается вашей учетной записью Signal).

Справочник по конфигурации (Signal)

Полная конфигурация: Конфигурация

Опции провайдера:

  • channels.signal.enabled: включить/отключить запуск канала.
  • channels.signal.account: E.164 для учетной записи бота.
  • channels.signal.cliPath: путь к signal-cli.
  • channels.signal.httpUrl: полный URL демона (переопределяет host/port).
  • channels.signal.httpHost, channels.signal.httpPort: привязка демона (по умолчанию 127.0.0.1:8080).
  • channels.signal.autoStart: автозапуск демона (по умолчанию true, если httpUrl не установлен).
  • channels.signal.startupTimeoutMs: таймаут ожидания запуска в мс (макс. 120000).
  • channels.signal.receiveMode: on-start | manual.
  • channels.signal.ignoreAttachments: пропустить загрузку вложений.
  • channels.signal.ignoreStories: игнорировать истории из демона.
  • channels.signal.sendReadReceipts: пересылать уведомления о прочтении.
  • channels.signal.dmPolicy: pairing | allowlist | open | disabled (по умолчанию: pairing).
  • channels.signal.allowFrom: список разрешенных для личных сообщений (E.164 или uuid:<id>). open требует "*". Signal не имеет имен пользователей; используйте телефон/UUID идентификаторы.
  • channels.signal.groupPolicy: open | allowlist | disabled (по умолчанию: allowlist).
  • channels.signal.groupAllowFrom: список разрешенных отправителей группы.
  • channels.signal.historyLimit: максимальное количество сообщений группы для включения в контекст (0 отключает).
  • channels.signal.dmHistoryLimit: лимит истории личных сообщений в пользовательских оборотах. Переопределения для каждого пользователя: channels.signal.dms["<phone_or_uuid>"].historyLimit.
  • channels.signal.textChunkLimit: размер исходящего фрагмента (символы).
  • channels.signal.chunkMode: length (по умолчанию) или newline для разделения по пустым строкам (границы абзацев) перед разделением по длине.
  • channels.signal.mediaMaxMb: ограничение входящего/исходящего медиа (MB).

Связанные глобальные опции:

  • agents.list[].groupChat.mentionPatterns (Signal не поддерживает нативные упоминания).
  • messages.groupChat.mentionPatterns (глобальный запасной вариант).
  • messages.responsePrefix.