Signal(signal-cli)
ステータス:外部CLI統合。ゲートウェイはHTTP JSON-RPC + SSE経由で signal-cli と通信します。
前提条件
- OpenClawがサーバーにインストールされていること(以下のLinuxフローはUbuntu 24でテスト済み)。
- ゲートウェイが動作するホストで
signal-cliが利用可能であること。 - SMS登録パスで確認SMSを1通受信できる電話番号。
- 登録時の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を設定し、ゲートウェイを再起動します。
- 最初のDMを送信し、ペアリングを承認します(
openclaw pairing approve signal <CODE>)。
最小設定:
{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}
フィールドリファレンス:
| フィールド | 説明 |
|---|---|
account | E.164形式のBot電話番号(+15551234567) |
cliPath | signal-cli のパス(PATH 上にあれば signal-cli) |
dmPolicy | DMアクセスポリシー(pairing 推奨) |
allowFrom | DMを許可する電話番号または uuid:<id> 値 |
signal-cliとは
signal-cli経由のSignalチャンネル(組み込みlibsignalではありません)。- 決定論的ルーティング:返信は常にSignalに戻ります。
- DMはエージェントのメインセッションを共有し、グループは分離されます(
agent:<agentId>:signal:group:<groupId>)。
設定書き込み
デフォルトでは、Signalは /config set|unset によってトリガーされる設定更新の書き込みが許可されています(commands.config: true が必要)。
以下で無効化できます:
{
channels: { signal: { configWrites: false } },
}
番号モデル(重要)
- ゲートウェイはSignalデバイス(
signal-cliアカウント)に接続します。 - 個人のSignalアカウントでBotを実行する場合、自分自身のメッセージは無視されます(ループ防止)。
- 「Botにテキストして返信をもらう」には、専用のBot番号を使用してください。
セットアップパスA:既存のSignalアカウントをリンク(QR)
signal-cliをインストールします(JVMまたはネイティブビルド)。- Botアカウントをリンクします:
signal-cli link -n "OpenClaw"を実行し、SignalでQRをスキャンします。
- Signalを設定してゲートウェイを起動します。
例:
{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}
マルチアカウントサポート:アカウントごとの設定とオプションの name を使用して channels.signal.accounts を設定します。共有パターンについてはgateway/configurationを参照してください。
セットアップパスB:専用Bot番号を登録(SMS、Linux)
既存のSignalアプリアカウントをリンクするのではなく、専用のBot番号が必要な場合に使用します。
- SMSを受信できる番号を取得します(固定電話の場合は音声認証)。
- アカウント/セッションの競合を避けるため、専用のBot番号を使用してください。
- ゲートウェイホストに
signal-cliをインストールします:
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 /opt
sudo ln -sf /opt/signal-cli /usr/local/bin/
signal-cli --version
JVMビルド(signal-cli-${VERSION}.tar.gz)を使用する場合は、まずJRE 25+をインストールしてください。
Signal サーバーAPIの変更により古いリリースが破損する可能性があるため、signal-cli を最新に保ってください。
- 番号を登録して認証します:
signal-cli -a +<BOT_PHONE_NUMBER> register
captchaが必要な場合:
https://signalcaptchas.org/registration/generate.htmlを開きます。- captchaを完了し、「Open Signal」から
signalcaptcha://...リンクターゲットをコピーします。 - 可能であれば、ブラウザセッションと同じ外部IPから実行します。
- 登録を直ちに再実行します(captchaトークンはすぐに期限切れになります):
signal-cli -a +<BOT_PHONE_NUMBER> register --captcha '<SIGNALCAPTCHA_URL>'
signal-cli -a +<BOT_PHONE_NUMBER> verify <VERIFICATION_CODE>
- OpenClawを設定し、ゲートウェイを再起動して、チャンネルを確認します:
# ゲートウェイをユーザーsystemdサービスとして実行している場合:
systemctl --user restart openclaw-gateway
# 確認:
openclaw doctor
openclaw channels status --probe
- DM送信者をペアリングします:
- Bot番号にメッセージを送信します。
- サーバーでコードを承認します:
openclaw pairing approve signal <PAIRING_CODE>。 - 「不明な連絡先」を避けるため、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: {
httpUrl: "http://127.0.0.1:8080",
autoStart: false,
},
},
}
これにより、自動起動とOpenClaw内の起動待機がスキップされます。自動起動時のスタートが遅い場合は、channels.signal.startupTimeoutMs を設定してください。
アクセス制御(DM + グループ)
DM:
- デフォルト:
channels.signal.dmPolicy = "pairing"。 - 不明な送信者にはペアリングコードが送られます。承認されるまでメッセージは無視されます(コードは1時間後に期限切れ)。
- 以下の方法で承認します:
openclaw pairing list signalopenclaw pairing approve signal <CODE>
- ペアリングはSignal DMのデフォルトのトークン交換です。詳細:ペアリング
- UUIDのみの送信者(
sourceUuidから)はchannels.signal.allowFromにuuid:<id>として保存されます。
グループ:
channels.signal.groupPolicy = open | allowlist | disabled。allowlistが設定されている場合、channels.signal.groupAllowFromがグループ内でトリガーできる人を制御します。channels.signal.groups["<group-id>" | "*"]でrequireMention、tools、toolsBySenderを使用してグループの動作をオーバーライドできます。- マルチアカウントセットアップでは、
channels.signal.accounts.<id>.groupsでアカウントごとのオーバーライドを使用します。 - ランタイムの注意:
channels.signalが完全に欠落している場合、ランタイムはグループチェックに対してgroupPolicy="allowlist"にフォールバックします(channels.defaults.groupPolicyが設定されていても)。
動作の仕組み
signal-cliはデーモンとして実行され、ゲートウェイは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(ペアリング出力の
uuid:<id>を使用。ベアUUIDも有効)。 messageIdはリアクションするメッセージのSignalタイムスタンプです。- グループリアクションには
targetAuthorまたはtargetAuthorUuidが必要です。
例:
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=✅
設定:
channels.signal.actions.reactions:リアクションアクションの有効/無効(デフォルトtrue)。channels.signal.reactionLevel:off | ack | minimal | extensive。off/ackはエージェントのリアクションを無効にします(messageツールreactはエラーになります)。minimal/extensiveはエージェントのリアクションを有効にし、ガイダンスレベルを設定します。
- アカウントごとのオーバーライド:
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アカウントがサポートしている場合)。
トラブルシューティング
まず以下の手順を実行してください:
openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
openclaw channels status --probe
必要に応じてDMペアリング状態を確認してください:
openclaw pairing list signal
よくある障害:
- デーモンは到達可能だが返信がない:アカウント/デーモンの設定(
httpUrl、account)と受信モードを確認してください。 - DMが無視される:送信者がペアリング承認待ちです。
- グループメッセージが無視される:グループ送信者/メンションゲーティングが配信をブロックしています。
- 編集後の設定バリデーションエラー:
openclaw doctor --fixを実行してください。 - 診断にSignalが表示されない:
channels.signal.enabled: trueを確認してください。
追加のチェック:
openclaw pairing list signal
pgrep -af signal-cli
grep -i "signal" "/tmp/openclaw/openclaw-$(date +%Y-%m-%d).log" | tail -20
トリアージフローについて:/channels/troubleshooting。
セキュリティに関する注意事項
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:デーモンバインド(デフォルト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許可リスト(E.164またはuuid:<id>)。openには"*"が必要です。Signalにはユーザー名がありません。電話/UUID IDを使用してください。channels.signal.groupPolicy:open | allowlist | disabled(デフォルト:allowlist)。channels.signal.groupAllowFrom:グループ送信者の許可リスト。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はネイティブメンションをサポートしていません)。messages.groupChat.mentionPatterns(グローバルフォールバック)。messages.responsePrefix。