Mainstream messaging

Signal

Stato: integrazione CLI esterna. Il Gateway comunica con signal-cli tramite HTTP JSON-RPC + SSE.

Prerequisiti

  • OpenClaw installato sul tuo server (il flusso Linux seguente è stato testato su Ubuntu 24).
  • signal-cli disponibile sull'host in cui viene eseguito il gateway.
  • Un numero di telefono che possa ricevere un SMS di verifica (per il percorso di registrazione via SMS).
  • Accesso al browser per il captcha di Signal (signalcaptchas.org) durante la registrazione.

Configurazione rapida (principianti)

  1. Usa un numero Signal separato per il bot (consigliato).
  2. Installa signal-cli (Java è richiesto se usi la build JVM).
  3. Scegli un percorso di configurazione:
    • Percorso A (collegamento QR): signal-cli link -n "OpenClaw" e scansiona con Signal.
    • Percorso B (registrazione SMS): registra un numero dedicato con captcha + verifica SMS.
  4. Configura OpenClaw e riavvia il gateway.
  5. Invia un primo DM e approva l'associazione (openclaw pairing approve signal <CODE>).

Configurazione minima:

{
  channels: {
    signal: {
      enabled: true,
      account: "+15551234567",
      cliPath: "signal-cli",
      dmPolicy: "pairing",
      allowFrom: ["+15557654321"],
    },
  },
}

Riferimento dei campi:

Campo Descrizione
account Numero di telefono del bot in formato E.164 (+15551234567)
cliPath Percorso di signal-cli (signal-cli se è in PATH)
dmPolicy Criterio di accesso ai DM (pairing consigliato)
allowFrom Numeri di telefono o valori uuid:<id> autorizzati a inviare DM

Che cos'è

  • Canale Signal tramite signal-cli (non libsignal integrato).
  • Instradamento deterministico: le risposte tornano sempre a Signal.
  • I DM condividono la sessione principale dell'agente; i gruppi sono isolati (agent:<agentId>:signal:group:<groupId>).

Scritture della configurazione

Per impostazione predefinita, Signal è autorizzato a scrivere aggiornamenti di configurazione attivati da /config set|unset (richiede commands.config: true).

Disattiva con:

{
  channels: { signal: { configWrites: false } },
}

Il modello del numero (importante)

  • Il gateway si connette a un dispositivo Signal (l'account signal-cli).
  • Se esegui il bot sul tuo account Signal personale, ignorerà i tuoi messaggi (protezione dai loop).
  • Per "mando un messaggio al bot e lui risponde", usa un numero bot separato.

Percorso di configurazione A: collegare un account Signal esistente (QR)

  1. Installa signal-cli (build JVM o nativa).
  2. Collega un account bot:
    • signal-cli link -n "OpenClaw" quindi scansiona il QR in Signal.
  3. Configura Signal e avvia il gateway.

Esempio:

{
  channels: {
    signal: {
      enabled: true,
      account: "+15551234567",
      cliPath: "signal-cli",
      dmPolicy: "pairing",
      allowFrom: ["+15557654321"],
    },
  },
}

Supporto multi-account: usa channels.signal.accounts con configurazione per account e name opzionale. Consulta gateway/configuration per il modello condiviso.

Percorso di configurazione B: registrare un numero bot dedicato (SMS, Linux)

Usalo quando vuoi un numero bot dedicato invece di collegare un account app Signal esistente.

  1. Procurati un numero che possa ricevere SMS (o verifica vocale per linee fisse).
    • Usa un numero bot dedicato per evitare conflitti di account/sessione.
  2. Installa signal-cli sull'host del 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

Se usi la build JVM (signal-cli-${VERSION}.tar.gz), installa prima JRE 25+. Mantieni signal-cli aggiornato; upstream segnala che le versioni vecchie possono smettere di funzionare quando cambiano le API server di Signal.

  1. Registra e verifica il numero:
signal-cli -a +&lt;BOT_PHONE_NUMBER&gt; register

Se è richiesto il captcha:

  1. Apri https://signalcaptchas.org/registration/generate.html.
  2. Completa il captcha, copia la destinazione del link signalcaptcha://... da "Open Signal".
  3. Esegui dalla stessa IP esterna della sessione browser quando possibile.
  4. Esegui subito di nuovo la registrazione (i token captcha scadono rapidamente):
signal-cli -a +&lt;BOT_PHONE_NUMBER&gt; register --captcha '&lt;SIGNALCAPTCHA_URL&gt;'
signal-cli -a +&lt;BOT_PHONE_NUMBER&gt; verify &lt;VERIFICATION_CODE&gt;
  1. Configura OpenClaw, riavvia il gateway, verifica il canale:
# If you run the gateway as a user systemd service:
systemctl --user restart openclaw-gateway.service

# Then verify:
openclaw doctor
openclaw channels status --probe
  1. Associa il mittente DM:
    • Invia qualsiasi messaggio al numero del bot.
    • Approva il codice sul server: openclaw pairing approve signal &lt;PAIRING_CODE&gt;.
    • Salva il numero del bot come contatto sul telefono per evitare "Contatto sconosciuto".

Riferimenti upstream:

  • README di signal-cli: https://github.com/AsamK/signal-cli
  • Flusso captcha: https://github.com/AsamK/signal-cli/wiki/Registration-with-captcha
  • Flusso di collegamento: https://github.com/AsamK/signal-cli/wiki/Linking-other-devices-(Provisioning)

Modalità daemon esterna (httpUrl)

Se vuoi gestire signal-cli autonomamente (avvii a freddo JVM lenti, init del container o CPU condivise), esegui il daemon separatamente e indirizza OpenClaw verso di esso:

{
  channels: {
    signal: {
      httpUrl: "http://127.0.0.1:8080",
      autoStart: false,
    },
  },
}

Questo evita l'avvio automatico e l'attesa di startup all'interno di OpenClaw. Per avvii lenti con avvio automatico, imposta channels.signal.startupTimeoutMs.

Controllo degli accessi (DM + gruppi)

DM:

  • Predefinito: channels.signal.dmPolicy = "pairing".
  • I mittenti sconosciuti ricevono un codice di associazione; i messaggi vengono ignorati finché non sono approvati (i codici scadono dopo 1 ora).
  • Approva tramite:
    • openclaw pairing list signal
    • openclaw pairing approve signal &lt;CODE&gt;
  • L'associazione è lo scambio di token predefinito per i DM Signal. Dettagli: Associazione
  • I mittenti solo UUID (da sourceUuid) vengono memorizzati come uuid:<id> in channels.signal.allowFrom.

Gruppi:

  • channels.signal.groupPolicy = open | allowlist | disabled.
  • channels.signal.groupAllowFrom controlla quali gruppi o mittenti possono attivare risposte di gruppo quando allowlist è impostato; le voci possono essere ID gruppo Signal (grezzi, group:<id> o signal:group:<id>), numeri di telefono dei mittenti, valori uuid:<id> o *.
  • channels.signal.groups["<group-id>" | "*"] può sovrascrivere il comportamento dei gruppi con requireMention, tools e toolsBySender.
  • Usa channels.signal.accounts.<id>.groups per sovrascritture per account nelle configurazioni multi-account.
  • L'inserimento di un gruppo Signal in allowlist tramite groupAllowFrom non disattiva di per sé il gating delle menzioni. Una voce channels.signal.groups["<group-id>"] configurata in modo specifico elabora ogni messaggio del gruppo a meno che requireMention=true sia impostato.
  • Nota runtime: se channels.signal manca del tutto, il runtime ripiega su groupPolicy="allowlist" per i controlli dei gruppi (anche se channels.defaults.groupPolicy è impostato).

Come funziona (comportamento)

  • signal-cli viene eseguito come daemon; il gateway legge gli eventi tramite SSE.
  • I messaggi in ingresso vengono normalizzati nella busta canale condivisa.
  • Le risposte vengono sempre instradate allo stesso numero o gruppo.

Media + limiti

  • Il testo in uscita viene suddiviso in blocchi fino a channels.signal.textChunkLimit (predefinito 4000).
  • Suddivisione opzionale sulle nuove righe: imposta channels.signal.chunkMode="newline" per suddividere sulle righe vuote (confini di paragrafo) prima della suddivisione per lunghezza.
  • Allegati supportati (base64 recuperato da signal-cli).
  • Gli allegati di note vocali usano il nome file signal-cli come fallback MIME quando contentType manca, così la trascrizione audio può comunque classificare i memo vocali AAC.
  • Limite media predefinito: channels.signal.mediaMaxMb (predefinito 8).
  • Usa channels.signal.ignoreAttachments per saltare il download dei media.
  • Il contesto della cronologia dei gruppi usa channels.signal.historyLimit (o channels.signal.accounts.*.historyLimit), con fallback a messages.groupChat.historyLimit. Imposta 0 per disattivare (predefinito 50).

Digitazione + conferme di lettura

  • Indicatori di digitazione: OpenClaw invia segnali di digitazione tramite signal-cli sendTyping e li aggiorna mentre una risposta è in esecuzione.
  • Conferme di lettura: quando channels.signal.sendReadReceipts è true, OpenClaw inoltra le conferme di lettura per i DM consentiti.
  • Signal-cli non espone conferme di lettura per i gruppi.

Reazioni (strumento messaggio)

  • Usa message action=react con channel=signal.
  • Destinazioni: E.164 o UUID del mittente (usa uuid:<id> dall'output dell'associazione; funziona anche l'UUID semplice).
  • messageId è il timestamp Signal del messaggio a cui stai reagendo.
  • Le reazioni nei gruppi richiedono targetAuthor o targetAuthorUuid.

Esempi:

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=✅

Configurazione:

  • channels.signal.actions.reactions: abilita/disabilita le azioni di reazione (predefinito true).
  • channels.signal.reactionLevel: off | ack | minimal | extensive.
    • off/ack disattiva le reazioni dell'agente (lo strumento messaggio react genererà errore).
    • minimal/extensive abilita le reazioni dell'agente e imposta il livello di guida.
  • Sovrascritture per account: channels.signal.accounts.<id>.actions.reactions, channels.signal.accounts.<id>.reactionLevel.

Destinazioni di consegna (CLI/cron)

  • DM: signal:+15551234567 (o E.164 semplice).
  • DM UUID: uuid:<id> (o UUID semplice).
  • Gruppi: signal:group:<groupId>.
  • Nomi utente: username:<name> (se supportato dal tuo account Signal).

Risoluzione dei problemi

Esegui prima questa sequenza:

openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
openclaw channels status --probe

Poi conferma lo stato di associazione DM se necessario:

openclaw pairing list signal

Errori comuni:

  • Daemon raggiungibile ma nessuna risposta: verifica le impostazioni account/daemon (httpUrl, account) e la modalità di ricezione.
  • DM ignorati: il mittente è in attesa dell'approvazione dell'associazione.
  • Messaggi di gruppo ignorati: il gating del mittente gruppo/menzione blocca la consegna.
  • Errori di validazione della configurazione dopo modifiche: esegui openclaw doctor --fix.
  • Signal assente dalla diagnostica: conferma channels.signal.enabled: true.

Controlli aggiuntivi:

openclaw pairing list signal
pgrep -af signal-cli
grep -i "signal" "/tmp/openclaw/openclaw-$(date +%Y-%m-%d).log" | tail -20

Per il flusso di triage: /channels/troubleshooting.

Note di sicurezza

  • signal-cli memorizza le chiavi dell'account localmente (in genere ~/.local/share/signal-cli/data/).
  • Esegui il backup dello stato dell'account Signal prima della migrazione o ricostruzione del server.
  • Mantieni channels.signal.dmPolicy: "pairing" a meno che tu non voglia esplicitamente un accesso DM più ampio.
  • La verifica SMS è necessaria solo per flussi di registrazione o recupero, ma perdere il controllo del numero/account può complicare una nuova registrazione.

Riferimento di configurazione (Signal)

Configurazione completa: Configurazione

Opzioni provider:

  • channels.signal.enabled: abilita/disabilita l'avvio del canale.
  • channels.signal.account: E.164 per l'account del bot.
  • channels.signal.cliPath: percorso di signal-cli.
  • channels.signal.httpUrl: URL completo del daemon (sovrascrive host/porta).
  • channels.signal.httpHost, channels.signal.httpPort: bind del daemon (predefinito 127.0.0.1:8080).
  • channels.signal.autoStart: avvio automatico del daemon (predefinito true se httpUrl non è impostato).
  • channels.signal.startupTimeoutMs: timeout di attesa dell'avvio in ms (limite 120000).
  • channels.signal.receiveMode: on-start | manual.
  • channels.signal.ignoreAttachments: salta i download degli allegati.
  • channels.signal.ignoreStories: ignora le storie dal daemon.
  • channels.signal.sendReadReceipts: inoltra le conferme di lettura.
  • channels.signal.dmPolicy: pairing | allowlist | open | disabled (predefinito: pairing).
  • channels.signal.allowFrom: elenco consentiti per DM (E.164 o uuid:<id>). open richiede "*". Signal non ha nomi utente; usa ID telefono/UUID.
  • channels.signal.groupPolicy: open | allowlist | disabled (predefinito: allowlist).
  • channels.signal.groupAllowFrom: elenco consentiti per gruppi; accetta ID gruppo Signal (raw, group:<id> o signal:group:<id>), numeri E.164 del mittente o valori uuid:<id>.
  • channels.signal.groups: override per gruppo indicizzati per ID gruppo Signal (o "*"). Campi supportati: requireMention, tools, toolsBySender.
  • channels.signal.accounts.<id>.groups: versione per account di channels.signal.groups per configurazioni multi-account.
  • channels.signal.historyLimit: numero massimo di messaggi di gruppo da includere come contesto (0 disabilita).
  • channels.signal.dmHistoryLimit: limite della cronologia DM in turni utente. Override per utente: channels.signal.dms["<phone_or_uuid>"].historyLimit.
  • channels.signal.textChunkLimit: dimensione dei blocchi in uscita (caratteri).
  • channels.signal.chunkMode: length (predefinito) o newline per dividere sulle righe vuote (confini di paragrafo) prima della suddivisione per lunghezza.
  • channels.signal.mediaMaxMb: limite dei media in ingresso/uscita (MB).

Opzioni globali correlate:

  • agents.list[].groupChat.mentionPatterns (Signal non supporta menzioni native).
  • messages.groupChat.mentionPatterns (fallback globale).
  • messages.responsePrefix.

Correlati