Signal (signal-cli)
Statut : intégration CLI externe. La gateway communique avecsignal-cli via HTTP JSON-RPC + SSE.
Prérequis
- OpenClaw installé sur votre serveur (le flux Linux ci-dessous a été testé sur Ubuntu 24).
signal-clidisponible sur l’hôte où la gateway s’exécute.- Un numéro de téléphone capable de recevoir un SMS de vérification (pour le parcours d’inscription par SMS).
- Un accès navigateur pour le captcha Signal (
signalcaptchas.org) pendant l’inscription.
Configuration rapide (débutant)
- Utilisez un numéro Signal distinct pour le bot (recommandé).
- Installez
signal-cli(Java est requis si vous utilisez la build JVM). - Choisissez un parcours de configuration :
- Parcours A (liaison QR) :
signal-cli link -n "OpenClaw"puis scannez avec Signal. - Parcours B (inscription SMS) : inscrivez un numéro dédié avec captcha + vérification SMS.
- Parcours A (liaison QR) :
- Configurez OpenClaw et redémarrez la gateway.
- Envoyez un premier message privé et approuvez le jumelage (
openclaw pairing approve signal <CODE>).
| Champ | Description |
|---|---|
account | Numéro de téléphone du bot au format E.164 (+15551234567) |
cliPath | Chemin vers signal-cli (signal-cli s’il est dans le PATH) |
dmPolicy | Politique d’accès aux messages privés (pairing recommandé) |
allowFrom | Numéros de téléphone ou valeurs uuid:<id> autorisés à envoyer des messages privés |
Ce que c’est
- Canal Signal via
signal-cli(pas de libsignal intégrée). - Routage déterministe : les réponses reviennent toujours vers Signal.
- Les messages privés partagent la session principale de l’agent ; les groupes sont isolés (
agent:<agentId>:signal:group:<groupId>).
Écritures de configuration
Par défaut, Signal est autorisé à écrire des mises à jour de configuration déclenchées par/config set|unset (nécessite commands.config: true).
Désactivez avec :
Le modèle de numéro (important)
- La gateway se connecte à un appareil Signal (le compte
signal-cli). - Si vous exécutez le bot sur votre compte Signal personnel, il ignorera vos propres messages (protection contre les boucles).
- Pour « j’envoie un message au bot et il répond », utilisez un numéro de bot distinct.
Parcours de configuration A : lier un compte Signal existant (QR)
- Installez
signal-cli(build JVM ou native). - Liez un compte bot :
signal-cli link -n "OpenClaw"puis scannez le QR dans Signal.
- Configurez Signal et démarrez la gateway.
channels.signal.accounts avec une configuration par compte et un name facultatif. Voir gateway/configuration pour le modèle partagé.
Parcours de configuration B : inscrire un numéro de bot dédié (SMS, Linux)
Utilisez cette option si vous souhaitez un numéro de bot dédié au lieu de lier un compte d’application Signal existant.- Obtenez un numéro capable de recevoir des SMS (ou une vérification vocale pour les lignes fixes).
- Utilisez un numéro de bot dédié pour éviter les conflits de compte/session.
- Installez
signal-clisur l’hôte gateway :
signal-cli-${VERSION}.tar.gz), installez d’abord JRE 25+.
Maintenez signal-cli à jour ; l’amont indique que les anciennes versions peuvent cesser de fonctionner à mesure que les API serveur de Signal évoluent.
- Inscrivez et vérifiez le numéro :
- Ouvrez
https://signalcaptchas.org/registration/generate.html. - Effectuez le captcha, copiez la cible du lien
signalcaptcha://...depuis « Open Signal ». - Exécutez depuis la même IP externe que la session navigateur si possible.
- Relancez immédiatement l’inscription (les jetons captcha expirent rapidement) :
- Configurez OpenClaw, redémarrez la gateway, vérifiez le canal :
- Jumelez l’expéditeur de votre message privé :
- Envoyez n’importe quel message au numéro du bot.
- Approuvez le code sur le serveur :
openclaw pairing approve signal <PAIRING_CODE>. - Enregistrez le numéro du bot comme contact sur votre téléphone pour éviter « Unknown contact ».
signal-cli peut désauthentifier la session principale de l’application Signal pour ce numéro. Préférez un numéro de bot dédié, ou utilisez le mode de liaison QR si vous devez conserver la configuration de votre application téléphonique existante.
Références amont :
- README
signal-cli:https://github.com/AsamK/signal-cli - Flux captcha :
https://github.com/AsamK/signal-cli/wiki/Registration-with-captcha - Flux de liaison :
https://github.com/AsamK/signal-cli/wiki/Linking-other-devices-(Provisioning)
Mode daemon externe (httpUrl)
Si vous souhaitez gérer signal-cli vous-même (démarrages à froid JVM lents, initialisation de conteneur ou CPU partagés), exécutez le daemon séparément et pointez OpenClaw vers lui :
channels.signal.startupTimeoutMs.
Contrôle d’accès (messages privés + groupes)
Messages privés :- Par défaut :
channels.signal.dmPolicy = "pairing". - Les expéditeurs inconnus reçoivent un code de jumelage ; les messages sont ignorés jusqu’à approbation (les codes expirent après 1 heure).
- Approuver via :
openclaw pairing list signalopenclaw pairing approve signal <CODE>
- Le jumelage est l’échange de jetons par défaut pour les messages privés Signal. Détails : Jumelage
- Les expéditeurs UUID uniquement (depuis
sourceUuid) sont stockés commeuuid:<id>danschannels.signal.allowFrom.
channels.signal.groupPolicy = open | allowlist | disabled.channels.signal.groupAllowFromcontrôle qui peut déclencher dans les groupes lorsqueallowlistest défini.channels.signal.groups["<group-id>" | "*"]peut remplacer le comportement de groupe avecrequireMention,toolsettoolsBySender.- Utilisez
channels.signal.accounts.<id>.groupspour des remplacements par compte dans les configurations multi-comptes. - Note d’exécution : si
channels.signalest complètement absent, l’exécution revient àgroupPolicy="allowlist"pour les vérifications de groupe (même sichannels.defaults.groupPolicyest défini).
Fonctionnement (comportement)
signal-clis’exécute comme daemon ; la gateway lit les événements via SSE.- Les messages entrants sont normalisés dans l’enveloppe de canal partagée.
- Les réponses sont toujours routées vers le même numéro ou groupe.
Médias + limites
- Le texte sortant est segmenté selon
channels.signal.textChunkLimit(4000 par défaut). - Segmentation facultative par nouvelles lignes : définissez
channels.signal.chunkMode="newline"pour découper sur les lignes vides (limites de paragraphe) avant la segmentation par longueur. - Pièces jointes prises en charge (base64 récupéré depuis
signal-cli). - Limite média par défaut :
channels.signal.mediaMaxMb(8 par défaut). - Utilisez
channels.signal.ignoreAttachmentspour ignorer le téléchargement des médias. - Le contexte d’historique de groupe utilise
channels.signal.historyLimit(ouchannels.signal.accounts.*.historyLimit), avec repli surmessages.groupChat.historyLimit. Définissez0pour désactiver (50 par défaut).
Saisie + accusés de lecture
- Indicateurs de saisie : OpenClaw envoie des signaux de saisie via
signal-cli sendTypinget les actualise pendant qu’une réponse est en cours. - Accusés de lecture : lorsque
channels.signal.sendReadReceiptsest vrai, OpenClaw transmet les accusés de lecture pour les messages privés autorisés. - Signal-cli n’expose pas les accusés de lecture pour les groupes.
Réactions (outil de message)
- Utilisez
message action=reactavecchannel=signal. - Cibles : E.164 de l’expéditeur ou UUID (utilisez
uuid:<id>depuis la sortie du jumelage ; un UUID nu fonctionne aussi). messageIdest l’horodatage Signal du message auquel vous réagissez.- Les réactions de groupe nécessitent
targetAuthoroutargetAuthorUuid.
channels.signal.actions.reactions: activer/désactiver les actions de réaction (true par défaut).channels.signal.reactionLevel:off | ack | minimal | extensive.off/ackdésactive les réactions de l’agent (l’outil de messagereactrenverra une erreur).minimal/extensiveactive les réactions de l’agent et définit le niveau de guidage.
- Remplacements par compte :
channels.signal.accounts.<id>.actions.reactions,channels.signal.accounts.<id>.reactionLevel.
Cibles de livraison (CLI/cron)
- Messages privés :
signal:+15551234567(ou E.164 brut). - Messages privés UUID :
uuid:<id>(ou UUID nu). - Groupes :
signal:group:<groupId>. - Noms d’utilisateur :
username:<name>(si pris en charge par votre compte Signal).
Dépannage
Exécutez d’abord cette séquence :- Daemon accessible mais aucune réponse : vérifiez les paramètres de compte/daemon (
httpUrl,account) et le mode de réception. - Messages privés ignorés : l’expéditeur est en attente d’approbation de jumelage.
- Messages de groupe ignorés : le filtrage par expéditeur/mention du groupe bloque la remise.
- Erreurs de validation de configuration après modification : exécutez
openclaw doctor --fix. - Signal absent des diagnostics : confirmez
channels.signal.enabled: true.
Notes de sécurité
signal-clistocke les clés de compte localement (généralement~/.local/share/signal-cli/data/).- Sauvegardez l’état du compte Signal avant une migration ou une reconstruction du serveur.
- Conservez
channels.signal.dmPolicy: "pairing"sauf si vous souhaitez explicitement un accès plus large aux messages privés. - La vérification par SMS n’est nécessaire que pour l’inscription ou les flux de récupération, mais perdre le contrôle du numéro/compte peut compliquer la réinscription.
Référence de configuration (Signal)
Configuration complète : Configuration Options du fournisseur :channels.signal.enabled: activer/désactiver le démarrage du canal.channels.signal.account: E.164 pour le compte bot.channels.signal.cliPath: chemin verssignal-cli.channels.signal.httpUrl: URL complète du daemon (remplace l’hôte/le port).channels.signal.httpHost,channels.signal.httpPort: liaison du daemon (par défaut127.0.0.1:8080).channels.signal.autoStart: lancer automatiquement le daemon (true par défaut sihttpUrln’est pas défini).channels.signal.startupTimeoutMs: délai d’attente de démarrage en ms (plafond 120000).channels.signal.receiveMode:on-start | manual.channels.signal.ignoreAttachments: ignorer les téléchargements de pièces jointes.channels.signal.ignoreStories: ignorer les stories du daemon.channels.signal.sendReadReceipts: transmettre les accusés de lecture.channels.signal.dmPolicy:pairing | allowlist | open | disabled(par défaut : pairing).channels.signal.allowFrom: liste d’autorisation pour les messages privés (E.164 ouuuid:<id>).opennécessite"*". Signal n’a pas de noms d’utilisateur ; utilisez les identifiants téléphone/UUID.channels.signal.groupPolicy:open | allowlist | disabled(par défaut : allowlist).channels.signal.groupAllowFrom: liste d’autorisation des expéditeurs de groupe.channels.signal.groups: remplacements par groupe indexés par ID de groupe Signal (ou"*"). Champs pris en charge :requireMention,tools,toolsBySender.channels.signal.accounts.<id>.groups: version par compte dechannels.signal.groupspour les configurations multi-comptes.channels.signal.historyLimit: nombre maximal de messages de groupe à inclure comme contexte (0 désactive).channels.signal.dmHistoryLimit: limite d’historique des messages privés en tours utilisateur. Remplacements par utilisateur :channels.signal.dms["<phone_or_uuid>"].historyLimit.channels.signal.textChunkLimit: taille des segments sortants (caractères).channels.signal.chunkMode:length(par défaut) ounewlinepour découper sur des lignes vides (limites de paragraphe) avant la segmentation par longueur.channels.signal.mediaMaxMb: limite de médias entrants/sortants (Mo).
agents.list[].groupChat.mentionPatterns(Signal ne prend pas en charge les mentions natives).messages.groupChat.mentionPatterns(repli global).messages.responsePrefix.
Lié
- Vue d’ensemble des canaux — tous les canaux pris en charge
- Jumelage — authentification en message privé et flux de jumelage
- Groupes — comportement des discussions de groupe et filtrage par mention
- Routage des canaux — routage de session pour les messages
- Sécurité — modèle d’accès et durcissement