Skip to content

Commit b110a8e

Browse files
OpenClaw BotCopilot
andcommitted
Signal: add container REST API support
Co-authored-by: Copilot <[email protected]>
1 parent f8123e4 commit b110a8e

17 files changed

Lines changed: 1907 additions & 17 deletions
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Signal/container mode: add REST API support for bbernhard/signal-cli-rest-api containerized deployments via a unified adapter layer, with automatic mode detection and `channels.signal.apiMode` config. (#10240) Thanks @Hua688.

docs/channels/signal.md

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
---
2-
summary: "Signal support via signal-cli (JSON-RPC + SSE), setup paths, and number model"
2+
summary: "Signal support via signal-cli (native daemon or bbernhard container), setup paths, and number model"
33
read_when:
44
- Setting up Signal support
55
- Debugging Signal send/receive
66
title: "Signal"
77
---
88

9-
Status: external CLI integration. Gateway talks to `signal-cli` over HTTP JSON-RPC + SSE.
9+
Status: external CLI integration. Gateway talks to `signal-cli` over HTTP — either native daemon (JSON-RPC + SSE) or bbernhard/signal-cli-rest-api container (REST + WebSocket).
1010

1111
## Prerequisites
1212

1313
- OpenClaw installed on your server (Linux flow below tested on Ubuntu 24).
14-
- `signal-cli` available on the host where the gateway runs.
14+
- One of:
15+
- `signal-cli` available on the host (native mode), **or**
16+
- `bbernhard/signal-cli-rest-api` Docker container (container mode).
1517
- A phone number that can receive one verification SMS (for SMS registration path).
1618
- Browser access for Signal captcha (`signalcaptchas.org`) during registration.
1719

@@ -177,6 +179,54 @@ If you want to manage `signal-cli` yourself (slow JVM cold starts, container ini
177179

178180
This skips auto-spawn and the startup wait inside OpenClaw. For slow starts when auto-spawning, set `channels.signal.startupTimeoutMs`.
179181

182+
## Container mode (bbernhard/signal-cli-rest-api)
183+
184+
Instead of running `signal-cli` natively, you can use the [bbernhard/signal-cli-rest-api](https://github.com/bbernhard/signal-cli-rest-api) Docker container. This wraps `signal-cli` behind a REST API and WebSocket interface.
185+
186+
Requirements:
187+
188+
- The container **must** run with `MODE=json-rpc` for real-time message receiving.
189+
- Register or link your Signal account inside the container before connecting OpenClaw.
190+
191+
Example `docker-compose.yml` service:
192+
193+
```yaml
194+
signal-cli:
195+
image: bbernhard/signal-cli-rest-api:latest
196+
environment:
197+
MODE: json-rpc
198+
ports:
199+
- "8080:8080"
200+
volumes:
201+
- signal-cli-data:/home/.local/share/signal-cli
202+
```
203+
204+
OpenClaw config:
205+
206+
```json5
207+
{
208+
channels: {
209+
signal: {
210+
enabled: true,
211+
account: "+15551234567",
212+
httpUrl: "http://signal-cli:8080",
213+
autoStart: false,
214+
apiMode: "container", // or "auto" to detect automatically
215+
},
216+
},
217+
}
218+
```
219+
220+
The `apiMode` field controls which protocol OpenClaw uses:
221+
222+
| Value | Behavior |
223+
| ------------- | ------------------------------------------------------------------------------------ |
224+
| `"auto"` | (Default) Probes both endpoints and picks whichever responds first |
225+
| `"native"` | Force native signal-cli (JSON-RPC at `/api/v1/rpc`, SSE at `/api/v1/events`) |
226+
| `"container"` | Force bbernhard container (REST at `/v2/send`, WebSocket at `/v1/receive/{account}`) |
227+
228+
When `apiMode` is `"auto"`, OpenClaw caches the detected mode for 30 seconds to avoid repeated probes.
229+
180230
## Access control (DMs + groups)
181231

182232
DMs:
@@ -199,7 +249,8 @@ Groups:
199249

200250
## How it works (behavior)
201251

202-
- `signal-cli` runs as a daemon; the gateway reads events via SSE.
252+
- Native mode: `signal-cli` runs as a daemon; the gateway reads events via SSE.
253+
- Container mode: the gateway sends via REST API and receives via WebSocket.
203254
- Inbound messages are normalized into the shared channel envelope.
204255
- Replies always route back to the same number or group.
205256

@@ -299,6 +350,7 @@ Full configuration: [Configuration](/gateway/configuration)
299350
Provider options:
300351

301352
- `channels.signal.enabled`: enable/disable channel startup.
353+
- `channels.signal.apiMode`: `auto | native | container` (default: auto). See [Container mode](#container-mode-bbernhardsignal-cli-rest-api).
302354
- `channels.signal.account`: E.164 for the bot account.
303355
- `channels.signal.cliPath`: path to `signal-cli`.
304356
- `channels.signal.httpUrl`: full daemon URL (overrides host/port).

extensions/signal/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
"private": true,
55
"description": "OpenClaw Signal channel plugin",
66
"type": "module",
7+
"dependencies": {
8+
"ws": "^8.20.0"
9+
},
710
"devDependencies": {
811
"@openclaw/plugin-sdk": "workspace:*"
912
},

0 commit comments

Comments
 (0)