@openclaw/signal)です。Gateway は HTTP 経由で signal-cli と通信します。ネイティブデーモン(JSON-RPC + SSE)または bbernhard/signal-cli-rest-api コンテナ(REST + WebSocket)のいずれかを使用します。OpenClaw は libsignal を組み込みません。
番号モデル(最初にお読みください)
- Gateway は Signal デバイス、つまり
signal-cliアカウントに接続します。 - ボットを個人用の Signal アカウントで実行すると、ループ防止のため自分自身のメッセージは無視されます。
- 「ボットにメッセージを送ると返信される」ようにするには、ボット専用の別番号を使用してください。
インストール
openclaw plugins install clawhub:@openclaw/signal または npm:@openclaw/signal でソースを指定できます。plugins install によって Plugin が登録され、有効化されるため、別途 enable を実行する必要はありません。一般的なインストール規則については、Pluginを参照してください。
クイックセットアップ
1
番号を選択
ボットには別の Signal 番号を使用してください(推奨)。
2
Plugin をインストール
3
ガイド付きセットアップを実行
signal-cli が PATH に存在するかを検出し、存在しない場合はインストールを提案します。Linux x86-64 では公式のネイティブ GraalVM ビルドをダウンロードし、macOS およびその他のアーキテクチャでは Homebrew 経由でインストールします。その後、ボット番号と signal-cli のパスを入力するよう求めます。非対話型セットアップでは、openclaw channels add --channel signal はボットの電話番号を指定する --signal-number <e164> に加え、Signal デーモンのエンドポイント(デフォルトは 127.0.0.1:8080)を指定する --http-host <host> と --http-port <port> も受け付けます。4
5
検証してペアリング
openclaw pairing approve signal <CODE>。
複数アカウントのサポート:アカウントごとの設定と任意の
name を含む channels.signal.accounts を使用します。名前付きアカウントはそれぞれ固有の transport を所有し、トップレベルのトランスポートを継承しません。トップレベルのトランスポートは、暗黙の default アカウントだけに属します。共通パターンについては、複数アカウントのチャンネルを参照してください。
概要
- 決定的なルーティング:返信は常に Signal に返されます。
- DM はエージェントのメインセッションを共有し、グループは分離されます(
agent:<agentId>:signal:group:<groupId>)。 - デフォルトでは、Signal は
/config set|unsetによってトリガーされた設定更新を書き込む場合があります(commands.config: trueが必要です)。channels.signal.configWrites: falseで無効化できます。
セットアップパス A:既存の Signal アカウントをリンク(QR)
signal-cli(JVM またはネイティブビルド)をインストールするか、openclaw channels addにインストールさせます。- ボットアカウントをリンクします:
signal-cli link -n "OpenClaw"を実行し、Signal で QR をスキャンします。 - Signal を設定し、Gateway を起動します。
セットアップパス B:ボット専用番号を登録(SMS、Linux)
既存の Signal アプリアカウントをリンクする代わりに、ボット専用番号を使用する場合にこの手順を使用します。以下のフローは Ubuntu 24 でテスト済みです。- SMS(固定電話の場合は音声認証)を受信できる番号を用意します。ボット専用番号を使用すると、アカウントやセッションの競合を回避できます。
- Gateway ホストに
signal-cliをインストールします:
signal-cli-${VERSION}.tar.gz)を使用する場合は、先に JRE をインストールしてください。signal-cli は常に最新の状態に保ってください。Signal サーバー API の変更により、古いリリースが動作しなくなる可能性があるとアップストリームで説明されています。
- 番号を登録して認証します:
https://signalcaptchas.org/registration/generate.htmlを開きます。- captcha を完了し、「Open Signal」から
signalcaptcha://...リンクのターゲットをコピーします。 - 可能であれば、ブラウザセッションと同じ外部 IP から実行してください(captcha トークンはすぐに期限切れになります)。
- 直ちに登録して認証します:
- OpenClaw を設定し、Gateway を再起動して、チャンネルを検証します:
- DM の送信者をペアリングします:
- ボット番号に任意のメッセージを送信します。
- サーバーで承認します:
openclaw pairing approve signal <PAIRING_CODE>。 - 「Unknown contact」と表示されないように、ボット番号をスマートフォンの連絡先に保存します。
signal-cliREADME:https://github.com/AsamK/signal-cli- Captcha フロー:
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 が接続するように指定します:
非対話型セットアップでは、必要に応じてエンドポイントの種類を明示的に選択します:
channels.signal.transport.startupTimeoutMs を設定してください。
コンテナモード(bbernhard/signal-cli-rest-api)
signal-cli をネイティブで実行する代わりに、signal-cli を REST + WebSocket インターフェースでラップする bbernhard/signal-cli-rest-api Docker コンテナを使用します。
- リアルタイムでメッセージを受信するには、コンテナを
MODE=json-rpcで実行する必要があります。 - OpenClaw に接続する前に、コンテナ内で Signal アカウントを登録またはリンクしてください。
docker-compose.yml サービスの例:
transport.kind は、OpenClaw が使用するプロトコルとプロセスのライフサイクルを制御します:
セットアップと
openclaw doctor --fix では、具体的な種類を識別するために、既存のエンドポイントを一度プローブする場合があります。ランタイム操作では、プロトコルの自動検出や切り替えは行いません。
コンテナモードでは、コンテナが対応する API を公開している場合、ネイティブモードと同じ Signal 操作をサポートします。これには、送信、受信、添付ファイル、入力中インジケーター、既読・閲覧済み通知、リアクション、グループ、スタイル付きテキストが含まれます。OpenClaw は、group.{base64(internal_id)} グループ ID や書式付きテキスト用の text_mode: "styled" を含め、ネイティブ Signal RPC 呼び出しをコンテナの REST ペイロードに変換します。
運用上の注意:
- 受信には
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を送信する場合、サイズ超過のレスポンスは完全にバッファリングされる前に拒否され、それ以外の場合はストリーミング中に拒否されます。
アクセス制御(DM + グループ)
DM:- デフォルト:
channels.signal.dmPolicy = "pairing"。 - 不明な送信者にはペアリングコードが送られ、承認されるまでメッセージは無視されます(コードは 1 時間後に期限切れになります)。
openclaw pairing list signalとopenclaw pairing approve signal <CODE>を使用して承認します。- ペアリングは Signal DM のデフォルトのトークン交換方式です。詳細:ペアリング
- UUID のみの送信者(
sourceUuid由来)は、channels.signal.allowFromにuuid:<id>として保存されます。
channels.signal.groupPolicy = open | allowlist | disabled。channels.signal.groupAllowFromは、allowlistが設定されている場合に、グループ返信をトリガーできるグループまたは送信者を制御します。エントリには、Signal グループ ID(raw、group:<id>、またはsignal:group:<id>)、送信者の電話番号、uuid:<id>の値、または*を指定できます。channels.signal.groups["<group-id>" | "*"]では、requireMention、tools、およびtoolsBySenderを使用してグループの動作を上書きできます。- マルチアカウント構成でアカウントごとに上書きするには、
channels.signal.accounts.<id>.groupsを使用します。 groupAllowFromを通じて Signal グループを許可リストに追加しても、それだけではメンション制限は無効になりません。明示的に設定されたchannels.signal.groups["<group-id>"]エントリは、requireMention=trueが設定されていない限り、すべてのグループメッセージを処理します。requireMention=trueを使用すると、Signal ネイティブの @メンションは、構造化されたメンションメタデータからボットアカウントの電話番号またはaccountUuidと照合されます。設定されたmentionPatternsは、プレーンテキストのフォールバックとして残ります。- ランタイムに関する注意:
channels.signalが完全に欠落している場合、ランタイムはグループチェックにgroupPolicy="allowlist"をフォールバックとして使用します(channels.defaults.groupPolicyが設定されている場合でも同様です)。
仕組み(動作)
- ネイティブモード:
signal-cliはデーモンとして実行され、Gateway は SSE 経由でイベントを読み取ります。 - コンテナモード: Gateway は 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 は許可された DM の既読通知を転送します。 signal-cliはグループの既読通知を公開しません。
ライフサイクルステータスのリアクション
受信ターンで、共有のキュー待ち/思考中/ツール/Compaction/完了/エラーのリアクションライフサイクルを Signal に表示させるには、messages.statusReactions.enabled: true を設定します。Signal は受信メッセージのタイムスタンプをリアクション対象として使用します。グループリアクションは、Signal グループ ID と元の送信者を対象作成者として指定して送信されます。
ステータスリアクションには、確認リアクションと、一致する messages.ackReactionScope(direct、group-all、group-mentions、または all)も必要です。Signal のステータスリアクションを無効にするには、channels.signal.reactionLevel: "off" を設定します。
Signal は、最終的な完了/エラー状態の後に最初の確認リアクションを復元します。
リアクション(メッセージツール)
message action=react を channel=signal とともに使用します。
- 対象: 送信者の E.164 または UUID(ペアリング出力の
uuid:<id>を使用します。プレフィックスなしの UUID も使用できます)。 messageIdは、リアクション対象メッセージの Signal タイムスタンプです。- グループリアクションには
targetAuthorまたはtargetAuthorUuidが必要です。
channels.signal.actions.reactions: リアクションアクションを有効化/無効化します(デフォルトは true)。channels.signal.reactionLevel:off | ack | minimal | extensive(デフォルトはminimal)。off/ackはエージェントのリアクションを無効にします(メッセージツールのreactはエラーになります)。minimal/extensiveはエージェントのリアクションを有効にし、ガイダンスレベルを設定します。
- アカウントごとの上書き:
channels.signal.accounts.<id>.actions.reactions、channels.signal.accounts.<id>.reactionLevel。
承認リアクション
Signal の exec および Plugin 承認プロンプトは、トップレベルのapprovals.exec および approvals.plugin ルーティングブロックを使用します。Signal には channels.signal.execApprovals ブロックはありません。
👍は一度だけ承認します。👎は拒否します。- リクエストに永続的な承認の選択肢がある場合は、
/approve <id> allow-alwaysを使用します。
channels.signal.allowFrom、channels.signal.defaultTo、または一致するアカウントレベルのフィールドで明示的に指定された Signal 承認者が必要です。同じチャット内での直接的な exec 承認プロンプトでは、明示的な承認者がいなくても、重複するローカルの /approve フォールバックを非表示にできます。承認者がいないグループ承認では、ローカルフォールバックが引き続き表示されます。
質問リアクション
秘密ではない単一選択式の質問が 1 件、選択肢が 1~4 件あるask_user プロンプトでは、Signal は選択肢ラベルの横に 1️⃣ から 4️⃣ を表示します。配信されたプロンプトに対応する数字でリアクションすると回答できます。OpenClaw は、リアクションがボットによって作成されたメッセージを対象としていることを検証し、その数字を Gateway 経由で正規の選択肢にマッピングします。古いタップや重複したタップは無視されます。複数質問、複数選択、および自由記述のプロンプトは、引き続きテキスト返信のみで回答できます。通常の Signal の DM/グループ受け入れルールにより送信者が認可されます。
配信先(CLI/Cron)
- DM:
signal:+15551234567(またはプレフィックスなしの E.164)。 - UUID DM:
uuid:<id>(またはプレフィックスなしの UUID)。 - グループ:
signal:group:<groupId>。 - ユーザー名:
username:<name>(使用している Signal アカウントでサポートされている場合)。
エイリアス
繰り返し使用する Signal の配信先に、安定した名前のエイリアスを設定します。エイリアスは OpenClaw 側の設定にすぎず、Signal の連絡先を作成または編集するものではありません。openclaw directory peers list --channel signal および openclaw directory groups list --channel signal は、設定済みのエイリアスを一覧表示します。Signal ディレクトリは設定を基盤としており、Signal の連絡先をリアルタイムで照会したり、Signal アカウントを変更したりすることはありません。
トラブルシューティング
まず次の手順を実行します。- デーモンに到達できるが返信がない:
account、transport.kind、トランスポート URL、および受信モードを確認してください。 - DM が無視される: 送信者のペアリング承認が保留中です。
- グループメッセージが無視される: グループ送信者またはメンションの制限によって配信がブロックされています。
- 編集後に設定検証エラーが発生する:
openclaw doctor --fixを実行してください。 - 診断に Signal が表示されない:
channels.signal.enabled: trueを確認してください。
セキュリティに関する注意事項
signal-cliはアカウントキーをローカルに保存します(通常は~/.local/share/signal-cli/data/)。- サーバーを移行または再構築する前に、Signal アカウントの状態をバックアップしてください。
- DM へのアクセス範囲を明示的に広げる場合を除き、
channels.signal.dmPolicy: "pairing"を維持してください。 - SMS 認証が必要なのは登録または復旧フローのみですが、番号やアカウントの制御を失うと、再登録が複雑になる可能性があります。
設定リファレンス(Signal)
完全な設定: 設定 プロバイダーオプション:channels.signal.enabled: チャネルの起動を有効化/無効化します。channels.signal.account: ボットアカウントの E.164。channels.signal.accountUuid: ネイティブな @メンション検出とループ防止に使用する、任意のボットアカウント UUID。channels.signal.transport: アカウント所有のトランスポート。管理対象のネイティブデフォルトを使用する場合は省略します。channels.signal.transport.kind:managed-native | external-native | container。channels.signal.transport.url:external-nativeとcontainerでは必須です。接続エンドポイントがデーモンのバインド先と異なる場合、managed-nativeでは任意です。channels.signal.transport.cliPath:signal-cliへの管理対象ネイティブパス。channels.signal.transport.configPath: 任意の管理対象ネイティブsignal-cli --configディレクトリ。channels.signal.transport.httpHost,channels.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.dmPolicy:pairing | allowlist | open | disabled(デフォルト: ペアリング)。channels.signal.allowFrom: DM 許可リスト(E.164 またはuuid:<id>)。openには"*"が必要です。Signal にはユーザー名がないため、電話番号/UUID ID を使用してください。channels.signal.aliases: DM またはグループの配信先に対する OpenClaw 側のエイリアス。channels.signal.groupPolicy:open | allowlist | disabled(デフォルト: 許可リスト)。channels.signal.groupAllowFrom: グループ許可リスト。Signal グループ ID(未加工、group:<id>、またはsignal:group:<id>)、送信者の E.164 番号、またはuuid:<id>値を使用できます。channels.signal.groups: Signal グループ ID(または"*")をキーとするグループ単位のオーバーライド。サポートされるフィールド:requireMention、tools、toolsBySender。channels.signal.accounts.<id>.groups: 複数アカウント構成向けの、アカウント単位のchannels.signal.groups。channels.signal.accounts.<id>.aliases: アカウント単位のエイリアス。トップレベルのエイリアスとマージされます。channels.signal.replyToMode: ネイティブ返信の引用モード、off | first | all | batched(デフォルト:all)。channels.signal.replyToModeByChatType.direct,channels.signal.replyToModeByChatType.group: チャット種別ごとのネイティブ返信引用のオーバーライド。channels.signal.accounts.<id>.replyToMode,channels.signal.accounts.<id>.replyToModeByChatType.direct,channels.signal.accounts.<id>.replyToModeByChatType.group: アカウント単位の返信引用のオーバーライド。channels.signal.historyLimit: コンテキストに含めるグループメッセージの最大数(0 で無効化)。channels.signal.dmHistoryLimit: ユーザーターン数で指定する DM 履歴の上限。ユーザー単位のオーバーライド:channels.signal.dms["<phone_or_uuid>"].historyLimit。channels.signal.textChunkLimit: 送信チャンクの文字数(デフォルト 4000)。channels.signal.streaming.chunkMode:length(デフォルト)、または長さに基づくチャンク分割の前に空行(段落の境界)で分割するnewline。channels.signal.mediaMaxMb: 受信/送信メディアの上限(MB、デフォルト 8)。channels.signal.reactionLevel:off | ack | minimal | extensive(デフォルトminimal)。リアクションを参照してください。channels.signal.reactionNotifications:off | own | all | allowlist(デフォルトown)- 他のユーザーからの受信リアクションがエージェントに通知される条件。channels.signal.reactionAllowlist:reactionNotifications: "allowlist"の場合に、リアクションによってエージェントへ通知する送信者。channels.signal.streaming.block.enabled,channels.signal.streaming.block.coalesce: チャネル間で共有されるブロックモードのストリーミング制御。ストリーミングを参照してください。
agents.entries.*.groupChat.mentionPatterns(プレーンテキストのフォールバック。ボットアカウントのアイデンティティが設定されている場合、Signal のネイティブ @メンションは構造化メタデータから検出されます)。messages.groupChat.mentionPatterns(グローバルフォールバック)。channels.signal.responsePrefixまたはアカウントレベルのresponsePrefix。
関連項目
- チャネルの概要 - サポートされているすべてのチャネル
- ペアリング - DM 認証とペアリングの流れ
- グループ - グループチャットの動作とメンションによる制御
- チャネルルーティング - メッセージのセッションルーティング
- セキュリティ - アクセスモデルと堅牢化