Signal (signal-cli)¶
Statut : intégration CLI externe. La Gateway communique avec signal-cli via HTTP JSON-RPC + SSE.
Prerequisites¶
- OpenClaw installed on your server (Linux flow below tested on Ubuntu 24).
signal-cliavailable on the host where the gateway runs.- A phone number that can receive one verification SMS (for SMS registration path).
- Browser access for Signal captcha (
signalcaptchas.org) during registration.
Configuration (chemin rapide)¶
- Utilisez un numero Signal distinct pour le bot (recommande).
- Installez
signal-cli(Java requis). - Choose one setup path:
-
signal-cli link -n "OpenClaw"- Path B (SMS register): register a dedicated number with captcha + SMS verification. - Configurez OpenClaw et demarrez la Gateway.
- Send a first DM and approve pairing (
openclaw pairing approve signal <CODE>).
Configuration minimale :
{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}
Field reference:
| Field | Description |
|---|---|
account |
Bot phone number in E.164 format (+15551234567) |
cliPath |
Demarrage rapide (debutant) |
dmPolicy |
DM access policy (pairing recommended) |
allowFrom |
Phone numbers or uuid:<id> values allowed to DM |
Ce que c’est¶
- Canal Signal via
signal-cli(pas de libsignal embarquee). - Routage deterministe : les reponses reviennent toujours sur Signal.
- Les Messages prives partagent la session principale de l’agent ; les groupes sont isoles (
agent:<agentId>:signal:group:<groupId>).
Ecritures de configuration¶
Par defaut, Signal est autorise a ecrire des mises a jour de configuration declenchees par /config set|unset (necessite commands.config: true).
Desactiver avec :
{
channels: { signal: { configWrites: false } },
}
Le modele de numeros (important)¶
- La Gateway se connecte a un appareil Signal (le compte
signal-cli). - Si vous executez le bot sur votre compte Signal personnel, il ignorera vos propres messages (protection contre les boucles).
- Pour « je texte le bot et il repond », utilisez un numero de bot distinct.
Setup path A: link existing Signal account (QR)¶
- Installez
signal-cli(Java requis). - Liez un compte bot :
-
signal-cli link -n "OpenClaw"puis scannez le QR dans Signal. - Configurez Signal et demarrez la Gateway.
Exemple :
{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}
Prise en charge multi-comptes : utilisez channels.signal.accounts avec une configuration par compte et name en option. Voir gateway/configuration pour le modele partage.
Setup path B: register dedicated bot number (SMS, Linux)¶
Use this when you want a dedicated bot number instead of linking an existing Signal app account.
- Get a number that can receive SMS (or voice verification for landlines). - Use a dedicated bot number to avoid account/session conflicts.
- Install
signal-clion the gateway host:
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
If you use the JVM build (signal-cli-${VERSION}.tar.gz), install JRE 25+ first.
Keep signal-cli updated; upstream notes that old releases can break as Signal server APIs change.
- Register and verify the number:
signal-cli -a +<BOT_PHONE_NUMBER> register
If captcha is required:
- Open
https://signalcaptchas.org/registration/generate.html. - Complete captcha, copy the
signalcaptcha://...link target from "Open Signal". - Run from the same external IP as the browser session when possible.
- Run registration again immediately (captcha tokens expire quickly):
signal-cli -a +<BOT_PHONE_NUMBER> register --captcha '<SIGNALCAPTCHA_URL>'
signal-cli -a +<BOT_PHONE_NUMBER> verify <VERIFICATION_CODE>
- Liez l’appareil du bot et demarrez le daemon :
# If you run the gateway as a user systemd service:
systemctl --user restart openclaw-gateway
# Then verify:
openclaw doctor
openclaw channels status --probe
- Pair your DM sender:
- Send any message to the bot number.
- Approve code on the server:
openclaw pairing approve signal <PAIRING_CODE>. - Save the bot number as a contact on your phone to avoid "Unknown contact".
Important: registering a phone number account with signal-cli can de-authenticate the main Signal app session for that number. Prefer a dedicated bot number, or use QR link mode if you need to keep your existing phone app setup.
Upstream references:
signal-cliREADME:https://github.com/AsamK/signal-cli- Captcha flow:
https://github.com/AsamK/signal-cli/wiki/Registration-with-captcha - Linking flow:
https://github.com/AsamK/signal-cli/wiki/Linking-other-devices-(Provisioning)
Mode daemon externe (httpUrl)¶
Si vous souhaitez gerer signal-cli vous-meme (demarrages JVM a froid lents, initialisation de conteneur ou CPU partages), lancez le daemon separement et pointez OpenClaw dessus :
{
channels: {
signal: {
httpUrl: "http://127.0.0.1:8080",
autoStart: false,
},
},
}
Cela ignore l’auto-lancement et l’attente de demarrage dans OpenClaw. Pour des demarrages lents lors de l’auto-lancement, definissez channels.signal.startupTimeoutMs.
Controle d’acces (Messages prives + groupes)¶
DMs:
- Par defaut :
channels.signal.dmPolicy = "pairing". - Les expediteurs inconnus recoivent un code d’appairage ; les messages sont ignores jusqu’a approbation (les codes expirent apres 1 heure).
- Approuver via :
openclaw pairing list signalopenclaw pairing approve signal <CODE>- L’appairage est l’echange de jeton par defaut pour les Messages prives Signal. Details : Appairage
- Les expediteurs uniquement UUID (depuis
sourceUuid) sont stockes commeuuid:<id>danschannels.signal.allowFrom.
Groupes :
channels.signal.groupPolicy = open | allowlist | disabled.channels.signal.groupAllowFromcontrole qui peut declencher dans les groupes lorsqueallowlistest defini.
Comment ça marche (comportement)¶
signal-clis’execute comme un daemon ; la Gateway lit les evenements via SSE.- Les messages entrants sont normalises dans l’enveloppe de canal partagee.
- Les reponses sont toujours renvoyees vers le meme numero ou groupe.
Medias + limites¶
- Le texte sortant est segmente en blocs de
channels.signal.textChunkLimit(par defaut 4000). - Segmentation optionnelle par sauts de ligne : definir
channels.signal.chunkMode="newline"pour decouper sur les lignes vides (frontieres de paragraphes) avant la segmentation par longueur. - Pieces jointes prises en charge (base64 recupere depuis
signal-cli). - Limite media par defaut :
channels.signal.mediaMaxMb(par defaut 8). - Utilisez
channels.signal.ignoreAttachmentspour ignorer le telechargement des medias. - Le contexte d’historique de groupe utilise
channels.signal.historyLimit(ouchannels.signal.accounts.*.historyLimit), avec repli versmessages.groupChat.historyLimit. Definir0pour desactiver (par defaut 50).
Indicateurs de saisie + accusés de lecture¶
- Indicateurs de saisie : OpenClaw envoie des signaux de saisie via
signal-cli sendTypinget les rafraichit pendant l’execution d’une reponse. - Accuses de lecture : lorsque
channels.signal.sendReadReceiptsest vrai, OpenClaw transmet les accuses de lecture pour les Messages prives autorises. - Signal-cli n’expose pas les accuses de lecture pour les groupes.
Reactions (outil message)¶
- Utilisez
message action=reactavecchannel=signal. - Cibles : expediteur E.164 ou UUID (utilisez
uuid:<id>depuis la sortie d’appairage ; l’UUID brut fonctionne aussi). messageIdest l’horodatage Signal du message auquel vous reagissez.- Les reactions en groupe necessitent
targetAuthoroutargetAuthorUuid.
Exemples :
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=✅
Configuration :
channels.signal.actions.reactions : activer/desactiver les actions de reaction (par defaut true).channels.signal.reactionLevel :off | ack | minimal | extensive.off/ackdesactive les reactions de l’agent (l’outil messagereactrenverra une erreur).minimal/extensiveactive les reactions de l’agent et definit le niveau de guidage.- Surcharges par compte :
channels.signal.accounts.<id>.actions.reactions,channels.signal.accounts.<id>.reactionLevel.
Cibles de livraison (CLI/cron)¶
- Messages prives :
signal:+15551234567(ou E.164 simple). - Messages prives UUIDÂ :
uuid:<id>(ou UUID brut). - Groupes :
signal:group:<groupId>. - Noms d’utilisateur :
username:<name>(si pris en charge par votre compte Signal).
Problemes courants¶
Exécutez d'abord cette échelle :
openclaw models auth paste-token --provider anthropic
openclaw models status
Ensuite, confirmez l'état d'appairage du DM si nécessaire:
openclaw pairing list signal
Échecs communs :
- Le démon est joignable mais pas de réponses : vérifiez les paramètres du compte/démon (
httpUrl,account) et le mode réception. - DMs ignorés: l'expéditeur est en attente d'approbation du jumelage.
- Les messages de groupe ont été ignorés : envoi de blocs de barrière d'expéditeur/mention de groupe.
- Config validation errors after edits: run
openclaw doctor --fix. - Signal missing from diagnostics: confirm
channels.signal.enabled: true.
Extra checks:
openclaw pairing list signal
pgrep -af signal-cli
grep -i "signal" "/tmp/openclaw/openclaw-$(date +%Y-%m-%d).log" | tail -20
channels/signal.md
Security notes¶
signal-clistores account keys locally (typically~/.local/share/signal-cli/data/).- Back up Signal account state before server migration or rebuild.
- openclaw models auth paste-token --provider anthropic openclaw models status
- SMS verification is only needed for registration or recovery flows, but losing control of the number/account can complicate re-registration.
Reference de configuration (Signal)¶
Configuration complete : Configuration
Options du fournisseur :
channels.signal.enabled : activer/desactiver le demarrage du canal.channels.signal.account : E.164 pour le compte bot.channels.signal.cliPath : chemin verssignal-cli.channels.signal.httpUrl : URL complete du daemon (remplace hote/port).channels.signal.httpHost,channels.signal.httpPort : liaison du daemon (par defaut 127.0.0.1:8080).channels.signal.autoStart : auto-lancement du daemon (par defaut true sihttpUrln’est pas defini).channels.signal.startupTimeoutMs : delai d’attente au demarrage en ms (plafond 120000).channels.signal.receiveMode :on-start | manual.channels.signal.ignoreAttachments : ignorer le telechargement des pieces jointes.channels.signal.ignoreStories : ignorer les stories du daemon.channels.signal.sendReadReceipts : transmettre les accuses de lecture.channels.signal.dmPolicy :pairing | allowlist | open | disabled(par defaut : appairage).channels.signal.allowFrom : liste blanche des Messages prives (E.164 ouuuid:<id>).opennecessite"*". Signal n’a pas de noms d’utilisateur ; utilisez des identifiants telephone/UUID.channels.signal.groupPolicy :open | allowlist | disabled(par defaut : liste blanche).channels.signal.groupAllowFrom : liste blanche des expediteurs de groupe.channels.signal.historyLimit : nombre maximal de messages de groupe a inclure comme contexte (0 desactive).channels.signal.dmHistoryLimit : limite d’historique des Messages prives en tours utilisateur. Surcharges par utilisateur :channels.signal.dms["<phone_or_uuid>"].historyLimit.channels.signal.textChunkLimit : taille de segmentation sortante (caracteres).channels.signal.chunkMode :length(par defaut) ounewlinepour decouper sur les lignes vides (frontieres de paragraphes) avant la segmentation par longueur.channels.signal.mediaMaxMb : limite media entrante/sortante (Mo).
Options globales associees :
agents.list[].groupChat.mentionPatterns(Signal ne prend pas en charge les mentions natives).messages.groupChat.mentionPatterns(repli global).messages.responsePrefix.