Signal
Signal:基于 signal-cli(JSON-RPC + SSE)的接入、配置与号码模型
状态:外部 CLI 集成。Gateway 通过 HTTP JSON-RPC + SSE 与 signal-cli 通信。
新手快速配置
1. 推荐使用 <strong>单独的 Signal 号码</strong> 作为 bot 号码。
2. 安装 <code>signal-cli</code>(需要 Java)。
3. 链接 bot 设备并启动 daemon:
- <code>signal-cli link -n "OpenClaw"</code>
4. 配置 OpenClaw 并启动 gateway。
最小配置:
{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}它是什么
- 通过 <code>signal-cli</code> 接入 Signal(不是内嵌 libsignal)。
- 确定性路由:回复始终回到 Signal。
- 私信使用 agent 的主会话;群聊会隔离为 '<code>'agent:'<agentId>':signal:group:'<groupId>''</code>'。
配置写回(Config writes)
默认允许 Signal 把由 <code>/config set|unset</code> 触发的更新写回配置文件(需要 <code>commands.config: true</code>)。
禁用:
{
channels: { signal: { configWrites: false } },
}号码模型(重要)
- Gateway 连接到的是一个 <strong>Signal 设备</strong>(也就是 <code>signal-cli</code> 所登录的账号)。
- 如果你用 <strong>自己的个人 Signal 账号</strong> 跑 bot,为避免回环,它会忽略你自己发的消息。
- 如果你希望"我发消息给 bot,bot 回复我",请使用 <strong>单独的 bot 号码</strong>。
设置(快速路径)
1. 安装 <code>signal-cli</code>(需要 Java)。
2. 链接 bot 账号:
- <code>signal-cli link -n "OpenClaw"</code> 然后在 Signal 里扫码
3. 配置并启动 gateway。
多账号:用 '<code>'channels.signal.accounts'</code>' 配置每个账号(可选 '<code>'name'</code>')。共享结构见 '<a href="/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts">'/gateway/configuration'</a>'。
外部 daemon 模式(httpUrl)
如果你想自己管理 <code>signal-cli</code>(避免 JVM 冷启动、容器初始化、或共享 CPU 的启动开销),可以单独运行 daemon,然后让 OpenClaw 连接它:
{
channels: {
signal: {
httpUrl: "http://127.0.0.1:8080",
autoStart: false,
},
},
}这会跳过 OpenClaw 侧的自动拉起与启动等待。若自动拉起时启动过慢,可调 <code>channels.signal.startupTimeoutMs</code>。
访问控制(私聊 + 群聊)
私聊:
- 默认:<code>channels.signal.dmPolicy = "pairing"</code>。
- 未知发送者会收到配对码,批准前消息不会处理(1 小时过期)。
- 批准:
- <code>openclaw pairing list signal</code>
- '<code>'openclaw pairing approve signal '<CODE>''</code>'
- pairing 是 Signal 私聊默认 token exchange。见 '<a href="/start/pairing">'Pairing'</a>'。
- If the sender only has a UUID (from '<code>'sourceUuid'</code>'), it will be stored in '<code>'channels.signal.allowFrom'</code>' as '<code>'uuid:'<id>''</code>'.
群聊:
- <code>channels.signal.groupPolicy = open | allowlist | disabled</code>。
- <code>channels.signal.groupAllowFrom</code> 控制当 <code>allowlist</code> 时哪些发送者可触发。
工作方式(行为)
- <code>signal-cli</code> 以 daemon 方式运行;gateway 通过 SSE 读取事件。
- 入站消息会被归一化到通用的 channel envelope。
- 回复始终回到同一号码或群。
媒体与限制
- 出站文本按 <code>channels.signal.textChunkLimit</code> 分段(默认 4000)。
- 可选按空行优先分段:<code>channels.signal.chunkMode="newline"</code>。
- 支持附件(由 <code>signal-cli</code> 提供 base64)。
- 默认媒体上限:<code>channels.signal.mediaMaxMb</code>(默认 8MB)。
- <code>channels.signal.ignoreAttachments</code> 可跳过媒体下载。
- 群历史上下文:<code>channels.signal.historyLimit</code>(或 <code>channels.signal.accounts.*.historyLimit</code>),兜底 <code>messages.groupChat.historyLimit</code>。设为 <code>0</code> 禁用(默认 50)。
输入状态与已读
- <strong>Typing</strong>:OpenClaw 会通过 <code>signal-cli sendTyping</code> 发送输入中信号,并在回复运行期间刷新。
- <strong>Read receipts</strong>:当 <code>channels.signal.sendReadReceipts</code> 为 true 时,OpenClaw 会为允许的私聊转发已读回执。
- signal-cli 不支持群聊已读回执。
Reactions(消息工具)
- 使用消息工具:<code>message action=react channel=signal</code>。
- target 可用 E.164 或 UUID(从 pairing 输出中拿 '<code>'uuid:'<id>''</code>';裸 UUID 也可)。
- <code>messageId</code> 是你要反应的那条消息对应的 Signal 时间戳。
- 群聊反应需要 <code>targetAuthor</code> 或 <code>targetAuthorUuid</code>。
示例:
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=✅
配置开关:
- <code>channels.signal.actions.reactions</code>:是否启用 reactions(默认 true)。
- <code>channels.signal.reactionLevel</code>:<code>off | ack | minimal | extensive</code>
- <code>off</code>/<code>ack</code> 会禁用 agent reactions(消息工具 <code>react</code> 会报错)
- <code>minimal</code>/<code>extensive</code> 会启用 agent reactions,并设置引导强度
- 按账号覆盖:'<code>'channels.signal.accounts.'<id>'.actions.reactions'</code>'、'<code>'channels.signal.accounts.'<id>'.reactionLevel'</code>'
投递目标(CLI/cron)
- 私聊:<code>signal:+15551234567</code>(或直接写 E.164)
- UUID 私聊:'<code>'uuid:'<id>''</code>'(或裸 UUID)
- 群聊:'<code>'signal:group:'<groupId>''</code>'
- 用户名:'<code>'username:'<name>''</code>'(若你的 Signal 账号支持)
Signal 配置参考
完整配置参考见 '<a href="/gateway/configuration">'Configuration'</a>'。
通道选项:
- <code>channels.signal.enabled</code>
- <code>channels.signal.account</code>(bot 账号的 E.164)
- <code>channels.signal.cliPath</code>
- <code>channels.signal.httpUrl</code>(daemon URL)
- <code>channels.signal.httpHost</code>、<code>channels.signal.httpPort</code>(默认 127.0.0.1:8080)
- <code>channels.signal.autoStart</code>(httpUrl 未设置时默认 true)
- <code>channels.signal.startupTimeoutMs</code>(启动等待,最大 120000)
- <code>channels.signal.receiveMode</code>(<code>on-start | manual</code>)
- <code>channels.signal.ignoreAttachments</code>
- <code>channels.signal.ignoreStories</code>
- <code>channels.signal.sendReadReceipts</code>
- <code>channels.signal.dmPolicy</code>(<code>pairing | allowlist | open | disabled</code>,默认 pairing)
- '<code>'channels.signal.allowFrom'</code>'(私聊 allowlist:E.164 或 '<code>'uuid:'<id>''</code>';open 需要 '<code>'"*"'</code>')
- <code>channels.signal.groupPolicy</code>(默认 allowlist)
- <code>channels.signal.groupAllowFrom</code>
- <code>channels.signal.historyLimit</code>(0 禁用)
- '<code>'channels.signal.dmHistoryLimit'</code>'(私聊历史上限,按 user turns;按用户覆盖 '<code>'channels.signal.dms["'<phone_or_uuid>'"].historyLimit'</code>')
- <code>channels.signal.textChunkLimit</code>
- <code>channels.signal.chunkMode</code>
- <code>channels.signal.mediaMaxMb</code>
相关全局选项:
- <code>agents.list[].groupChat.mentionPatterns</code>(Signal 没有原生 mentions)
- <code>messages.groupChat.mentionPatterns</code>
- <code>messages.responsePrefix</code>