@openclaw/signal). Das Gateway kommuniziert über HTTP mit signal-cli: entweder mit dem nativen Daemon (JSON-RPC + SSE) oder dem Container bbernhard/signal-cli-rest-api (REST + WebSocket). OpenClaw bettet libsignal nicht ein.
Das Nummernmodell (zuerst lesen)
- Das Gateway verbindet sich mit einem Signal-Gerät: dem
signal-cli-Konto. - Wenn der Bot über Ihr persönliches Signal-Konto ausgeführt wird, ignoriert er Ihre eigenen Nachrichten (Schleifenschutz).
- Verwenden Sie für „Ich schreibe dem Bot und er antwortet“ eine separate Bot-Nummer.
Installation
openclaw plugins install clawhub:@openclaw/signal oder npm:@openclaw/signal. plugins install registriert und aktiviert das Plugin; ein separater enable-Schritt ist nicht erforderlich. Allgemeine Installationsregeln finden Sie unter Plugins.
Schnelleinrichtung
1
Nummer auswählen
Verwenden Sie für den Bot eine separate Signal-Nummer (empfohlen).
2
Plugin installieren
3
Geführte Einrichtung ausführen
signal-cli in PATH befindet, und bietet bei Fehlen die Installation an: Unter Linux x86-64 lädt er den offiziellen nativen GraalVM-Build herunter, unter macOS und auf anderen Architekturen installiert er ihn über Homebrew. Anschließend fragt er nach der Bot-Nummer und dem signal-cli-Pfad.Für die nicht interaktive Einrichtung akzeptiert openclaw channels add --channel signal außerdem --signal-number <e164> für die Telefonnummer des Bots sowie --http-host <host> und --http-port <port> für den Endpunkt des Signal-Daemons (Standard: 127.0.0.1:8080).4
5
Überprüfen und koppeln
openclaw pairing approve signal <CODE>.
Unterstützung mehrerer Konten: Verwenden Sie
channels.signal.accounts mit einer Konfiguration pro Konto und optional name. Jedes benannte Konto besitzt seinen eigenen transport; es übernimmt nicht den Transport der obersten Ebene. Der Transport der obersten Ebene gehört nur zum impliziten default-Konto. Das gemeinsame Muster finden Sie unter Kanäle mit mehreren Konten.
Funktionsweise
- Deterministisches Routing: Antworten werden immer an Signal zurückgesendet.
- Direktnachrichten verwenden die Hauptsitzung des Agenten gemeinsam; Gruppen sind isoliert (
agent:<agentId>:signal:group:<groupId>). - Standardmäßig darf Signal durch
/config set|unsetausgelöste Konfigurationsaktualisierungen schreiben (erfordertcommands.config: true). Deaktivieren Sie dies mitchannels.signal.configWrites: false.
Einrichtungspfad A: Vorhandenes Signal-Konto verknüpfen (QR)
- Installieren Sie
signal-cli(JVM- oder nativer Build) oder lassen Sie es vonopenclaw channels addinstallieren. - Verknüpfen Sie ein Bot-Konto:
signal-cli link -n "OpenClaw", und scannen Sie anschließend den QR-Code in Signal. - Konfigurieren Sie Signal und starten Sie das Gateway.
Einrichtungspfad B: Dedizierte Bot-Nummer registrieren (SMS, Linux)
Verwenden Sie diesen Weg für eine dedizierte Bot-Nummer, anstatt ein vorhandenes Signal-App-Konto zu verknüpfen. Der folgende Ablauf wurde unter Ubuntu 24 getestet.- Beschaffen Sie eine Nummer, die SMS empfangen kann (oder eine Sprachverifizierung für Festnetzanschlüsse). Eine dedizierte Bot-Nummer vermeidet Konto- und Sitzungskonflikte.
- Installieren Sie
signal-cliauf dem Gateway-Host:
signal-cli-${VERSION}.tar.gz) verwenden, installieren Sie zuerst eine JRE. Halten Sie signal-cli aktuell; laut Upstream können ältere Releases ausfallen, wenn sich die Signal-Server-APIs ändern.
- Registrieren und verifizieren Sie die Nummer:
- Öffnen Sie
https://signalcaptchas.org/registration/generate.html. - Schließen Sie das Captcha ab und kopieren Sie das Ziel des
signalcaptcha://...-Links aus „Open Signal“. - Führen Sie den Befehl nach Möglichkeit über dieselbe externe IP-Adresse wie die Browsersitzung aus (Captcha-Token laufen schnell ab).
- Registrieren und verifizieren Sie die Nummer sofort:
- Konfigurieren Sie OpenClaw, starten Sie das Gateway neu und überprüfen Sie den Kanal:
- Koppeln Sie den Absender Ihrer Direktnachrichten:
- Senden Sie eine beliebige Nachricht an die Bot-Nummer.
- Genehmigen Sie sie auf dem Server:
openclaw pairing approve signal <PAIRING_CODE>. - Speichern Sie die Bot-Nummer als Kontakt auf Ihrem Telefon, um „Unknown contact“ zu vermeiden.
signal-cli-README:https://github.com/AsamK/signal-cli- Captcha-Ablauf:
https://github.com/AsamK/signal-cli/wiki/Registration-with-captcha - Verknüpfungsablauf:
https://github.com/AsamK/signal-cli/wiki/Linking-other-devices-(Provisioning)
Externer nativer Daemon-Modus
Umsignal-cli selbst zu verwalten (langsame JVM-Kaltstarts, Containerinitialisierung, gemeinsam genutzte CPUs), führen Sie den Daemon separat aus und richten Sie OpenClaw darauf aus:
Wählen Sie für die nicht interaktive Einrichtung bei Bedarf die Endpunktart ausdrücklich aus:
channels.signal.transport.startupTimeoutMs fest.
Container-Modus (bbernhard/signal-cli-rest-api)
Anstattsignal-cli nativ auszuführen, verwenden Sie den Docker-Container bbernhard/signal-cli-rest-api, der signal-cli hinter einer REST- und WebSocket-Schnittstelle kapselt.
- Der Container muss für den Nachrichtenempfang in Echtzeit mit
MODE=json-rpcausgeführt werden. - Registrieren oder verknüpfen Sie Ihr Signal-Konto innerhalb des Containers, bevor Sie OpenClaw verbinden.
docker-compose.yml-Dienst:
transport.kind steuert, welches Protokoll und welchen Prozesslebenszyklus OpenClaw verwendet:
Die Einrichtung und
openclaw doctor --fix können einen vorhandenen Endpunkt einmal prüfen, um dessen konkrete Art zu bestimmen. Laufzeitoperationen erkennen oder wechseln Protokolle nicht automatisch.
Der Container-Modus unterstützt dieselben Signal-Operationen wie der native Modus, sofern der Container entsprechende APIs bereitstellt: Senden, Empfangen, Anhänge, Tippindikatoren, Gelesen-/Angesehen-Bestätigungen, Reaktionen, Gruppen und formatierten Text. OpenClaw übersetzt native Signal-RPC-Aufrufe in die REST-Nutzdaten des Containers, einschließlich group.{base64(internal_id)}-Gruppen-IDs und text_mode: "styled" für formatierten Text.
Betriebshinweise:
- Verwenden Sie
MODE=json-rpczum Empfangen.MODE=normalkann dazu führen, dass/v1/aboutfehlerfrei erscheint, aber/v1/receive/{account}führt kein WebSocket-Upgrade durch, sodass die Empfangsübertragung des Containers bei ihrer Prüfung fehlschlägt. - Legen Sie
kind: "container"für die bbernhard-REST-API undkind: "external-native"für nativessignal-cli-JSON-RPC/SSE fest. - Für das Herunterladen von Anhängen im Container gelten dieselben Medien-Byte-Limits wie im nativen Modus. Übergroße Antworten werden abgelehnt, bevor sie vollständig gepuffert werden, wenn der Server
Content-Lengthsendet, andernfalls während des Streamings.
Zugriffskontrolle (Direktnachrichten + Gruppen)
Direktnachrichten:- Standard:
channels.signal.dmPolicy = "pairing". - Unbekannte Absender erhalten einen Kopplungscode; Nachrichten werden ignoriert, bis sie genehmigt wurden (Codes laufen nach 1 Stunde ab).
- Genehmigen Sie über
openclaw pairing list signalundopenclaw pairing approve signal <CODE>. - Die Kopplung ist der standardmäßige Token-Austausch für Signal-Direktnachrichten. Details: Kopplung
- Absender, die nur über eine UUID verfügen (aus
sourceUuid), werden alsuuid:<id>inchannels.signal.allowFromgespeichert.
channels.signal.groupPolicy = open | allowlist | disabled.channels.signal.groupAllowFromsteuert, welche Gruppen oder Absender Gruppenantworten auslösen können, wennallowlistfestgelegt ist; Einträge können Signal-Gruppen-IDs (unverarbeitet,group:<id>odersignal:group:<id>), Telefonnummern von Absendern,uuid:<id>-Werte oder*sein.channels.signal.groups["<group-id>" | "*"]kann das Gruppenverhalten mitrequireMention,toolsundtoolsBySenderüberschreiben.- Verwenden Sie
channels.signal.accounts.<id>.groupsfür kontospezifische Überschreibungen in Mehrkontokonfigurationen. - Das Zulassen einer Signal-Gruppe über
groupAllowFromdeaktiviert die Erwähnungsbeschränkung nicht automatisch. Ein ausdrücklich konfigurierterchannels.signal.groups["<group-id>"]-Eintrag verarbeitet jede Gruppennachricht, sofernrequireMention=truenicht festgelegt ist. - Bei
requireMention=truewerden native @Erwähnungen von Signal anhand strukturierter Erwähnungsmetadaten mit der Telefonnummer oderaccountUuiddes Bot-Kontos abgeglichen. KonfiguriertementionPatternsbleiben als Klartext-Ausweichlösung erhalten. - Hinweis zur Laufzeit: Wenn
channels.signalvollständig fehlt, greift die Laufzeit bei Gruppenprüfungen aufgroupPolicy="allowlist"zurück (selbst wennchannels.defaults.groupPolicyfestgelegt ist).
Funktionsweise (Verhalten)
- Nativer Modus:
signal-cliwird als Daemon ausgeführt; das Gateway liest Ereignisse über SSE. - Containermodus: Das Gateway sendet über die REST-API und empfängt über WebSocket.
- Eingehende Nachrichten werden in den gemeinsamen Channel-Umschlag normalisiert.
- Antworten werden immer an dieselbe Nummer oder Gruppe zurückgeleitet.
- Antworten auf eingehende Nachrichten enthalten native Signal-Zitatmetadaten, wenn das Backend den Zeitstempel und Autor der eingehenden Nachricht akzeptiert; wenn Zitatmetadaten fehlen oder abgelehnt werden, sendet OpenClaw die Antwort als normale Nachricht.
- Konfigurieren Sie die Verwendung nativer Zitate mit
channels.signal.replyToMode = off | first | all | batchedoder mitchannels.signal.replyToModeByChatType.direct/groupfür Überschreibungen je Chattyp. Werte auf Kontoebene unterchannels.signal.accounts.<id>haben Vorrang.
Medien und Beschränkungen
- Ausgehender Text wird gemäß
channels.signal.textChunkLimitin Abschnitte aufgeteilt (Standard: 4000). - Optionale Aufteilung an Zeilenumbrüchen: Legen Sie
channels.signal.streaming.chunkMode="newline"fest, um vor der längenbasierten Aufteilung an Leerzeilen (Absatzgrenzen) zu teilen. - Anhänge werden unterstützt (Base64-Abruf von
signal-cli). - Sprachnachrichtenanhänge verwenden den Dateinamen
signal-clials MIME-Ausweichwert, wenncontentTypefehlt, damit die Audiotranskription AAC-Sprachmemos weiterhin klassifizieren kann. - Standardmäßige Medienobergrenze:
channels.signal.mediaMaxMb(Standard: 8). - Verwenden Sie
channels.signal.ignoreAttachments, um das Herunterladen von Medien für jeden Transport zu überspringen. - Der Kontext der Gruppenhistorie verwendet
channels.signal.historyLimit(oderchannels.signal.accounts.*.historyLimit) und greift ersatzweise aufmessages.groupChat.historyLimitzurück. Legen Sie zum Deaktivieren0fest (Standard: 50).
Tippanzeigen und Lesebestätigungen
- Tippanzeigen: OpenClaw sendet Tippsignale über
signal-cli sendTypingund aktualisiert sie, während eine Antwort ausgeführt wird. - Lesebestätigungen: Wenn
channels.signal.sendReadReceiptsauf „true“ gesetzt ist, leitet OpenClaw Lesebestätigungen für zulässige Direktnachrichten weiter. signal-clistellt keine Lesebestätigungen für Gruppen bereit.
Statusreaktionen des Lebenszyklus
Legen Siemessages.statusReactions.enabled: true fest, damit Signal bei eingehenden Interaktionen den gemeinsamen Reaktionslebenszyklus für „in Warteschlange“/„denkt nach“/Tool/Compaction/„erledigt“/„Fehler“ anzeigt. Signal verwendet den Zeitstempel der eingehenden Nachricht als Reaktionsziel; Gruppenreaktionen werden mit der Signal-Gruppen-ID und dem ursprünglichen Absender als Zielautor gesendet.
Statusreaktionen erfordern außerdem eine Bestätigungsreaktion und einen passenden messages.ackReactionScope (direct, group-all, group-mentions oder all). Legen Sie channels.signal.reactionLevel: "off" fest, um Signal-Statusreaktionen zu deaktivieren.
Signal stellt nach dem abschließenden Status „erledigt“/„Fehler“ die ursprüngliche Bestätigungsreaktion wieder her.
Reaktionen (Nachrichten-Tool)
Verwenden Siemessage action=react mit channel=signal.
- Ziele: E.164-Nummer oder UUID des Absenders (verwenden Sie
uuid:<id>aus der Kopplungsausgabe; eine alleinstehende UUID funktioniert ebenfalls). messageIdist der Signal-Zeitstempel der Nachricht, auf die Sie reagieren.- Gruppenreaktionen erfordern
targetAuthorodertargetAuthorUuid.
channels.signal.actions.reactions: Reaktionsaktionen aktivieren/deaktivieren (Standard: „true“).channels.signal.reactionLevel:off | ack | minimal | extensive(Standard:minimal).off/ackdeaktiviert Agentenreaktionen (das Nachrichten-Toolreactgibt Fehler zurück).minimal/extensiveaktiviert Agentenreaktionen und legt die Anleitungsstufe fest.
- Kontospezifische Überschreibungen:
channels.signal.accounts.<id>.actions.reactions,channels.signal.accounts.<id>.reactionLevel.
Genehmigungsreaktionen
Signal-Eingabeaufforderungen für Ausführungs- und Plugin-Genehmigungen verwenden die Routingblöckeapprovals.exec und approvals.plugin auf oberster Ebene. Signal besitzt keinen channels.signal.execApprovals-Block.
👍genehmigt einmalig.👎lehnt ab.- Verwenden Sie
/approve <id> allow-always, wenn eine Anfrage eine dauerhafte Genehmigung anbietet.
channels.signal.allowFrom, channels.signal.defaultTo oder den entsprechenden Feldern auf Kontoebene erforderlich. Direkte Ausführungsgenehmigungen im selben Chat können die doppelte lokale /approve-Ausweichlösung auch ohne ausdrücklich festgelegte Genehmigende unterdrücken; bei Gruppengenehmigungen ohne Genehmigende bleibt die lokale Ausweichlösung sichtbar.
Fragereaktionen
Bei einerask_user-Eingabeaufforderung mit einer einzelnen, nicht geheimen Einfachauswahlfrage und einer bis vier Optionen zeigt Signal neben den Optionsbezeichnungen 1️⃣ bis 4️⃣ an. Reagieren Sie auf die zugestellte Eingabeaufforderung mit der entsprechenden Zahl, um sie zu beantworten. OpenClaw überprüft, ob die Reaktion auf die vom Bot verfasste Nachricht zielt, und ordnet die Zahl anschließend über das Gateway der kanonischen Option zu. Veraltete oder doppelte Betätigungen werden ignoriert. Eingabeaufforderungen mit mehreren Fragen, Mehrfachauswahl oder Freitext können weiterhin nur per Textantwort beantwortet werden; die normalen Signal-Zulassungsregeln für Direktnachrichten und Gruppen autorisieren den Absender.
Zustellungsziele (CLI/Cron)
- Direktnachrichten:
signal:+15551234567(oder einfache E.164-Nummer). - UUID-Direktnachrichten:
uuid:<id>(oder alleinstehende UUID). - Gruppen:
signal:group:<groupId>. - Benutzernamen:
username:<name>(sofern von Ihrem Signal-Konto unterstützt).
Aliasse
Konfigurieren Sie Aliasse für stabile Namen wiederkehrender Signal-Ziele. Aliasse sind ausschließlich OpenClaw-seitige Konfiguration; sie erstellen oder bearbeiten keine Signal-Kontakte.openclaw directory peers list --channel signal und openclaw directory groups list --channel signal führen konfigurierte Aliasse auf. Das Signal-Verzeichnis basiert auf der Konfiguration; es fragt Signal-Kontakte nicht live ab und verändert das Signal-Konto nicht.
Fehlerbehebung
Führen Sie zunächst diese Befehlsfolge aus:- Daemon erreichbar, aber keine Antworten: Überprüfen Sie
account,transport.kind, die Transport-URL und den Empfangsmodus. - Direktnachrichten werden ignoriert: Die Kopplungsgenehmigung für den Absender steht noch aus.
- Gruppennachrichten werden ignoriert: Die Gruppenabsender- oder Erwähnungsbeschränkung blockiert die Zustellung.
- Fehler bei der Konfigurationsvalidierung nach Änderungen: Führen Sie
openclaw doctor --fixaus. - Signal fehlt in der Diagnose: Überprüfen Sie
channels.signal.enabled: true.
Sicherheitshinweise
signal-clispeichert Kontoschlüssel lokal (üblicherweise~/.local/share/signal-cli/data/).- Sichern Sie vor einer Servermigration oder einem Neuaufbau den Zustand des Signal-Kontos.
- Behalten Sie
channels.signal.dmPolicy: "pairing"bei, sofern Sie nicht ausdrücklich einen umfassenderen Zugriff auf Direktnachrichten wünschen. - Eine SMS-Verifizierung ist nur für Registrierungs- oder Wiederherstellungsabläufe erforderlich, der Verlust der Kontrolle über die Nummer oder das Konto kann jedoch eine erneute Registrierung erschweren.
Konfigurationsreferenz (Signal)
Vollständige Konfiguration: Konfiguration Provider-Optionen:channels.signal.enabled: Kanalstart aktivieren/deaktivieren.channels.signal.account: E.164 für das Bot-Konto.channels.signal.accountUuid: optionale UUID des Bot-Kontos für native @Erwähnungserkennung und Schleifenschutz.channels.signal.transport: kontoeigener Transport. Für verwaltete native Standardwerte weglassen.channels.signal.transport.kind:managed-native | external-native | container.channels.signal.transport.url: erforderlich fürexternal-nativeundcontainer; optional fürmanaged-native, wenn dessen Verbindungsendpunkt von der Daemon-Bindung abweicht.channels.signal.transport.cliPath: verwalteter nativer Pfad zusignal-cli.channels.signal.transport.configPath: optionales verwaltetes nativessignal-cli --config-Verzeichnis.channels.signal.transport.httpHost,channels.signal.transport.httpPort: verwaltete native Daemon-Bindung (Standard:127.0.0.1:8080).channels.signal.transport.startupTimeoutMs: verwaltete native Startwartezeit in ms (mindestens 1000, höchstens 120000; Standard: 30000).channels.signal.transport.receiveMode: verwaltetes nativeson-start | manual.channels.signal.ignoreAttachments: Downloads eingehender Anhänge für dieses Konto überspringen.channels.signal.transport.ignoreStories: verwalteter nativer Story-Schalter.channels.signal.sendReadReceipts: Lesebestätigungen weiterleiten.channels.signal.dmPolicy:pairing | allowlist | open | disabled(Standard: Kopplung).channels.signal.allowFrom: DM-Zulassungsliste (E.164 oderuuid:<id>).openerfordert"*". Signal hat keine Benutzernamen; verwenden Sie Telefon-/UUID-IDs.channels.signal.aliases: OpenClaw-seitige Aliasse für DM- oder Gruppenzustellungsziele.channels.signal.groupPolicy:open | allowlist | disabled(Standard: Zulassungsliste).channels.signal.groupAllowFrom: Gruppenzulassungsliste; akzeptiert Signal-Gruppen-IDs (unverarbeitet,group:<id>odersignal:group:<id>), E.164-Nummern von Absendern oderuuid:<id>-Werte.channels.signal.groups: gruppenspezifische Überschreibungen, nach Signal-Gruppen-ID (oder"*") verschlüsselt. Unterstützte Felder:requireMention,tools,toolsBySender.channels.signal.accounts.<id>.groups: kontospezifische Version vonchannels.signal.groupsfür Konfigurationen mit mehreren Konten.channels.signal.accounts.<id>.aliases: kontospezifische Aliasse, zusammengeführt mit Aliassen der obersten Ebene.channels.signal.replyToMode: nativer Antwortzitatmodus,off | first | all | batched(Standard:all).channels.signal.replyToModeByChatType.direct,channels.signal.replyToModeByChatType.group: chatspezifische Überschreibungen nativer Antwortzitate.channels.signal.accounts.<id>.replyToMode,channels.signal.accounts.<id>.replyToModeByChatType.direct,channels.signal.accounts.<id>.replyToModeByChatType.group: kontospezifische Überschreibungen von Antwortzitaten.channels.signal.historyLimit: maximale Anzahl der Gruppennachrichten, die als Kontext einbezogen werden (0 deaktiviert).channels.signal.dmHistoryLimit: DM-Verlaufslimit in Benutzerdurchläufen. Benutzerspezifische Überschreibungen:channels.signal.dms["<phone_or_uuid>"].historyLimit.channels.signal.textChunkLimit: ausgehende Blockgröße in Zeichen (Standard: 4000).channels.signal.streaming.chunkMode:length(Standard) odernewline, um vor der längenbasierten Aufteilung an Leerzeilen (Absatzgrenzen) zu teilen.channels.signal.mediaMaxMb: Medienlimit für eingehende/ausgehende Medien in MB (Standard: 8).channels.signal.reactionLevel:off | ack | minimal | extensive(Standard:minimal). Siehe Reaktionen.channels.signal.reactionNotifications:off | own | all | allowlist(Standard:own) – wann der Agent über eingehende Reaktionen anderer benachrichtigt wird.channels.signal.reactionAllowlist: Absender, deren Reaktionen den Agenten benachrichtigen, wennreactionNotifications: "allowlist".channels.signal.streaming.block.enabled,channels.signal.streaming.block.coalesce: kanalübergreifend gemeinsame Streaming-Steuerelemente für den Blockmodus. Siehe Streaming.
agents.entries.*.groupChat.mentionPatterns(Nur-Text-Rückfalloption; native Signal-@Erwähnungen werden aus strukturierten Metadaten erkannt, wenn die Identität des Bot-Kontos konfiguriert ist).messages.groupChat.mentionPatterns(globale Rückfalloption).channels.signal.responsePrefixoder einresponsePrefixauf Kontoebene.
Verwandte Themen
- Kanalübersicht – alle unterstützten Kanäle
- Kopplung – DM-Authentifizierung und Kopplungsablauf
- Gruppen – Gruppenchatverhalten und Erwähnungsbeschränkung
- Kanal-Routing – Sitzungs-Routing für Nachrichten
- Sicherheit – Zugriffsmodell und Absicherung