Mainstream messaging
Signal
Status: integracja z zewnętrznym CLI. Gateway komunikuje się z signal-cli przez HTTP JSON-RPC + SSE.
Wymagania wstępne
- OpenClaw zainstalowany na serwerze (poniższy przepływ dla Linuxa przetestowano na Ubuntu 24).
signal-clidostępne na hoście, na którym działa gateway.- Numer telefonu, który może odebrać jeden SMS weryfikacyjny (dla ścieżki rejestracji przez SMS).
- Dostęp do przeglądarki dla captcha Signal (
signalcaptchas.org) podczas rejestracji.
Szybka konfiguracja (dla początkujących)
- Użyj osobnego numeru Signal dla bota (zalecane).
- Zainstaluj
signal-cli(Java jest wymagana, jeśli używasz kompilacji JVM). - Wybierz jedną ścieżkę konfiguracji:
- Ścieżka A (link QR):
signal-cli link -n "OpenClaw"i zeskanuj w Signal. - Ścieżka B (rejestracja SMS): zarejestruj dedykowany numer z captcha + weryfikacją SMS.
- Ścieżka A (link QR):
- Skonfiguruj OpenClaw i uruchom ponownie gateway.
- Wyślij pierwszą wiadomość prywatną i zatwierdź parowanie (
openclaw pairing approve signal <CODE>).
Minimalna konfiguracja:
{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}
Opis pól:
| Pole | Opis |
|---|---|
account |
Numer telefonu bota w formacie E.164 (+15551234567) |
cliPath |
Ścieżka do signal-cli (signal-cli, jeśli jest w PATH) |
dmPolicy |
Zasady dostępu do wiadomości prywatnych (zalecane pairing) |
allowFrom |
Numery telefonów lub wartości uuid:<id> dopuszczone do wiadomości prywatnych |
Co to jest
- Kanał Signal przez
signal-cli(nie osadzony libsignal). - Deterministyczne trasowanie: odpowiedzi zawsze wracają do Signal.
- Wiadomości prywatne współdzielą główną sesję agenta; grupy są izolowane (
agent:<agentId>:signal:group:<groupId>).
Zapisy konfiguracji
Domyślnie Signal może zapisywać aktualizacje konfiguracji wywołane przez /config set|unset (wymaga commands.config: true).
Wyłącz za pomocą:
{
channels: { signal: { configWrites: false } },
}
Model numeru (ważne)
- Gateway łączy się z urządzeniem Signal (kontem
signal-cli). - Jeśli uruchomisz bota na swoim osobistym koncie Signal, będzie ignorował twoje własne wiadomości (ochrona przed pętlą).
- Dla scenariusza „piszę do bota, a on odpowiada” użyj osobnego numeru bota.
Ścieżka konfiguracji A: połącz istniejące konto Signal (QR)
- Zainstaluj
signal-cli(kompilację JVM lub natywną). - Połącz konto bota:
signal-cli link -n "OpenClaw", a potem zeskanuj QR w Signal.
- Skonfiguruj Signal i uruchom gateway.
Przykład:
{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}
Obsługa wielu kont: użyj channels.signal.accounts z konfiguracją dla każdego konta i opcjonalnym name. Zobacz gateway/configuration, aby poznać wspólny wzorzec.
Ścieżka konfiguracji B: zarejestruj dedykowany numer bota (SMS, Linux)
Użyj tej opcji, gdy chcesz mieć dedykowany numer bota zamiast łączyć istniejące konto aplikacji Signal.
- Uzyskaj numer, który może odbierać SMS (lub weryfikację głosową dla numerów stacjonarnych).
- Użyj dedykowanego numeru bota, aby uniknąć konfliktów konta/sesji.
- Zainstaluj
signal-clina hoście gateway:
VERSION=$(curl -Ls -o /dev/null -w %{url_effective} https://github.com/AsamK/signal-cli/releases/latest | sed -e 's/^.*\/v//')
curl -L -O "https://github.com/AsamK/signal-cli/releases/download/v${VERSION}/signal-cli-${VERSION}-Linux-native.tar.gz"
sudo tar xf "signal-cli-${VERSION}-Linux-native.tar.gz" -C /opt
sudo ln -sf /opt/signal-cli /usr/local/bin/
signal-cli --version
Jeśli używasz kompilacji JVM (signal-cli-${VERSION}.tar.gz), najpierw zainstaluj JRE 25+.
Aktualizuj signal-cli; upstream wskazuje, że stare wydania mogą przestać działać, gdy zmienią się API serwera Signal.
- Zarejestruj i zweryfikuj numer:
signal-cli -a +<BOT_PHONE_NUMBER> register
Jeśli captcha jest wymagana:
- Otwórz
https://signalcaptchas.org/registration/generate.html. - Ukończ captcha, skopiuj cel linku
signalcaptcha://...z „Open Signal”. - Jeśli to możliwe, uruchom z tego samego zewnętrznego IP co sesja przeglądarki.
- Natychmiast uruchom rejestrację ponownie (tokeny captcha szybko wygasają):
signal-cli -a +<BOT_PHONE_NUMBER> register --captcha '<SIGNALCAPTCHA_URL>'
signal-cli -a +<BOT_PHONE_NUMBER> verify <VERIFICATION_CODE>
- Skonfiguruj OpenClaw, uruchom ponownie gateway, zweryfikuj kanał:
# If you run the gateway as a user systemd service:
systemctl --user restart openclaw-gateway.service
# Then verify:
openclaw doctor
openclaw channels status --probe
- Sparuj nadawcę wiadomości prywatnych:
- Wyślij dowolną wiadomość na numer bota.
- Zatwierdź kod na serwerze:
openclaw pairing approve signal <PAIRING_CODE>. - Zapisz numer bota jako kontakt w telefonie, aby uniknąć „Unknown contact”.
Odwołania upstream:
- README
signal-cli:https://github.com/AsamK/signal-cli - Przepływ captcha:
https://github.com/AsamK/signal-cli/wiki/Registration-with-captcha - Przepływ łączenia:
https://github.com/AsamK/signal-cli/wiki/Linking-other-devices-(Provisioning)
Tryb zewnętrznego demona (httpUrl)
Jeśli chcesz samodzielnie zarządzać signal-cli (wolne zimne starty JVM, inicjalizacja kontenera lub współdzielone CPU), uruchom demona osobno i wskaż go w OpenClaw:
{
channels: {
signal: {
httpUrl: "http://127.0.0.1:8080",
autoStart: false,
},
},
}
To pomija automatyczne uruchamianie procesu i oczekiwanie na start w OpenClaw. Przy wolnych startach podczas automatycznego uruchamiania ustaw channels.signal.startupTimeoutMs.
Kontrola dostępu (wiadomości prywatne + grupy)
Wiadomości prywatne:
- Domyślnie:
channels.signal.dmPolicy = "pairing". - Nieznani nadawcy otrzymują kod parowania; wiadomości są ignorowane do czasu zatwierdzenia (kody wygasają po 1 godzinie).
- Zatwierdź przez:
openclaw pairing list signalopenclaw pairing approve signal <CODE>
- Parowanie jest domyślną wymianą tokenów dla wiadomości prywatnych Signal. Szczegóły: Parowanie
- Nadawcy wyłącznie z UUID (z
sourceUuid) są zapisywani jakouuid:<id>wchannels.signal.allowFrom.
Grupy:
channels.signal.groupPolicy = open | allowlist | disabled.channels.signal.groupAllowFromkontroluje, które grupy lub nadawcy mogą wyzwalać odpowiedzi grupowe, gdy ustawionoallowlist; wpisami mogą być identyfikatory grup Signal (surowe,group:<id>lubsignal:group:<id>), numery telefonów nadawców, wartościuuid:<id>albo*.channels.signal.groups["<group-id>" | "*"]może nadpisać zachowanie grupy za pomocąrequireMention,toolsitoolsBySender.- Użyj
channels.signal.accounts.<id>.groupsdla nadpisań per konto w konfiguracjach wielokontowych. - Dodanie grupy Signal do listy dozwolonych przez
groupAllowFromsamo w sobie nie wyłącza bramkowania wzmiankami. Konkretnie skonfigurowany wpischannels.signal.groups["<group-id>"]przetwarza każdą wiadomość grupową, chyba że ustawionorequireMention=true. - Uwaga o środowisku wykonawczym: jeśli
channels.signalcałkowicie brakuje, środowisko wykonawcze wraca dogroupPolicy="allowlist"dla kontroli grup (nawet jeśli ustawionochannels.defaults.groupPolicy).
Jak to działa (zachowanie)
signal-clidziała jako demon; gateway odczytuje zdarzenia przez SSE.- Wiadomości przychodzące są normalizowane do współdzielonej koperty kanału.
- Odpowiedzi zawsze są trasowane z powrotem do tego samego numeru lub grupy.
Multimedia + limity
- Tekst wychodzący jest dzielony do
channels.signal.textChunkLimit(domyślnie 4000). - Opcjonalne dzielenie według nowych linii: ustaw
channels.signal.chunkMode="newline", aby dzielić według pustych linii (granic akapitów) przed dzieleniem według długości. - Załączniki są obsługiwane (base64 pobierane z
signal-cli). - Załączniki notatek głosowych używają nazwy pliku z
signal-clijako zapasowego MIME, gdy brakujecontentType, dzięki czemu transkrypcja audio nadal może klasyfikować notatki głosowe AAC. - Domyślny limit multimediów:
channels.signal.mediaMaxMb(domyślnie 8). - Użyj
channels.signal.ignoreAttachments, aby pominąć pobieranie multimediów. - Kontekst historii grupy używa
channels.signal.historyLimit(lubchannels.signal.accounts.*.historyLimit) i wraca domessages.groupChat.historyLimit. Ustaw0, aby wyłączyć (domyślnie 50).
Wpisywanie + potwierdzenia odczytu
- Wskaźniki pisania: OpenClaw wysyła sygnały pisania przez
signal-cli sendTypingi odświeża je, gdy trwa odpowiedź. - Potwierdzenia odczytu: gdy
channels.signal.sendReadReceiptsma wartość true, OpenClaw przekazuje potwierdzenia odczytu dla dozwolonych wiadomości prywatnych. - Signal-cli nie udostępnia potwierdzeń odczytu dla grup.
Reakcje (narzędzie wiadomości)
- Użyj
message action=reactzchannel=signal. - Cele: nadawca E.164 lub UUID (użyj
uuid:<id>z wyjścia parowania; sam UUID też działa). messageIdto znacznik czasu Signal dla wiadomości, na którą reagujesz.- Reakcje w grupach wymagają
targetAuthorlubtargetAuthorUuid.
Przykłady:
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=✅
Konfiguracja:
channels.signal.actions.reactions: włącza/wyłącza akcje reakcji (domyślnie true).channels.signal.reactionLevel:off | ack | minimal | extensive.off/ackwyłącza reakcje agenta (narzędzie wiadomościreactzwróci błąd).minimal/extensivewłącza reakcje agenta i ustawia poziom wskazówek.
- Nadpisania per konto:
channels.signal.accounts.<id>.actions.reactions,channels.signal.accounts.<id>.reactionLevel.
Cele dostarczania (CLI/cron)
- Wiadomości prywatne:
signal:+15551234567(lub zwykłe E.164). - Wiadomości prywatne UUID:
uuid:<id>(lub sam UUID). - Grupy:
signal:group:<groupId>. - Nazwy użytkowników:
username:<name>(jeśli obsługiwane przez twoje konto Signal).
Rozwiązywanie problemów
Najpierw uruchom tę sekwencję:
openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
openclaw channels status --probe
Następnie w razie potrzeby potwierdź stan parowania wiadomości prywatnych:
openclaw pairing list signal
Typowe awarie:
- Demon osiągalny, ale brak odpowiedzi: zweryfikuj ustawienia konta/demona (
httpUrl,account) i tryb odbioru. - Wiadomości prywatne ignorowane: nadawca oczekuje na zatwierdzenie parowania.
- Wiadomości grupowe ignorowane: bramkowanie nadawcy grupy/wzmianki blokuje dostarczenie.
- Błędy walidacji konfiguracji po edycjach: uruchom
openclaw doctor --fix. - Brak Signal w diagnostyce: potwierdź
channels.signal.enabled: true.
Dodatkowe kontrole:
openclaw pairing list signal
pgrep -af signal-cli
grep -i "signal" "/tmp/openclaw/openclaw-$(date +%Y-%m-%d).log" | tail -20
Przepływ triage: /channels/troubleshooting.
Uwagi dotyczące bezpieczeństwa
signal-cliprzechowuje klucze konta lokalnie (zwykle~/.local/share/signal-cli/data/).- Wykonaj kopię zapasową stanu konta Signal przed migracją serwera lub jego ponowną budową.
- Zachowaj
channels.signal.dmPolicy: "pairing", chyba że wyraźnie chcesz szerszego dostępu do wiadomości prywatnych. - Weryfikacja SMS jest potrzebna tylko w przepływach rejestracji lub odzyskiwania, ale utrata kontroli nad numerem/kontem może skomplikować ponowną rejestrację.
Opis konfiguracji (Signal)
Pełna konfiguracja: Konfiguracja
Opcje dostawcy:
channels.signal.enabled: włącz/wyłącz uruchamianie kanału.channels.signal.account: E.164 dla konta bota.channels.signal.cliPath: ścieżka dosignal-cli.channels.signal.httpUrl: pełny adres URL demona (zastępuje host/port).channels.signal.httpHost,channels.signal.httpPort: adres nasłuchu demona (domyślnie 127.0.0.1:8080).channels.signal.autoStart: automatycznie uruchamiaj demona (domyślnie true, jeślihttpUrlnie jest ustawione).channels.signal.startupTimeoutMs: limit czasu oczekiwania na uruchomienie w ms (maks. 120000).channels.signal.receiveMode:on-start | manual.channels.signal.ignoreAttachments: pomiń pobieranie załączników.channels.signal.ignoreStories: ignoruj relacje z demona.channels.signal.sendReadReceipts: przekazuj potwierdzenia odczytu.channels.signal.dmPolicy:pairing | allowlist | open | disabled(domyślnie: pairing).channels.signal.allowFrom: lista dozwolonych DM (E.164 lubuuid:<id>).openwymaga"*". Signal nie ma nazw użytkowników; używaj identyfikatorów telefonu/UUID.channels.signal.groupPolicy:open | allowlist | disabled(domyślnie: allowlist).channels.signal.groupAllowFrom: lista dozwolonych grup; akceptuje identyfikatory grup Signal (surowe,group:<id>lubsignal:group:<id>), numery nadawców E.164 albo wartościuuid:<id>.channels.signal.groups: zastąpienia dla poszczególnych grup, kluczowane identyfikatorem grupy Signal (lub"*"). Obsługiwane pola:requireMention,tools,toolsBySender.channels.signal.accounts.<id>.groups: wersjachannels.signal.groupsdla poszczególnych kont w konfiguracjach wielokontowych.channels.signal.historyLimit: maksymalna liczba wiadomości grupowych do uwzględnienia jako kontekst (0 wyłącza).channels.signal.dmHistoryLimit: limit historii DM w turach użytkownika. Zastąpienia dla poszczególnych użytkowników:channels.signal.dms["<phone_or_uuid>"].historyLimit.channels.signal.textChunkLimit: rozmiar fragmentu wychodzącego (znaki).channels.signal.chunkMode:length(domyślnie) lubnewline, aby dzielić według pustych wierszy (granic akapitów) przed dzieleniem według długości.channels.signal.mediaMaxMb: limit multimediów przychodzących/wychodzących (MB).
Powiązane opcje globalne:
agents.list[].groupChat.mentionPatterns(Signal nie obsługuje natywnych wzmianek).messages.groupChat.mentionPatterns(globalna rezerwa).messages.responsePrefix.
Powiązane
- Przegląd kanałów — wszystkie obsługiwane kanały
- Parowanie — uwierzytelnianie DM i przepływ parowania
- Grupy — zachowanie czatu grupowego i bramkowanie wzmiankami
- Routing kanałów — routing sesji dla wiadomości
- Bezpieczeństwo — model dostępu i utwardzanie