Signal(signal-cli)
ステータス: 外部CLI統合。GatewayはHTTP JSON-RPC + SSE経由でsignal-cliと通信します。
前提条件
- サーバーにOpenClawがインストールされていること(以下のLinuxフローはUbuntu 24でテスト済み)。
- Gatewayを実行するホストで
signal-cliが利用可能であること。 - 1回の認証SMSを受信できる電話番号(SMS登録経路の場合)。
- 登録時にSignal captcha(
signalcaptchas.org)へアクセスするためのブラウザー。
クイックセットアップ(初級者向け)
- botには別のSignal番号を使用します(推奨)。
signal-cliをインストールします(JVMビルドを使う場合はJavaが必要です)。- セットアップ経路を1つ選びます。
- 経路A(QRリンク):
signal-cli link -n "OpenClaw"を実行し、Signalでスキャンします。 - 経路B(SMS登録): captcha + SMS認証で専用番号を登録します。
- 経路A(QRリンク):
- OpenClawを設定してGatewayを再起動します。
- 最初のDMを送信し、pairingを承認します(
openclaw pairing approve signal <CODE>)。
| フィールド | 説明 |
|---|---|
account | E.164形式のbot電話番号(+15551234567) |
cliPath | signal-cliへのパス(PATH上にあるならsignal-cli) |
dmPolicy | DMアクセス方針(pairing推奨) |
allowFrom | DMを許可する電話番号またはuuid:<id>値 |
これは何か
signal-cli経由のSignalチャンネルです(埋め込みlibsignalではありません)。- 決定的なルーティング: 返信は常にSignalへ戻ります。
- DMはagentのメインセッションを共有し、グループは分離されます(
agent:<agentId>:signal:group:<groupId>)。
config書き込み
デフォルトでは、Signalは/config set|unsetによってトリガーされたconfig更新の書き込みを許可されています(commands.config: trueが必要)。
無効化するには次を使用します。
番号モデル(重要)
- GatewayはSignalデバイス(
signal-cliアカウント)に接続します。 - botを個人のSignalアカウントで実行すると、自分自身のメッセージは無視されます(ループ保護)。
- 「自分がbotにテキストを送り、botが返信する」動作にするには、別のbot番号を使用してください。
セットアップ経路A: 既存のSignalアカウントをリンクする(QR)
signal-cliをインストールします(JVMまたはネイティブビルド)。- botアカウントをリンクします。
signal-cli link -n "OpenClaw"を実行し、SignalでQRをスキャンします。
- Signalを設定してGatewayを起動します。
channels.signal.accountsを使用すると、アカウントごとのconfigと任意のnameを設定できます。共有パターンについてはgateway/configurationを参照してください。
セットアップ経路B: 専用のbot番号を登録する(SMS、Linux)
既存のSignalアプリのアカウントをリンクする代わりに、専用のbot番号を使いたい場合はこちらを使用します。- SMSを受信できる番号を用意します(固定電話の場合は音声認証でも可)。
- アカウントやセッションの競合を避けるため、専用のbot番号を使用してください。
- Gatewayホストに
signal-cliをインストールします。
signal-cli-${VERSION}.tar.gz)を使用する場合は、最初にJRE 25+をインストールしてください。
signal-cliは最新の状態に保ってください。上流では、SignalサーバーAPIの変更により古いリリースが動作しなくなる可能性があると案内しています。
- 番号を登録して認証します。
https://signalcaptchas.org/registration/generate.htmlを開きます。- captchaを完了し、「Open Signal」から
signalcaptcha://...リンク先をコピーします。 - 可能であれば、ブラウザーセッションと同じ外部IPから実行してください。
- すぐに再度登録を実行します(captchaトークンはすぐに期限切れになります)。
- OpenClawを設定し、Gatewayを再起動して、チャンネルを確認します。
- DM送信者をpairingします。
- bot番号に何らかのメッセージを送信します。
- サーバー上でコードを承認します:
openclaw pairing approve signal <PAIRING_CODE>。 - 「Unknown contact」を避けるため、bot番号を電話の連絡先に保存します。
signal-cliで電話番号アカウントを登録すると、その番号のメインSignalアプリセッションが認証解除される場合があります。専用のbot番号を推奨します。既存の電話アプリ構成を維持する必要がある場合は、QRリンクモードを使用してください。
上流リファレンス:
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)
外部デーモンモード(httpUrl)
signal-cliを自分で管理したい場合(JVMのコールドスタートが遅い、コンテナー初期化、共有CPUなど)、デーモンを別に実行してOpenClawからそこを参照します。
channels.signal.startupTimeoutMsを設定してください。
アクセス制御(DM + グループ)
DM:- デフォルト:
channels.signal.dmPolicy = "pairing"。 - 未知の送信者にはpairingコードが送られ、承認されるまでメッセージは無視されます(コードは1時間で期限切れ)。
- 承認方法:
openclaw pairing list signalopenclaw pairing approve signal <CODE>
- PairingはSignal DMのデフォルトのトークン交換です。詳細: Pairing
- UUIDのみの送信者(
sourceUuid由来)は、channels.signal.allowFromにuuid:<id>として保存されます。
channels.signal.groupPolicy = open | allowlist | disabled。channels.signal.groupAllowFromは、allowlist設定時にグループ内で誰がトリガーできるかを制御します。channels.signal.groups["<group-id>" | "*"]では、requireMention、tools、toolsBySenderを使ってグループ動作を上書きできます。- マルチアカウント構成では、アカウントごとの上書きに
channels.signal.accounts.<id>.groupsを使用します。 - ランタイム注記:
channels.signalが完全に欠けている場合、ランタイムはグループチェックでgroupPolicy="allowlist"にフォールバックします(channels.defaults.groupPolicyが設定されていても同様です)。
仕組み(動作)
signal-cliはデーモンとして動作し、GatewayはSSE経由でイベントを読み取ります。- 受信メッセージは共有チャンネルエンベロープに正規化されます。
- 返信は常に同じ番号またはグループにルーティングされます。
メディア + 制限
- 送信テキストは
channels.signal.textChunkLimit(デフォルト4000)に分割されます。 - 任意の改行チャンク化:
channels.signal.chunkMode="newline"を設定すると、長さで分割する前に空行(段落境界)で分割します。 - 添付ファイルをサポートします(
signal-cliから取得したbase64)。 - デフォルトのメディア上限:
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はグループの既読通知を公開していません。
リアクション(messageツール)
channel=signalでmessage action=reactを使用します。- ターゲット: 送信者のE.164またはUUID(pairing出力の
uuid:<id>を使用します。UUID単体でも動作します)。 messageIdは、リアクション対象メッセージのSignalタイムスタンプです。- グループリアクションでは
targetAuthorまたはtargetAuthorUuidが必要です。
channels.signal.actions.reactions: リアクションアクションの有効化/無効化(デフォルトtrue)。channels.signal.reactionLevel:off | ack | minimal | extensive。off/ackではagentリアクションが無効になります(messageツールのreactはエラーになります)。minimal/extensiveではagentリアクションが有効になり、ガイダンスレベルが設定されます。
- アカウントごとの上書き:
channels.signal.accounts.<id>.actions.reactions、channels.signal.accounts.<id>.reactionLevel。
配信ターゲット(CLI/cron)
- DM:
signal:+15551234567(またはプレーンなE.164)。 - UUID DM:
uuid:<id>(またはUUID単体)。 - グループ:
signal:group:<groupId>。 - ユーザー名:
username:<name>(Signalアカウントでサポートされている場合)。
トラブルシューティング
まず次の手順を実行してください。- デーモンには到達できるが返信がない: アカウント/デーモン設定(
httpUrl、account)と受信モードを確認してください。 - DMが無視される: 送信者のpairing承認待ちです。
- グループメッセージが無視される: グループ送信者/mentionゲーティングが配信をブロックしています。
- 編集後にconfig検証エラーが出る:
openclaw doctor --fixを実行してください。 - 診断にSignalが表示されない:
channels.signal.enabled: trueを確認してください。
セキュリティに関する注意
signal-cliはアカウントキーをローカルに保存します(通常は~/.local/share/signal-cli/data/)。- サーバー移行や再構築の前にSignalアカウント状態をバックアップしてください。
- より広いDMアクセスを明示的に望まない限り、
channels.signal.dmPolicy: "pairing"を維持してください。 - SMS認証は登録またはリカバリーフローでのみ必要ですが、番号/アカウントの制御を失うと再登録が複雑になる場合があります。
設定リファレンス(Signal)
完全な設定: Configuration プロバイダーオプション:channels.signal.enabled: チャンネル起動の有効化/無効化。channels.signal.account: botアカウント用のE.164。channels.signal.cliPath:signal-cliへのパス。channels.signal.httpUrl: 完全なデーモンURL(host/portより優先)。channels.signal.httpHost,channels.signal.httpPort: デーモンのbind先(デフォルト127.0.0.1:8080)。channels.signal.autoStart: デーモンを自動起動(httpUrl未設定時のデフォルトはtrue)。channels.signal.startupTimeoutMs: 起動待機タイムアウト(ms、上限120000)。channels.signal.receiveMode:on-start | manual。channels.signal.ignoreAttachments: 添付ファイルのダウンロードをスキップ。channels.signal.ignoreStories: デーモンからのストーリーを無視。channels.signal.sendReadReceipts: 既読通知を転送。channels.signal.dmPolicy:pairing | allowlist | open | disabled(デフォルト: pairing)。channels.signal.allowFrom: DM allowlist(E.164またはuuid:<id>)。openには"*"が必要です。Signalにはユーザー名がないため、電話番号/UUID IDを使用してください。channels.signal.groupPolicy:open | allowlist | disabled(デフォルト: allowlist)。channels.signal.groupAllowFrom: グループ送信者allowlist。channels.signal.groups: SignalグループID(または"*")をキーにしたグループごとの上書き。サポートフィールド:requireMention、tools、toolsBySender。channels.signal.accounts.<id>.groups: マルチアカウント構成向けのchannels.signal.groupsのアカウント別版。channels.signal.historyLimit: コンテキストに含めるグループメッセージの最大数(0で無効)。channels.signal.dmHistoryLimit: ユーザーターン単位のDM履歴上限。ユーザー単位の上書き:channels.signal.dms["<phone_or_uuid>"].historyLimit。channels.signal.textChunkLimit: 送信チャンクサイズ(文字数)。channels.signal.chunkMode:length(デフォルト)またはnewline。長さで分割する前に空行(段落境界)で分割します。channels.signal.mediaMaxMb: 受信/送信メディア上限(MB)。
agents.list[].groupChat.mentionPatterns(Signalはネイティブmentionをサポートしません)。messages.groupChat.mentionPatterns(グローバルフォールバック)。messages.responsePrefix。
関連
- Channels Overview — サポートされているすべてのチャンネル
- Pairing — DM認証とpairingフロー
- Groups — グループチャットの動作とmentionゲーティング
- Channel Routing — メッセージのセッションルーティング
- Security — アクセスモデルとハードニング