Signal (signal-cli)

Status: externe CLI-integratie. De gateway communiceert met signal-cli via HTTP JSON-RPC + SSE.

Vereisten

  • OpenClaw geinstalleerd op je server (Linux-flow hieronder getest op Ubuntu 24).
  • signal-cli beschikbaar op de host waar de gateway draait.
  • Een telefoonnummer dat een verificatie-SMS kan ontvangen (voor het SMS-registratiepad).
  • Browsertoegang voor Signal-captcha (signalcaptchas.org) tijdens registratie.

Snelle installatie (beginner)

  1. Gebruik een apart Signal-nummer voor de bot (aanbevolen).
  2. Installeer signal-cli (Java vereist als je de JVM-build gebruikt).
  3. Kies een installatiepad:
    • Pad A (QR-link): signal-cli link -n "OpenClaw" en scan met Signal.
    • Pad B (SMS-registratie): registreer een apart nummer met captcha + SMS-verificatie.
  4. Configureer OpenClaw en herstart de gateway.
  5. Stuur een eerste DM en keur de koppeling goed (openclaw pairing approve signal <CODE>).

Minimale configuratie:

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

Veldreferentie:

VeldBeschrijving
accountBot-telefoonnummer in E.164-formaat (+15551234567)
cliPathPad naar signal-cli (signal-cli als op PATH)
dmPolicyDM-toegangsbeleid (pairing aanbevolen)
allowFromTelefoonnummers of uuid:<id>-waarden die mogen DM’en

Wat het is

  • Signal-kanaal via signal-cli (niet embedded libsignal).
  • Deterministische routering: antwoorden gaan altijd terug naar Signal.
  • DM’s delen de hoofdsessie van de agent; groepen zijn geisoleerd (agent:<agentId>:signal:group:<groupId>).

Configschrijfacties

Standaard mag Signal config-updates schrijven die worden getriggerd door /config set|unset (vereist commands.config: true).

Uitschakelen met:

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

Het nummermodel (belangrijk)

  • De gateway maakt verbinding met een Signal-apparaat (het signal-cli-account).
  • Als je de bot draait op je persoonlijke Signal-account, negeert het je eigen berichten (lusbescherming).
  • Voor “ik stuur de bot een bericht en hij antwoordt” gebruik je een apart botnummer.

Installatiepad A: bestaand Signal-account koppelen (QR)

  1. Installeer signal-cli (JVM of native build).
  2. Koppel een botaccount:
    • signal-cli link -n "OpenClaw" en scan vervolgens de QR in Signal.
  3. Configureer Signal en start de gateway.

Voorbeeld:

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

Multi-account-ondersteuning: gebruik channels.signal.accounts met per-account-configuratie en optionele name. Zie gateway/configuration voor het gedeelde patroon.

Installatiepad B: apart botnummer registreren (SMS, Linux)

Gebruik dit wanneer je een apart botnummer wilt in plaats van een bestaand Signal-app-account te koppelen.

  1. Verkrijg een nummer dat SMS kan ontvangen (of spraakverificatie voor vaste lijnen).
    • Gebruik een apart botnummer om account-/sessieconflicten te voorkomen.
  2. Installeer signal-cli op de gatewayhost:
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

Als je de JVM-build gebruikt (signal-cli-${VERSION}.tar.gz), installeer dan eerst JRE 25+. Houd signal-cli bijgewerkt; upstream merkt op dat oude releases kunnen breken naarmate Signal-server-API’s veranderen.

  1. Registreer en verifieer het nummer:
signal-cli -a +<BOT_PHONE_NUMBER> register

Als captcha vereist is:

  1. Open https://signalcaptchas.org/registration/generate.html.
  2. Voltooi de captcha, kopieer de signalcaptcha://...-linkbestemming van “Open Signal”.
  3. Voer uit vanaf hetzelfde externe IP als de browsersessie wanneer mogelijk.
  4. Voer de registratie onmiddellijk opnieuw uit (captcha-tokens verlopen snel):
signal-cli -a +<BOT_PHONE_NUMBER> register --captcha '<SIGNALCAPTCHA_URL>'
signal-cli -a +<BOT_PHONE_NUMBER> verify <VERIFICATION_CODE>
  1. Configureer OpenClaw, herstart de gateway, verifieer het kanaal:
# If you run the gateway as a user systemd service:
systemctl --user restart openclaw-gateway

# Then verify:
openclaw doctor
openclaw channels status --probe
  1. Koppel je DM-afzender:
    • Stuur een willekeurig bericht naar het botnummer.
    • Keur de code goed op de server: openclaw pairing approve signal <PAIRING_CODE>.
    • Sla het botnummer op als contact op je telefoon om “Onbekend contact” te voorkomen.

Belangrijk: het registreren van een telefoonnummeraccount met signal-cli kan de hoofd-Signal-app-sessie voor dat nummer deauthenticeren. Gebruik bij voorkeur een apart botnummer, of gebruik QR-linkmodus als je je bestaande telefoon-app-setup wilt behouden.

Upstream-referenties:

  • signal-cli README: https://github.com/AsamK/signal-cli
  • Captcha-flow: https://github.com/AsamK/signal-cli/wiki/Registration-with-captcha
  • Koppelingflow: https://github.com/AsamK/signal-cli/wiki/Linking-other-devices-(Provisioning)

Externe daemonmodus (httpUrl)

Als je signal-cli zelf wilt beheren (trage JVM cold starts, containerinitialisatie of gedeelde CPU’s), draai de daemon apart en wijs OpenClaw ernaar:

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

Dit slaat auto-spawn en de opstartwachttijd binnen OpenClaw over. Voor trage starts bij auto-spawning, stel channels.signal.startupTimeoutMs in.

Toegangscontrole (DM’s + groepen)

DM’s:

  • Standaard: channels.signal.dmPolicy = "pairing".
  • Onbekende afzenders ontvangen een koppelingscode; berichten worden genegeerd totdat goedgekeurd (codes verlopen na 1 uur).
  • Goedkeuren via:
    • openclaw pairing list signal
    • openclaw pairing approve signal <CODE>
  • Koppeling is de standaard tokenuitwisseling voor Signal-DM’s. Details: Koppeling
  • UUID-alleen afzenders (van sourceUuid) worden opgeslagen als uuid:<id> in channels.signal.allowFrom.

Groepen:

  • channels.signal.groupPolicy = open | allowlist | disabled.
  • channels.signal.groupAllowFrom bepaalt wie kan triggeren in groepen wanneer allowlist is ingesteld.
  • channels.signal.groups["<group-id>" | "*"] kan groepsgedrag overschrijven met requireMention, tools en toolsBySender.
  • Gebruik channels.signal.accounts.<id>.groups voor per-account-overschrijvingen in multi-account-opstellingen.
  • Runtime-opmerking: als channels.signal volledig ontbreekt, valt de runtime terug op groupPolicy="allowlist" voor groepscontroles (zelfs als channels.defaults.groupPolicy is ingesteld).

Hoe het werkt (gedrag)

  • signal-cli draait als daemon; de gateway leest events via SSE.
  • Inkomende berichten worden genormaliseerd naar de gedeelde kanaalenvelop.
  • Antwoorden worden altijd teruggerouteerd naar hetzelfde nummer of dezelfde groep.

Media + limieten

  • Uitgaande tekst wordt opgesplitst bij channels.signal.textChunkLimit (standaard 4000).
  • Optionele newline-opsplitsing: stel channels.signal.chunkMode="newline" in om te splitsen op lege regels (alineagrenzen) voor lengteopsplitsing.
  • Bijlagen worden ondersteund (base64 opgehaald van signal-cli).
  • Standaard medialimiet: channels.signal.mediaMaxMb (standaard 8).
  • Gebruik channels.signal.ignoreAttachments om mediadownloads over te slaan.
  • Groepsgeschiedeniscontext gebruikt channels.signal.historyLimit (of channels.signal.accounts.*.historyLimit), met terugval op messages.groupChat.historyLimit. Stel 0 in om uit te schakelen (standaard 50).

Typindicatoren + leesbevestigingen

  • Typindicatoren: OpenClaw stuurt typsignalen via signal-cli sendTyping en vernieuwt ze terwijl een antwoord wordt uitgevoerd.
  • Leesbevestigingen: wanneer channels.signal.sendReadReceipts true is, stuurt OpenClaw leesbevestigingen door voor toegestane DM’s.
  • Signal-cli stelt geen leesbevestigingen bloot voor groepen.

Reacties (berichttool)

  • Gebruik message action=react met channel=signal.
  • Doelen: afzender E.164 of UUID (gebruik uuid:<id> uit koppelings-output; kale UUID werkt ook).
  • messageId is het Signal-tijdstempel voor het bericht waarop je reageert.
  • Groepsreacties vereisen targetAuthor of targetAuthorUuid.

Voorbeelden:

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

Configuratie:

  • channels.signal.actions.reactions: reactieacties in-/uitschakelen (standaard true).
  • channels.signal.reactionLevel: off | ack | minimal | extensive.
    • off/ack schakelt agentreacties uit (berichttool react geeft een fout).
    • minimal/extensive schakelt agentreacties in en stelt het begeleidingsniveau in.
  • Per-account-overschrijvingen: channels.signal.accounts.<id>.actions.reactions, channels.signal.accounts.<id>.reactionLevel.

Afleveringsdoelen (CLI/cron)

  • DM’s: signal:+15551234567 (of gewoon E.164).
  • UUID-DM’s: uuid:<id> (of kale UUID).
  • Groepen: signal:group:<groupId>.
  • Gebruikersnamen: username:<name> (indien ondersteund door je Signal-account).

Probleemoplossing

Voer eerst deze commandoladder uit:

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

Bevestig vervolgens de DM-koppelingsstatus indien nodig:

openclaw pairing list signal

Veelvoorkomende fouten:

  • Daemon bereikbaar maar geen antwoorden: verifieer account-/daemoninstellingen (httpUrl, account) en ontvangstmodus.
  • DM’s genegeerd: afzender wacht op koppelings-goedkeuring.
  • Groepsberichten genegeerd: groepsafzender-/mention-gating blokkeert aflevering.
  • Configvalidatiefouten na bewerkingen: voer openclaw doctor --fix uit.
  • Signal ontbreekt in diagnostiek: bevestig channels.signal.enabled: true.

Extra controles:

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

Voor triageflow: /channels/troubleshooting.

Beveiligingsnotities

  • signal-cli slaat accountsleutels lokaal op (doorgaans ~/.local/share/signal-cli/data/).
  • Maak een back-up van de Signal-accountstatus voor servermigratie of herbouw.
  • Houd channels.signal.dmPolicy: "pairing" tenzij je expliciet bredere DM-toegang wilt.
  • SMS-verificatie is alleen nodig voor registratie- of herstelflows, maar het verliezen van controle over het nummer/account kan herregistratie bemoeilijken.

Configuratiereferentie (Signal)

Volledige configuratie: Configuratie

Provideropties:

  • channels.signal.enabled: kanaal in-/uitschakelen bij opstart.
  • channels.signal.account: E.164 voor het botaccount.
  • channels.signal.cliPath: pad naar signal-cli.
  • channels.signal.httpUrl: volledige daemon-URL (overschrijft host/poort).
  • channels.signal.httpHost, channels.signal.httpPort: daemon-bind (standaard 127.0.0.1:8080).
  • channels.signal.autoStart: daemon automatisch starten (standaard true als httpUrl niet is ingesteld).
  • channels.signal.startupTimeoutMs: opstart-wachttijd in ms (limiet 120000).
  • channels.signal.receiveMode: on-start | manual.
  • channels.signal.ignoreAttachments: bijlagedownloads overslaan.
  • channels.signal.ignoreStories: stories van de daemon negeren.
  • channels.signal.sendReadReceipts: leesbevestigingen doorsturen.
  • channels.signal.dmPolicy: pairing | allowlist | open | disabled (standaard: pairing).
  • channels.signal.allowFrom: DM-allowlist (E.164 of uuid:<id>). open vereist "*". Signal heeft geen gebruikersnamen; gebruik telefoon-/UUID-ID’s.
  • channels.signal.groupPolicy: open | allowlist | disabled (standaard: allowlist).
  • channels.signal.groupAllowFrom: groepsafzender-allowlist.
  • channels.signal.groups: per-groep-overschrijvingen per Signal-groeps-ID (of "*"). Ondersteunde velden: requireMention, tools, toolsBySender.
  • channels.signal.accounts.<id>.groups: per-account-versie van channels.signal.groups voor multi-account-opstellingen.
  • channels.signal.historyLimit: maximaal aantal groepsberichten om als context op te nemen (0 schakelt uit).
  • channels.signal.dmHistoryLimit: DM-geschiedenislimiet in gebruikersbeurten. Per-gebruiker-overschrijvingen: channels.signal.dms["<phone_or_uuid>"].historyLimit.
  • channels.signal.textChunkLimit: uitgaande chunkgrootte (tekens).
  • channels.signal.chunkMode: length (standaard) of newline om te splitsen op lege regels (alineagrenzen) voor lengteopsplitsing.
  • channels.signal.mediaMaxMb: inkomende/uitgaande medialimiet (MB).

Gerelateerde globale opties:

  • agents.list[].groupChat.mentionPatterns (Signal ondersteunt geen native vermeldingen).
  • messages.groupChat.mentionPatterns (globale terugval).
  • messages.responsePrefix.