@openclaw/signal). Gateway komunikuje się z signal-cli przez HTTP: za pośrednictwem natywnego demona (JSON-RPC + SSE) albo kontenera bbernhard/signal-cli-rest-api (REST + WebSocket). OpenClaw nie zawiera wbudowanej biblioteki libsignal.
Model numerów (przeczytaj najpierw)
- Gateway łączy się z urządzeniem Signal: kontem
signal-cli. - Uruchomienie bota na osobistym koncie Signal powoduje, że ignoruje on własne wiadomości (ochrona przed pętlą).
- Aby uzyskać działanie „wysyłam wiadomość do bota, a on odpowiada”, użyj osobnego numeru bota.
Instalacja
openclaw plugins install clawhub:@openclaw/signal lub npm:@openclaw/signal. plugins install rejestruje i włącza wtyczkę; osobny krok enable nie jest potrzebny. Ogólne reguły instalacji opisano w sekcji Wtyczki.
Szybka konfiguracja
1
Wybierz numer
Użyj osobnego numeru Signal dla bota (zalecane).
2
Zainstaluj wtyczkę
3
Uruchom konfigurację z przewodnikiem
signal-cli znajduje się w PATH, a jeśli go brakuje, proponuje instalację: pobiera oficjalną natywną kompilację GraalVM dla systemu Linux x86-64 albo instaluje ją przez Homebrew w systemie macOS i na innych architekturach. Następnie prosi o numer bota i ścieżkę signal-cli.W przypadku konfiguracji nieinteraktywnej openclaw channels add --channel signal akceptuje również --signal-number <e164> jako numer telefonu bota oraz --http-host <host> i --http-port <port> jako punkt końcowy demona Signal (domyślnie 127.0.0.1:8080).4
5
Zweryfikuj i sparuj
openclaw pairing approve signal <CODE>.
Obsługa wielu kont: użyj
channels.signal.accounts z konfiguracją poszczególnych kont i opcjonalnym name. Wspólny wzorzec opisano w sekcji Kanały z wieloma kontami.
Charakterystyka
- Deterministyczne trasowanie: odpowiedzi zawsze wracają do Signal.
- Wiadomości prywatne współdzielą główną sesję agenta; grupy są izolowane (
agent:<agentId>:signal:group:<groupId>). - Domyślnie Signal może zapisywać aktualizacje konfiguracji wywołane przez
/config set|unset(wymagacommands.config: true). Wyłącz tę funkcję za pomocąchannels.signal.configWrites: false.
Ścieżka konfiguracji A: połączenie istniejącego konta Signal (QR)
- Zainstaluj
signal-cli(kompilację JVM lub natywną) albo pozwól, abyopenclaw channels addprzeprowadził instalację. - Połącz konto bota:
signal-cli link -n "OpenClaw", a następnie zeskanuj kod QR w Signal. - Skonfiguruj Signal i uruchom Gateway.
Ścieżka konfiguracji B: rejestracja dedykowanego numeru bota (SMS, Linux)
Użyj tej metody dla dedykowanego numeru bota zamiast łączenia istniejącego konta aplikacji Signal. Poniższy proces przetestowano w systemie Ubuntu 24.- Uzyskaj numer, który może odbierać wiadomości SMS (lub połączenia głosowe z kodem weryfikacyjnym w przypadku telefonów stacjonarnych). Dedykowany numer bota pozwala uniknąć konfliktów kont i sesji.
- Zainstaluj
signal-clina hoście Gateway:
signal-cli-${VERSION}.tar.gz), najpierw zainstaluj środowisko JRE. Regularnie aktualizuj signal-cli; według informacji projektu źródłowego stare wydania mogą przestać działać wskutek zmian interfejsów API serwerów Signal.
- Zarejestruj i zweryfikuj numer:
- Otwórz
https://signalcaptchas.org/registration/generate.html. - Rozwiąż captchę i skopiuj docelowy adres odsyłacza
signalcaptcha://...z opcji „Open Signal”. - Jeśli to możliwe, wykonaj polecenie z tego samego zewnętrznego adresu IP co sesja przeglądarki (tokeny captcha szybko wygasają).
- Natychmiast zarejestruj i zweryfikuj numer:
- Skonfiguruj OpenClaw, uruchom ponownie Gateway i zweryfikuj kanał:
- Sparuj nadawcę wiadomości prywatnych:
- Wyślij dowolną wiadomość na numer bota.
- Zatwierdź na serwerze:
openclaw pairing approve signal <PAIRING_CODE>. - Zapisz numer bota jako kontakt w telefonie, aby uniknąć komunikatu „Unknown contact”.
- README projektu
signal-cli:https://github.com/AsamK/signal-cli - Proces captchy:
https://github.com/AsamK/signal-cli/wiki/Registration-with-captcha - Proces łączenia:
https://github.com/AsamK/signal-cli/wiki/Linking-other-devices-(Provisioning)
Tryb zewnętrznego demona (httpUrl)
Aby samodzielnie zarządzaćsignal-cli (powolne zimne uruchamianie JVM, inicjalizacja kontenera, współdzielone procesory), uruchom demona oddzielnie i skieruj do niego OpenClaw:
channels.signal.startupTimeoutMs.
Tryb kontenera (bbernhard/signal-cli-rest-api)
Zamiast uruchamiaćsignal-cli natywnie, użyj kontenera Docker bbernhard/signal-cli-rest-api, który udostępnia signal-cli za pośrednictwem interfejsu REST + WebSocket.
Wymagania:
- Kontener musi działać z
MODE=json-rpc, aby odbierać wiadomości w czasie rzeczywistym. - Przed połączeniem OpenClaw zarejestruj lub połącz konto Signal wewnątrz kontenera.
docker-compose.yml:
apiMode określa protokół używany przez OpenClaw:
Gdy
apiMode ma wartość "auto", OpenClaw buforuje wykryty tryb przez 30 sekund dla każdego adresu URL demona, aby uniknąć wielokrotnych testów (tryb natywny ma pierwszeństwo, gdy oba transporty działają prawidłowo). Odbiór z kontenera jest wybierany do przesyłania strumieniowego dopiero po pomyślnym przejściu /v1/receive/{account} na WebSocket, co wymaga MODE=json-rpc.
Tryb kontenera obsługuje te same operacje Signal co tryb natywny, jeśli kontener udostępnia odpowiadające im interfejsy API: wysyłanie, odbieranie, załączniki, wskaźniki pisania, potwierdzenia odczytania i wyświetlenia, reakcje, grupy oraz tekst ze stylami. OpenClaw przekształca natywne wywołania RPC Signal w ładunki REST kontenera, w tym identyfikatory grup group.{base64(internal_id)} i text_mode: "styled" dla sformatowanego tekstu.
Uwagi operacyjne:
- W trybie kontenera użyj
autoStart: false; OpenClaw nie powinien uruchamiać natywnego demona, gdy wybranoapiMode: "container". - Do odbierania użyj
MODE=json-rpc.MODE=normalmoże sprawić, że/v1/aboutbędzie wyglądać na sprawne, ale/v1/receive/{account}nie przejdzie na WebSocket, dlatego OpenClaw nie wybierze strumieniowego odbioru z kontenera w trybieauto. - Ustaw
apiMode: "container", gdyhttpUrlwskazuje na interfejs REST API bbernhard,"native", gdy wskazuje na natywny interfejs JSON-RPC/SSEsignal-cli, oraz"auto", gdy wdrożenie może się różnić. - Pobieranie załączników w trybie kontenera podlega tym samym limitom liczby bajtów multimediów co tryb natywny. Zbyt duże odpowiedzi są odrzucane przed ich pełnym zbuforowaniem, gdy serwer wysyła
Content-Length, a w pozostałych przypadkach podczas przesyłania strumieniowego.
Kontrola dostępu (wiadomości prywatne i 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ź za pomocą
openclaw pairing list signaliopenclaw pairing approve signal <CODE>. - Parowanie jest domyślną metodą wymiany tokenów dla wiadomości prywatnych Signal. Szczegóły: Parowanie
- Nadawcy identyfikowani wyłącznie przez UUID (z
sourceUuid) są przechowywani jakouuid:<id>wchannels.signal.allowFrom.
channels.signal.groupPolicy = open | allowlist | disabled.channels.signal.groupAllowFromokreśla, które grupy lub którzy nadawcy mogą wywoływać 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 nadpisywać zachowanie grupy za pomocąrequireMention,toolsitoolsBySender.- W konfiguracjach z wieloma kontami użyj
channels.signal.accounts.<id>.groupsdo nadpisywania ustawień poszczególnych kont. - Dodanie grupy Signal do listy dozwolonych za pośrednictwem
groupAllowFromsamo w sobie nie wyłącza wymogu wzmianki. Jawnie skonfigurowany wpischannels.signal.groups["<group-id>"]przetwarza każdą wiadomość grupową, chyba że ustawionorequireMention=true. - Przy
requireMention=truenatywne wzmianki @ w Signal są dopasowywane na podstawie ustrukturyzowanych metadanych wzmianki do numeru telefonu konta bota lubaccountUuid. SkonfigurowanementionPatternspozostają mechanizmem rezerwowym opartym na zwykłym tekście. - Uwaga dotycząca środowiska uruchomieniowego: jeśli
channels.signaljest całkowicie nieobecne, środowisko uruchomieniowe używa rezerwowogroupPolicy="allowlist"podczas sprawdzania grup (nawet jeśli ustawionochannels.defaults.groupPolicy).
Jak to działa (zachowanie)
- Tryb natywny:
signal-clidziała jako demon; Gateway odczytuje zdarzenia przez SSE. - Tryb kontenera: Gateway wysyła przez REST API i odbiera przez WebSocket.
- Wiadomości przychodzące są normalizowane do wspólnej koperty kanału.
- Odpowiedzi są zawsze kierowane z powrotem do tego samego numeru lub tej samej grupy.
- Odpowiedzi na wiadomości przychodzące zawierają natywne metadane cytowania Signal, gdy backend akceptuje znacznik czasu i autora wiadomości przychodzącej; jeśli brakuje metadanych cytowania lub zostaną one odrzucone, OpenClaw wysyła odpowiedź jako zwykłą wiadomość.
- Natywne cytowanie należy skonfigurować za pomocą
channels.signal.replyToMode = off | first | all | batchedalbochannels.signal.replyToModeByChatType.direct/groupw przypadku nadpisań zależnych od typu czatu. Pierwszeństwo mają wartości na poziomie konta wchannels.signal.accounts.<id>.
Multimedia i limity
- Tekst wychodzący jest dzielony na fragmenty zgodnie z
channels.signal.textChunkLimit(domyślnie 4000). - Opcjonalne dzielenie według nowych wierszy: ustawienie
channels.signal.streaming.chunkMode="newline"powoduje dzielenie przy pustych wierszach (granicach akapitów) przed podziałem według długości. - Załączniki są obsługiwane (dane base64 są pobierane z
signal-cli). - Załączniki z notatkami głosowymi używają nazwy pliku
signal-clijako zastępczego typu MIME, gdy brakujecontentType, dzięki czemu transkrypcja dźwięku nadal może klasyfikować notatki głosowe AAC. - Domyślny limit multimediów:
channels.signal.mediaMaxMb(domyślnie 8). - Aby pominąć pobieranie multimediów, należy użyć
channels.signal.ignoreAttachments. - Kontekst historii grupy używa
channels.signal.historyLimit(lubchannels.signal.accounts.*.historyLimit), a w razie braku wartości —messages.groupChat.historyLimit. Ustawienie0wyłącza tę funkcję (domyślnie 50).
Wskaźniki pisania i potwierdzenia odczytu
- Wskaźniki pisania: OpenClaw wysyła sygnały pisania przez
signal-cli sendTypingi odświeża je podczas generowania odpowiedzi. - Potwierdzenia odczytu: gdy
channels.signal.sendReadReceiptsma wartość true, OpenClaw przekazuje potwierdzenia odczytu dla dozwolonych wiadomości prywatnych. signal-clinie udostępnia potwierdzeń odczytu dla grup.
Reakcje stanu cyklu życia
Ustawieniemessages.statusReactions.enabled: true pozwala Signal wyświetlać wspólny cykl reakcji dla stanów: w kolejce, przetwarzanie, narzędzie, Compaction, ukończenie i błąd — podczas obsługi wiadomości przychodzących. Signal używa znacznika czasu wiadomości przychodzącej jako celu reakcji; reakcje grupowe są wysyłane z identyfikatorem grupy Signal oraz pierwotnym nadawcą jako autorem docelowym.
Reakcje stanu wymagają również reakcji potwierdzającej i zgodnej wartości messages.ackReactionScope (direct, group-all, group-mentions lub all). Ustawienie channels.signal.reactionLevel: "off" wyłącza reakcje stanu Signal.
messages.removeAckAfterReply: true usuwa końcową reakcję stanu po skonfigurowanym czasie utrzymywania. W przeciwnym razie Signal przywraca początkową reakcję potwierdzającą po końcowym stanie ukończenia lub błędu.
Reakcje (narzędzie wiadomości)
Należy użyćmessage action=react z channel=signal.
- Cele: numer nadawcy w formacie E.164 lub UUID (należy użyć
uuid:<id>z danych wyjściowych parowania; sam UUID również działa). messageIdto znacznik czasu Signal wiadomości, na którą dodawana jest reakcja.- Reakcje grupowe wymagają
targetAuthorlubtargetAuthorUuid.
channels.signal.actions.reactions: włącza lub wyłącza działania reakcji (domyślnie true).channels.signal.reactionLevel:off | ack | minimal | extensive(domyślnieminimal).off/ackwyłącza reakcje agenta (narzędzie wiadomościreactzgłasza błędy).minimal/extensivewłącza reakcje agenta i ustawia poziom wskazówek.
- Nadpisania dla poszczególnych kont:
channels.signal.accounts.<id>.actions.reactions,channels.signal.accounts.<id>.reactionLevel.
Reakcje zatwierdzania
Monity zatwierdzania poleceń exec i pluginów w Signal używają nadrzędnych bloków routinguapprovals.exec i approvals.plugin. Signal nie ma bloku channels.signal.execApprovals.
👍zatwierdza jednorazowo.👎odrzuca.- Gdy żądanie oferuje trwałe zatwierdzenie, należy użyć
/approve <id> allow-always.
channels.signal.allowFrom, channels.signal.defaultTo lub odpowiednich pól na poziomie konta. Bezpośrednie monity zatwierdzania exec w tym samym czacie nadal mogą ukrywać zduplikowany lokalny mechanizm zastępczy /approve bez jawnych zatwierdzających; w przypadku zatwierdzeń grupowych bez zatwierdzających lokalny mechanizm zastępczy pozostaje widoczny.
Cele dostarczania (CLI/cron)
- Wiadomości prywatne:
signal:+15551234567(lub sam numer E.164). - Wiadomości prywatne UUID:
uuid:<id>(lub sam UUID). - Grupy:
signal:group:<groupId>. - Nazwy użytkowników:
username:<name>(jeśli są obsługiwane przez dane konto Signal).
Aliasy
Aliasy umożliwiają skonfigurowanie stabilnych nazw dla regularnie używanych celów Signal. Aliasy stanowią wyłącznie konfigurację po stronie OpenClaw; nie tworzą ani nie edytują kontaktów Signal.openclaw directory peers list --channel signal i openclaw directory groups list --channel signal wyświetlają skonfigurowane aliasy. Katalog Signal jest oparty na konfiguracji; nie odpytuje kontaktów Signal na żywo ani nie modyfikuje konta Signal.
Rozwiązywanie problemów
Najpierw należy wykonać następujące polecenia:- Demon jest osiągalny, ale nie ma odpowiedzi: należy sprawdzić ustawienia konta/demona (
httpUrl,account) oraz tryb odbierania. - Wiadomości prywatne są ignorowane: nadawca oczekuje na zatwierdzenie parowania.
- Wiadomości grupowe są ignorowane: reguły nadawcy grupowego lub wymagania dotyczące wzmianek blokują dostarczenie.
- Błędy walidacji konfiguracji po zmianach: należy uruchomić
openclaw doctor --fix. - Brak Signal w diagnostyce: należy sprawdzić
channels.signal.enabled: true.
Uwagi dotyczące bezpieczeństwa
signal-cliprzechowuje klucze konta lokalnie (zwykle w~/.local/share/signal-cli/data/).- Przed migracją lub przebudową serwera należy utworzyć kopię zapasową stanu konta Signal.
- Należy zachować
channels.signal.dmPolicy: "pairing", chyba że szerszy dostęp do wiadomości prywatnych jest wyraźnie pożądany. - Weryfikacja SMS jest potrzebna wyłącznie podczas rejestracji lub odzyskiwania, ale utrata kontroli nad numerem/kontem może utrudnić ponowną rejestrację.
Dokumentacja konfiguracji (Signal)
Pełna konfiguracja: Konfiguracja Opcje dostawcy:channels.signal.enabled: włącza lub wyłącza uruchamianie kanału.channels.signal.apiMode:auto | native | container(domyślnie: automatycznie). Zobacz Tryb kontenera.channels.signal.account: numer konta bota w formacie E.164.channels.signal.accountUuid: opcjonalny UUID konta bota do natywnego wykrywania wzmianek @ i ochrony przed pętlami.channels.signal.cliPath: ścieżka dosignal-cli.channels.signal.configPath: opcjonalny katalogsignal-cli --config.channels.signal.httpUrl: pełny adres URL demona (zastępuje host/port).channels.signal.httpHost,channels.signal.httpPort: adres nasłuchiwania demona (domyślnie127.0.0.1:8080).channels.signal.autoStart: automatycznie uruchamia demona (domyślnie true, jeślihttpUrlnie jest ustawione).channels.signal.startupTimeoutMs: limit czasu oczekiwania na uruchomienie w ms (minimum 1000, maksimum 120000; domyślnie 30000).channels.signal.receiveMode:on-start | manual.channels.signal.ignoreAttachments: pomija pobieranie załączników.channels.signal.ignoreStories: ignoruje relacje pochodzące od demona.channels.signal.sendReadReceipts: przekazuje potwierdzenia odczytu.channels.signal.dmPolicy:pairing | allowlist | open | disabled(domyślnie: parowanie).channels.signal.allowFrom: lista dozwolonych nadawców wiadomości prywatnych (E.164 lubuuid:<id>).openwymaga"*". Signal nie obsługuje nazw użytkowników; należy używać identyfikatorów telefonu/UUID.channels.signal.aliases: aliasy po stronie OpenClaw dla celów dostarczania wiadomości prywatnych lub grupowych.channels.signal.groupPolicy:open | allowlist | disabled(domyślnie: lista dozwolonych).channels.signal.groupAllowFrom: lista dozwolonych dla grup; akceptuje identyfikatory grup Signal (surowe,group:<id>lubsignal:group:<id>), numery nadawców w formacie E.164 albo wartościuuid:<id>.channels.signal.groups: nadpisania dla poszczególnych grup, indeksowane 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.accounts.<id>.aliases: aliasy poszczególnych kont, scalane z aliasami najwyższego poziomu.channels.signal.replyToMode: tryb natywnego cytowania odpowiedzi,off | first | all | batched(domyślnie:all).channels.signal.replyToModeByChatType.direct,channels.signal.replyToModeByChatType.group: nadpisania natywnego cytowania odpowiedzi dla poszczególnych typów czatu.channels.signal.accounts.<id>.replyToMode,channels.signal.accounts.<id>.replyToModeByChatType.direct,channels.signal.accounts.<id>.replyToModeByChatType.group: nadpisania cytowania odpowiedzi dla poszczególnych kont.channels.signal.historyLimit: maksymalna liczba wiadomości grupowych uwzględnianych jako kontekst (0 wyłącza).channels.signal.dmHistoryLimit: limit historii wiadomości prywatnych wyrażony w turach użytkownika. Nadpisania dla poszczególnych użytkowników:channels.signal.dms["<phone_or_uuid>"].historyLimit.channels.signal.textChunkLimit: rozmiar wychodzącego fragmentu w znakach (domyślnie 4000).channels.signal.streaming.chunkMode:length(domyślnie) lubnewline, aby dzielić przy pustych wierszach (granicach akapitów) przed podziałem według długości.channels.signal.mediaMaxMb: limit multimediów przychodzących/wychodzących w MB (domyślnie 8).channels.signal.reactionLevel:off | ack | minimal | extensive(domyślnieminimal). Zobacz Reakcje.channels.signal.reactionNotifications:off | own | all | allowlist(domyślnieown) — określa, kiedy agent jest powiadamiany o przychodzących reakcjach innych osób.channels.signal.reactionAllowlist: nadawcy, których reakcje powiadamiają agenta, gdyreactionNotifications: "allowlist".channels.signal.streaming.block.enabled,channels.signal.streaming.block.coalesce: współdzielone między kanałami ustawienia strumieniowania w trybie blokowym. Zobacz Strumieniowanie.
agents.list[].groupChat.mentionPatterns(zapasowy mechanizm oparty na zwykłym tekście; natywne wzmianki @ w Signal są wykrywane na podstawie ustrukturyzowanych metadanych, gdy skonfigurowano tożsamość konta bota).messages.groupChat.mentionPatterns(globalny mechanizm zapasowy).messages.responsePrefix.
Powiązane
- Przegląd kanałów - wszystkie obsługiwane kanały
- Parowanie - uwierzytelnianie wiadomości prywatnych i proces parowania
- Grupy - zachowanie czatów grupowych i ograniczanie na podstawie wzmianek
- Routing kanałów - routing sesji dla wiadomości
- Bezpieczeństwo - model dostępu i wzmacnianie zabezpieczeń