forked from Selig/openclaw-skill
Initial commit: OpenClaw Skill Collection
6 custom skills (assign-task, dispatch-webhook, daily-briefing, task-capture, qmd-brain, tts-voice) with technical documentation. Compatible with Claude Code, OpenClaw, Codex CLI, and OpenCode.
This commit is contained in:
194
openclaw-knowhow-skill/docs/channels/signal.md
Normal file
194
openclaw-knowhow-skill/docs/channels/signal.md
Normal file
@@ -0,0 +1,194 @@
|
||||
# Signal
|
||||
|
||||
## Signal (signal-cli)
|
||||
|
||||
**Status:** External CLI integration. Gateway talks to `signal-cli` over HTTP JSON-RPC + SSE.
|
||||
|
||||
## Quick Setup (Beginner)
|
||||
|
||||
1. Use a **separate Signal number** for the bot (recommended)
|
||||
2. Install `signal-cli` (Java required)
|
||||
3. Link the bot device and start the daemon:
|
||||
- `signal-cli link -n "OpenClaw"`
|
||||
4. Configure OpenClaw and start the gateway
|
||||
|
||||
**Minimal config:**
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
signal: {
|
||||
enabled: true,
|
||||
account: "+15551234567",
|
||||
cliPath: "signal-cli",
|
||||
dmPolicy: "pairing",
|
||||
allowFrom: ["+15557654321"],
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## What It Is
|
||||
|
||||
- Signal channel via `signal-cli` (not embedded libsignal)
|
||||
- Deterministic routing: replies always go back to Signal
|
||||
- DMs share the agent's main session; groups are isolated (`agent:<agentId>:signal:group:<groupId>`)
|
||||
|
||||
## Config Writes
|
||||
|
||||
By default, Signal is allowed to write config updates triggered by `/config set|unset` (requires `commands.config: true`).
|
||||
|
||||
Disable with:
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: { signal: { configWrites: false } },
|
||||
}
|
||||
```
|
||||
|
||||
## The Number Model (Important)
|
||||
|
||||
- The gateway connects to a **Signal device** (the `signal-cli` account)
|
||||
- If you run the bot on **your personal Signal account**, it will ignore your own messages (loop protection)
|
||||
- For "I text the bot and it replies," use a **separate bot number**
|
||||
|
||||
## Setup (Fast Path)
|
||||
|
||||
1. Install `signal-cli` (Java required)
|
||||
2. Link a bot account:
|
||||
- `signal-cli link -n "OpenClaw"` then scan the QR in Signal
|
||||
3. Configure Signal and start the gateway
|
||||
|
||||
**Example:**
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
signal: {
|
||||
enabled: true,
|
||||
account: "+15551234567",
|
||||
cliPath: "signal-cli",
|
||||
dmPolicy: "pairing",
|
||||
allowFrom: ["+15557654321"],
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Multi-account support: use `channels.signal.accounts` with per-account config and optional `name`.
|
||||
|
||||
## External Daemon Mode (httpUrl)
|
||||
|
||||
If you want to manage `signal-cli` yourself (slow JVM cold starts, container init, or shared CPUs), run the daemon separately and point OpenClaw at it:
|
||||
|
||||
```json5
|
||||
{
|
||||
channels: {
|
||||
signal: {
|
||||
httpUrl: "http://127.0.0.1:8080",
|
||||
autoStart: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
This skips auto-spawn and the startup wait inside OpenClaw. For slow starts when auto-spawning, set `channels.signal.startupTimeoutMs`.
|
||||
|
||||
## Access Control (DMs + Groups)
|
||||
|
||||
### DMs
|
||||
|
||||
- Default: `channels.signal.dmPolicy = "pairing"`
|
||||
- Unknown senders receive a pairing code; messages are ignored until approved (codes expire after 1 hour)
|
||||
- Approve via:
|
||||
- `openclaw pairing list signal`
|
||||
- `openclaw pairing approve signal <CODE>`
|
||||
- UUID-only senders (from `sourceUuid`) are stored as `uuid:<id>` in `channels.signal.allowFrom`
|
||||
|
||||
### Groups
|
||||
|
||||
- `channels.signal.groupPolicy = open | allowlist | disabled`
|
||||
- `channels.signal.groupAllowFrom` controls who can trigger in groups when `allowlist` is set
|
||||
|
||||
## How It Works (Behavior)
|
||||
|
||||
- `signal-cli` runs as a daemon; the gateway reads events via SSE
|
||||
- Inbound messages are normalized into the shared channel envelope
|
||||
- Replies always route back to the same number or group
|
||||
|
||||
## Media + Limits
|
||||
|
||||
- Outbound text is chunked to `channels.signal.textChunkLimit` (default 4000)
|
||||
- Optional newline chunking: set `channels.signal.chunkMode="newline"` to split on blank lines (paragraph boundaries) before length chunking
|
||||
- Attachments supported (base64 fetched from `signal-cli`)
|
||||
- Default media cap: `channels.signal.mediaMaxMb` (default 8)
|
||||
- Use `channels.signal.ignoreAttachments` to skip downloading media
|
||||
- Group history context uses `channels.signal.historyLimit` (or `channels.signal.accounts.*.historyLimit`), falling back to `messages.groupChat.historyLimit`. Set `0` to disable (default 50)
|
||||
|
||||
## Typing + Read Receipts
|
||||
|
||||
- **Typing indicators**: OpenClaw sends typing signals via `signal-cli sendTyping` and refreshes them while a reply is running
|
||||
- **Read receipts**: when `channels.signal.sendReadReceipts` is true, OpenClaw forwards read receipts for allowed DMs
|
||||
- Signal-cli does not expose read receipts for groups
|
||||
|
||||
## Reactions (Message Tool)
|
||||
|
||||
Use `message action=react` with `channel=signal`.
|
||||
|
||||
- Targets: sender E.164 or UUID (use `uuid:<id>` from pairing output; bare UUID works too)
|
||||
- `messageId` is the Signal timestamp for the message you're reacting to
|
||||
- Group reactions require `targetAuthor` or `targetAuthorUuid`
|
||||
|
||||
**Examples:**
|
||||
|
||||
```
|
||||
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=✅
|
||||
```
|
||||
|
||||
**Config:**
|
||||
|
||||
- `channels.signal.actions.reactions`: enable/disable reaction actions (default true)
|
||||
- `channels.signal.reactionLevel`: `off | ack | minimal | extensive`
|
||||
- `off`/`ack` disables agent reactions (message tool `react` will error)
|
||||
- `minimal`/`extensive` enables agent reactions and sets the guidance level
|
||||
- Per-account overrides: `channels.signal.accounts.<id>.actions.reactions`, `channels.signal.accounts.<id>.reactionLevel`
|
||||
|
||||
## Delivery Targets (CLI/cron)
|
||||
|
||||
- DMs: `signal:+15551234567` (or plain E.164)
|
||||
- UUID DMs: `uuid:<id>` (or bare UUID)
|
||||
- Groups: `signal:group:<groupId>`
|
||||
- Usernames: `username:<name>` (if supported by your Signal account)
|
||||
|
||||
## Configuration Reference (Signal)
|
||||
|
||||
### Provider Options
|
||||
|
||||
- `channels.signal.enabled`: enable/disable channel startup
|
||||
- `channels.signal.account`: E.164 for the bot account
|
||||
- `channels.signal.cliPath`: path to `signal-cli`
|
||||
- `channels.signal.httpUrl`: full daemon URL (overrides host/port)
|
||||
- `channels.signal.httpHost`, `channels.signal.httpPort`: daemon bind (default 127.0.0.1:8080)
|
||||
- `channels.signal.autoStart`: auto-spawn daemon (default true if `httpUrl` unset)
|
||||
- `channels.signal.startupTimeoutMs`: startup wait timeout in ms (cap 120000)
|
||||
- `channels.signal.receiveMode`: `on-start | manual`
|
||||
- `channels.signal.ignoreAttachments`: skip attachment downloads
|
||||
- `channels.signal.ignoreStories`: ignore stories from the daemon
|
||||
- `channels.signal.sendReadReceipts`: forward read receipts
|
||||
- `channels.signal.dmPolicy`: `pairing | allowlist | open | disabled` (default: pairing)
|
||||
- `channels.signal.allowFrom`: DM allowlist (E.164 or `uuid:<id>`). `open` requires `"*"`. Signal has no usernames; use phone/UUID ids
|
||||
- `channels.signal.groupPolicy`: `open | allowlist | disabled` (default: allowlist)
|
||||
- `channels.signal.groupAllowFrom`: group sender allowlist
|
||||
- `channels.signal.historyLimit`: max group messages to include as context (0 disables)
|
||||
- `channels.signal.dmHistoryLimit`: DM history limit in user turns. Per-user overrides: `channels.signal.dms["<phone_or_uuid>"].historyLimit`
|
||||
- `channels.signal.textChunkLimit`: outbound chunk size (chars)
|
||||
- `channels.signal.chunkMode`: `length` (default) or `newline` to split on blank lines (paragraph boundaries) before length chunking
|
||||
- `channels.signal.mediaMaxMb`: inbound/outbound media cap (MB)
|
||||
|
||||
### Related Global Options
|
||||
|
||||
- `agents.list[].groupChat.mentionPatterns` (Signal does not support native mentions)
|
||||
- `messages.groupChat.mentionPatterns` (global fallback)
|
||||
- `messages.responsePrefix`
|
||||
Reference in New Issue
Block a user