Mainstream messaging

Signal

Signal 是可下載的頻道外掛(@openclaw/signal)。閘道透過 HTTP 與 signal-cli 通訊:可以使用原生常駐程式(JSON-RPC + SSE),或使用 bbernhard/signal-cli-rest-api 容器(REST + WebSocket)。OpenClaw 不內嵌 libsignal。

號碼模型(請先閱讀)

  • 閘道會連線至一個 Signal 裝置:即 signal-cli 帳號。
  • 若在你的個人 Signal 帳號上執行機器人,它會忽略你自己的訊息(迴圈保護)。
  • 若要實現「我傳訊息給機器人,機器人便回覆」,請使用獨立的機器人號碼

安裝

bash
openclaw plugins install @openclaw/signal

未限定來源的外掛規格會先嘗試 ClawHub,再退回 npm。可使用 openclaw plugins install clawhub:@openclaw/signalnpm:@openclaw/signal 強制指定來源。plugins install 會註冊並啟用外掛;不需要另外執行 enable 步驟。一般安裝規則請參閱外掛

快速設定

  • 選擇號碼

    請為機器人使用獨立的 Signal 號碼(建議)。

  • 安裝外掛

    bash
    openclaw plugins install @openclaw/signal
  • 執行引導式設定

    bash
    openclaw channels add

    精靈會偵測 signal-cli 是否位於 PATH;若不存在,會提供安裝選項:在 Linux x86-64 上下載官方原生 GraalVM 組建,或在 macOS 和其他架構上透過 Homebrew 安裝。接著會提示輸入機器人號碼與 signal-cli 路徑。

    若要進行非互動式設定,openclaw channels add --channel signal 也接受以 --signal-number <e164> 指定機器人電話號碼,並可使用 --http-host <host>--http-port <port> 指定 Signal 常駐程式端點(預設為 127.0.0.1:8080)。

  • 連結或註冊帳號

    • QR 連結(最快): signal-cli link -n "OpenClaw",然後使用 Signal 掃描。請參閱路徑 A
    • **SMS 註冊:**使用專用號碼,搭配驗證碼與 SMS 驗證。請參閱路徑 B
  • 驗證並配對

    bash
    openclaw gateway call channels.status --params '{"probe":true}'

    傳送第一則私訊並核准配對:openclaw pairing approve signal &lt;CODE&gt;

  • 最小設定:

    json5
    {  channels: {    signal: {      enabled: true,      account: "+15551234567",      transport: {        kind: "managed-native",        cliPath: "signal-cli",      },      dmPolicy: "pairing",      allowFrom: ["+15557654321"],    },  },}
    欄位 說明
    account 採用 E.164 格式的機器人電話號碼(+15551234567
    transport 帳號擁有的 Signal 連線與程序模式
    dmPolicy 私訊存取政策(建議使用 pairing
    allowFrom 允許傳送私訊的電話號碼或 uuid:<id>

    多帳號支援:使用 channels.signal.accounts 設定各個帳號,並可選擇性設定 name。每個具名帳號都擁有自己的 transport;它不會繼承頂層傳輸設定。頂層傳輸設定僅屬於隱含的 default 帳號。共用模式請參閱多帳號頻道

    功能概述

    • 確定性路由:回覆一律傳回 Signal。
    • 私訊共用代理程式的主要工作階段;群組彼此隔離(agent:<agentId>:signal:group:<groupId>)。
    • Signal 預設可以寫入由 /config set|unset 觸發的設定更新(需要 commands.config: true)。可透過 channels.signal.configWrites: false 停用。

    設定路徑 A:連結現有 Signal 帳號(QR)

    1. 安裝 signal-cli(JVM 或原生組建),或讓 openclaw channels add 為你安裝。
    2. 連結機器人帳號:執行 signal-cli link -n "OpenClaw",然後在 Signal 中掃描 QR 碼。
    3. 設定 Signal 並啟動閘道。

    設定路徑 B:註冊專用機器人號碼(SMS、Linux)

    若要使用專用機器人號碼,而非連結現有的 Signal 應用程式帳號,請使用此方式。以下流程已在 Ubuntu 24 上測試。

    1. 取得可接收 SMS 的號碼(市話也可使用語音驗證)。專用機器人號碼可避免帳號/工作階段衝突。
    2. 在閘道主機上安裝 signal-cli
    bash
    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 /optsudo ln -sf /opt/signal-cli /usr/local/bin/signal-cli --version

    若使用 JVM 組建(signal-cli-${VERSION}.tar.gz),請先安裝 JRE。請持續更新 signal-cli;上游指出,Signal 伺服器 API 變更時,舊版本可能會故障。

    1. 註冊並驗證號碼:
    bash
    signal-cli -a +&lt;BOT_PHONE_NUMBER&gt; register

    若需要驗證碼(完成此步驟需要瀏覽器存取權):

    1. 開啟 https://signalcaptchas.org/registration/generate.html
    2. 完成驗證碼,從 "Open Signal" 複製 signalcaptcha://... 連結目標。
    3. 如有可能,請從與瀏覽器工作階段相同的外部 IP 執行(驗證碼權杖很快就會過期)。
    4. 立即註冊並驗證:
    bash
    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. 設定 OpenClaw、重新啟動閘道並驗證頻道:
    bash
    # 如果你將閘道作為使用者 systemd 服務執行:systemctl --user restart openclaw-gateway.service # 接著進行驗證:openclaw doctoropenclaw channels status --probe
    1. 配對你的私訊傳送者:
      • 向機器人號碼傳送任意訊息。
      • 在伺服器上核准:openclaw pairing approve signal &lt;PAIRING_CODE&gt;
      • 將機器人號碼儲存為手機上的聯絡人,以避免出現 "Unknown contact"。

    上游參考資料:

    • signal-cli README:https://github.com/AsamK/signal-cli
    • 驗證碼流程:https://github.com/AsamK/signal-cli/wiki/Registration-with-captcha
    • 連結流程:https://github.com/AsamK/signal-cli/wiki/Linking-other-devices-(Provisioning)

    外部原生常駐程式模式

    若要自行管理 signal-cli(例如 JVM 冷啟動緩慢、容器初始化或共用 CPU),請個別執行常駐程式,並將 OpenClaw 指向該程式:

    進行非互動式設定時,請視需要明確選取端點種類:

    bash
    openclaw channels add --channel signal --signal-number +15551234567 \  --http-url http://127.0.0.1:8080 --signal-transport external-native
    json5
    {  channels: {    signal: {      transport: {        kind: "external-native",        url: "http://127.0.0.1:8080",      },    },  },}

    這會略過自動啟動程序以及 OpenClaw 的啟動等待。若受管理的常駐程式啟動緩慢,請設定 channels.signal.transport.startupTimeoutMs

    容器模式(bbernhard/signal-cli-rest-api)

    除了以原生方式執行 signal-cli,也可以使用 bbernhard/signal-cli-rest-api Docker 容器;它會將 signal-cli 封裝於 REST + WebSocket 介面後方。

    bash
    openclaw channels add --channel signal --signal-number +15551234567 \  --http-url http://signal-cli:8080 --signal-transport container

    需求:

    • 容器必須MODE=json-rpc 執行,才能即時接收訊息。
    • 連線 OpenClaw 前,請先在容器內註冊或連結你的 Signal 帳號。

    docker-compose.yml 服務範例:

    yaml
    signal-cli:  image: bbernhard/signal-cli-rest-api:latest  environment:    MODE: json-rpc  ports:    - "8080:8080"  volumes:    - signal-cli-data:/home/.local/share/signal-cli

    OpenClaw 設定:

    json5
    {  channels: {    signal: {      enabled: true,      account: "+15551234567",      transport: {        kind: "container",        url: "http://signal-cli:8080",      },    },  },}

    transport.kind 控制 OpenClaw 使用的通訊協定與程序生命週期:

    行為
    "managed-native" 啟動原生 signal-cli,並在 /api/v1/rpc 使用 JSON-RPC、在 /api/v1/events 使用 SSE;url 可以選取不同於常駐程式繫結位址的連線端點
    "external-native" 連線至已在執行的原生 signal-cli 常駐程式
    "container" 連線至位於 /v2/send 的 bbernhard REST,以及位於 /v1/receive/{account} 的 WebSocket

    設定程序與 openclaw doctor --fix 可以探查現有端點一次,以識別其具體種類。執行階段操作不會自動偵測或切換通訊協定。

    當容器公開相符的 API 時,容器模式支援與原生模式相同的 Signal 操作:傳送、接收、附件、輸入狀態指示、已讀/已檢視回條、表情回應、群組及樣式文字。OpenClaw 會將原生 Signal RPC 呼叫轉換為容器的 REST 承載資料,包括 group.{base64(internal_id)} 群組 ID,以及用於格式化文字的 text_mode: "styled"

    操作注意事項:

    • 請使用 MODE=json-rpc 接收訊息。MODE=normal 可能會讓 /v1/about 看似正常,但 /v1/receive/{account} 不會升級為 WebSocket,因此容器的接收串流無法通過探查。
    • 請為 bbernhard REST API 設定 kind: "container",並為原生 signal-cli JSON-RPC/SSE 設定 kind: "external-native"
    • 容器附件下載遵循與原生模式相同的媒體位元組限制。若伺服器傳送 Content-Length,過大的回應會在完整緩衝前遭拒絕;否則會在串流處理期間遭拒絕。

    存取控制(私訊 + 群組)

    私訊:

    • 預設值:channels.signal.dmPolicy = "pairing"
    • 未知傳送者會收到配對碼;核准前會忽略其訊息(配對碼會在 1 小時後到期)。
    • 透過 openclaw pairing list signalopenclaw pairing approve signal &lt;CODE&gt; 核准。
    • 配對是 Signal 私訊預設的權杖交換方式。詳細資訊請參閱:配對
    • 僅有 UUID 的傳送者(來自 sourceUuid)會在 channels.signal.allowFrom 中儲存為 uuid:<id>

    群組:

    • channels.signal.groupPolicy = open | allowlist | disabled
    • channels.signal.groupAllowFrom 控制在設定 allowlist 時,哪些群組或傳送者可觸發群組回覆;項目可以是 Signal 群組 ID(原始格式、group:<id>signal:group:<id>)、傳送者電話號碼、uuid:<id> 值或 *
    • channels.signal.groups["<group-id>" | "*"] 可使用 requireMentiontoolstoolsBySender 覆寫群組行為。
    • 在多帳號設定中,使用 channels.signal.accounts.<id>.groups 進行個別帳號覆寫。
    • 透過 groupAllowFrom 將 Signal 群組加入允許清單,本身並不會停用提及閘控。除非已設定 requireMention=true,否則明確設定的 channels.signal.groups["<group-id>"] 項目會處理每則群組訊息。
    • 使用 requireMention=true 時,會根據結構化提及中繼資料,將 Signal 原生 @提及與機器人帳號電話或 accountUuid 進行比對。設定的 mentionPatterns 仍會作為純文字備援。
    • 執行階段注意事項:如果完全缺少 channels.signal,執行階段會改用 groupPolicy="allowlist" 進行群組檢查(即使已設定 channels.defaults.groupPolicy)。

    具有有限內容範圍且受提及閘控的群組:

    json5
    {  channels: {    signal: {      account: "+15551234567",      accountUuid: "bot-signal-uuid",      groupPolicy: "allowlist",      groupAllowFrom: ["group:<signal-group-id>"],      historyLimit: 8,      groups: {        "<signal-group-id>": { requireMention: true },      },    },  },  messages: {    groupChat: {      mentionPatterns: ["\\bopenclaw\\b"],    },  },}

    未提及機器人的允許群組訊息不會觸發回應,且只會保留在有限的待處理歷程視窗中。稍後原生 @提及或備援文字提及觸發機器人時,OpenClaw 會納入近期內容,並回覆至同一群組。遭略過的附件內容不會下載;在待處理內容中,它們可能只會顯示為精簡的媒體預留位置。

    運作方式(行為)

    • 原生模式:signal-cli 以常駐程式執行;閘道透過 SSE 讀取事件。
    • 容器模式:閘道透過 REST API 傳送,並透過 WebSocket 接收。
    • 傳入訊息會正規化為共用的頻道封裝。
    • 回覆一律路由回相同的號碼或群組。
    • 當後端接受傳入訊息的時間戳記與作者時,對傳入訊息的回覆會包含原生 Signal 引用中繼資料;如果引用中繼資料缺失或遭拒,OpenClaw 會以一般訊息傳送回覆。
    • 使用 channels.signal.replyToMode = off | first | all | batched 設定原生引用的使用方式,或使用 channels.signal.replyToModeByChatType.direct/group 依聊天類型覆寫。channels.signal.accounts.<id> 下的帳號層級值優先適用。

    媒體與限制

    • 傳出文字會依 channels.signal.textChunkLimit 分段(預設 4000)。
    • 選用的換行分段:設定 channels.signal.streaming.chunkMode="newline",可先依空白行(段落邊界)分割,再依長度分段。
    • 支援附件(從 signal-cli 擷取 base64)。
    • 缺少 contentType 時,語音備忘錄附件會使用 signal-cli 檔名作為 MIME 備援,因此音訊轉錄仍可辨識 AAC 語音備忘錄。
    • 預設媒體上限:channels.signal.mediaMaxMb(預設 8)。
    • 使用 channels.signal.ignoreAttachments 可針對任何傳輸方式略過媒體下載。
    • 群組歷程內容使用 channels.signal.historyLimit(或 channels.signal.accounts.*.historyLimit),並以 messages.groupChat.historyLimit 作為備援。設定 0 即可停用(預設 50)。

    輸入中狀態與已讀回條

    • 輸入中指示器:OpenClaw 透過 signal-cli sendTyping 傳送輸入中訊號,並在回覆執行期間持續重新整理。
    • 已讀回條:當 channels.signal.sendReadReceipts 為 true 時,OpenClaw 會轉送允許之私訊的已讀回條。
    • signal-cli 不會提供群組的已讀回條。

    生命週期狀態反應

    設定 messages.statusReactions.enabled: true,讓 Signal 在傳入回合上顯示共用的已排入佇列/思考中/工具/壓縮/完成/錯誤反應生命週期。Signal 使用傳入訊息的時間戳記作為反應目標;群組反應會使用 Signal 群組 ID 加上原始傳送者作為目標作者來傳送。

    狀態反應也需要確認反應,以及相符的 messages.ackReactionScopedirectgroup-allgroup-mentionsall)。設定 channels.signal.reactionLevel: "off" 可停用 Signal 狀態反應。

    Signal 會在最終完成/錯誤狀態後還原初始確認反應。

    反應(訊息工具)

    搭配 channel=signal 使用 message action=react

    • 目標:傳送者的 E.164 或 UUID(使用配對輸出中的 uuid:<id>;也可使用不含前綴的 UUID)。
    • messageId 是你要加上反應之訊息的 Signal 時間戳記。
    • 群組反應需要 targetAuthortargetAuthorUuid
    text
    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=truemessage action=react channel=signal target=signal:group:<groupId> targetAuthor=uuid:<sender-uuid> messageId=1737630212345 emoji=✅

    設定:

    • channels.signal.actions.reactions:啟用/停用反應動作(預設 true)。
    • channels.signal.reactionLeveloff | ack | minimal | extensive(預設 minimal)。
      • off/ack 會停用代理程式反應(訊息工具 react 會發生錯誤)。
      • minimal/extensive 會啟用代理程式反應並設定指引層級。
    • 個別帳號覆寫:channels.signal.accounts.<id>.actions.reactionschannels.signal.accounts.<id>.reactionLevel

    核准反應

    Signal 執行與外掛核准提示使用頂層 approvals.execapprovals.plugin 路由區塊。Signal 沒有 channels.signal.execApprovals 區塊。

    • 👍 核准一次。
    • 👎 拒絕。
    • 當請求提供永久核准選項時,使用 /approve <id> allow-always

    核准反應解析需要來自 channels.signal.allowFromchannels.signal.defaultTo 或相符帳號層級欄位的明確 Signal 核准者。直接在相同聊天中顯示的執行核准提示,即使沒有明確核准者,仍可抑制重複的本機 /approve 備援;沒有核准者的群組核准會讓本機備援保持顯示。

    問題反應

    對於包含一個非機密、單選問題及一至四個選項的 ask_user 提示,Signal 會在選項標籤旁顯示 1️⃣4️⃣。使用相符的數字對已傳送的提示加上反應,即可作答。OpenClaw 會驗證反應的目標是機器人撰寫的訊息,然後透過閘道將數字對應至標準選項。過期或重複的點選會被忽略。多問題、多選和自由文字提示仍只能以文字回覆;一般 Signal 私訊/群組准入規則會授權傳送者。

    傳送目標(命令列介面/排程)

    • 私訊:signal:+15551234567(或純 E.164)。
    • UUID 私訊:uuid:<id>(或不含前綴的 UUID)。
    • 群組:signal:group:<groupId>
    • 使用者名稱:username:<name>(若你的 Signal 帳號支援)。

    別名

    為經常使用的 Signal 目標設定穩定名稱的別名。別名僅為 OpenClaw 端的設定;不會建立或編輯 Signal 聯絡人。

    json5
    {  channels: {    signal: {      aliases: {        me: "+15557654321",        jane: "uuid:123e4567-e89b-12d3-a456-426614174000",        ops: "group:<groupId>",      },      defaultTo: "signal:me",    },  },}

    可在任何接受 Signal 傳送目標的位置使用別名:

    bash
    openclaw message send --channel signal --target signal:ops --message "Deployment is complete"

    個別帳號別名會繼承頂層別名,並可新增或覆寫名稱:

    json5
    {  channels: {    signal: {      aliases: {        me: "+15557654321",      },      accounts: {        work: {          aliases: {            ops: "group:<workGroupId>",          },        },      },    },  },}

    openclaw directory peers list --channel signalopenclaw directory groups list --channel signal 會列出已設定的別名。Signal 目錄由設定支援;不會即時查詢 Signal 聯絡人,也不會修改 Signal 帳號。

    疑難排解

    請先依序執行:

    bash
    openclaw statusopenclaw gateway statusopenclaw logs --followopenclaw doctoropenclaw channels status --probe

    接著視需要確認私訊配對狀態:

    bash
    openclaw pairing list signal

    常見失敗情況:

    • 可連線至常駐程式但沒有回覆:請驗證 accounttransport.kind、傳輸 URL 和接收模式。
    • 私訊遭忽略:傳送者正在等待配對核准。
    • 群組訊息遭忽略:群組傳送者/提及閘控阻擋了傳送。
    • 編輯後發生設定驗證錯誤:執行 openclaw doctor --fix
    • 診斷中缺少 Signal:確認 channels.signal.enabled: true

    額外檢查:

    bash
    openclaw pairing list signalpgrep -af signal-cliopenclaw logs --plain --limit 500 | grep -i "signal" | tail -20

    分流流程請參閱:頻道疑難排解

    安全性注意事項

    • signal-cli 會將帳號金鑰儲存在本機(通常為 ~/.local/share/signal-cli/data/)。
    • 移轉或重建伺服器前,請備份 Signal 帳號狀態。
    • 除非明確需要更廣泛的私訊存取權,否則請保留 channels.signal.dmPolicy: "pairing"
    • 只有註冊或復原流程需要 SMS 驗證,但失去對號碼/帳號的控制權可能會增加重新註冊的難度。

    設定參考(Signal)

    完整設定:設定

    提供者選項:

    • channels.signal.enabled:啟用/停用頻道啟動。
    • channels.signal.account:機器人帳號的 E.164。
    • channels.signal.accountUuid:選用的機器人帳號 UUID,用於原生 @提及偵測與迴圈防護。
    • channels.signal.transport:帳號自有的傳輸層。使用受管理的原生預設值時請省略。
    • channels.signal.transport.kindmanaged-native | external-native | container
    • channels.signal.transport.urlexternal-nativecontainer 必須設定;若 managed-native 的連線端點與常駐程式繫結不同,則可選擇設定。
    • channels.signal.transport.cliPath:受管理原生模式中指向 signal-cli 的路徑。
    • channels.signal.transport.configPath:選用的受管理原生 signal-cli --config 目錄。
    • channels.signal.transport.httpHostchannels.signal.transport.httpPort:受管理原生常駐程式繫結(預設為 127.0.0.1:8080)。
    • channels.signal.transport.startupTimeoutMs:受管理原生模式的啟動等待時間(毫秒)(下限 1000,上限 120000;預設 30000)。
    • channels.signal.transport.receiveMode:受管理原生 on-start | manual
    • channels.signal.ignoreAttachments:略過此帳號的傳入附件下載。
    • channels.signal.transport.ignoreStories:受管理原生限時動態開關。
    • channels.signal.sendReadReceipts:轉送已讀回條。
    • channels.signal.dmPolicypairing | allowlist | open | disabled(預設:配對)。
    • channels.signal.allowFrom:私訊允許清單(E.164 或 uuid:<id>)。open 需要 "*"。Signal 沒有使用者名稱;請使用電話號碼/UUID ID。
    • channels.signal.aliases:OpenClaw 端的私訊或群組傳送目標別名。
    • channels.signal.groupPolicyopen | allowlist | disabled(預設:允許清單)。
    • channels.signal.groupAllowFrom:群組允許清單;接受 Signal 群組 ID(原始格式、group:<id>signal:group:<id>)、傳送者的 E.164 號碼或 uuid:<id> 值。
    • channels.signal.groups:以 Signal 群組 ID(或 "*")為鍵的個別群組覆寫。支援的欄位:requireMentiontoolstoolsBySender
    • channels.signal.accounts.<id>.groups:用於多帳號設定的 channels.signal.groups 個別帳號版本。
    • channels.signal.accounts.<id>.aliases:個別帳號的別名,會與頂層別名合併。
    • channels.signal.replyToMode:原生回覆引用模式,off | first | all | batched(預設:all)。
    • channels.signal.replyToModeByChatType.directchannels.signal.replyToModeByChatType.group:依聊天類型設定的原生回覆引用覆寫。
    • channels.signal.accounts.<id>.replyToModechannels.signal.accounts.<id>.replyToModeByChatType.directchannels.signal.accounts.<id>.replyToModeByChatType.group:個別帳號的回覆引用覆寫。
    • channels.signal.historyLimit:要納入情境的群組訊息數量上限(0 表示停用)。
    • channels.signal.dmHistoryLimit:以使用者輪次計算的私訊歷史記錄上限。個別使用者覆寫:channels.signal.dms["<phone_or_uuid>"].historyLimit
    • channels.signal.textChunkLimit:以字元數計算的傳出分段大小(預設 4000)。
    • channels.signal.streaming.chunkModelength(預設),或使用 newline,先依空白行(段落邊界)分割,再依長度分段。
    • channels.signal.mediaMaxMb:傳入/傳出媒體大小上限(MB)(預設 8)。
    • channels.signal.reactionLeveloff | ack | minimal | extensive(預設為 minimal)。請參閱表情回應
    • channels.signal.reactionNotificationsoff | own | all | allowlist(預設為 own)— 代理何時會收到其他人傳入表情回應的通知。
    • channels.signal.reactionAllowlist:當 reactionNotifications: "allowlist" 時,其表情回應會通知代理的傳送者。
    • channels.signal.streaming.block.enabledchannels.signal.streaming.block.coalesce:各頻道共用的區塊模式串流控制項。請參閱串流

    相關全域選項:

    • agents.entries.*.groupChat.mentionPatterns(純文字備援;設定機器人帳號身分後,會從結構化中繼資料偵測 Signal 原生 @提及)。
    • messages.groupChat.mentionPatterns(全域備援)。
    • channels.signal.responsePrefix 或帳號層級的 responsePrefix

    相關內容

    Was this useful?
    On this page

    On this page