コンテンツにスキップ

OpenClawとSignalを連携:signal-cliでボットを構築

Signalを連携させる前に、以下の準備ができているか確認してください。

  • サーバーにOpenClawがインストールされていること(Linuxでの手順はUbuntu 24でテスト済みです)。
  • Gatewayが動作するホストで signal-cli が利用可能なこと。
  • 認証用のSMSを受信できる電話番号(SMS登録パスを使用する場合に必要です)。
  • 登録時のSignalキャプチャ(signalcaptchas.org)を解決するためのブラウザ環境。

クイックセットアップ(初心者向け)

Section titled “クイックセットアップ(初心者向け)”
  1. ボット用には、普段使いのものとは別の専用のSignal番号を用意することをおすすめします。
  2. signal-cli をインストールします(JVMビルドを使用する場合はJavaが必要です)。
  3. 次のいずれかのセットアップ方法を選んでください。
    • 方法A(QRリンク): signal-cli link -n "OpenClaw" を実行し、手元のSignalアプリでQRコードをスキャンします。
    • 方法B(SMS登録): キャプチャ解決とSMS認証を行い、専用の番号を登録します。
  4. OpenClawの設定を行い、Gatewayを再起動します。
  5. 最初のDMを送信し、ペアリングを承認します(openclaw pairing approve signal <CODE>)。

最小限の設定例はこちらです:

{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}

各項目の説明:

項目説明
accountボットの電話番号。E.164形式(+15551234567)で入力します。
cliPathsignal-cli へのパス(PATH が通っている場合は signal-cli)。
dmPolicyDMのアクセス制御ポリシー(pairing を推奨します)。
allowFromDMを許可する電話番号、または uuid:<id> のリスト。

このチャンネルの仕組みと特徴について説明します。

  • このチャンネルは、埋め込みの libsignal ではなく signal-cli を介して動作します。GatewayはHTTP JSON-RPCとSSEを利用して通信を行い、返信が常にSignalへ送り返される確定的なルーティングを採用しています。
  • DMはエージェントのメインセッションを共有しますが、グループチャットは agent:<agentId>:signal:group:<groupId> の形式で個別に分離されて管理されます。

デフォルトでは、Signal経由で /config set|unset コマンドを実行して設定を更新することが許可されています(これには commands.config: true の設定が必要です)。

もしこの機能を無効にしたい場合は、以下のように設定してください。

{
channels: { signal: { configWrites: false } },
}
  • Gateway は Signal デバイス(signal-cli アカウント)に接続します。
  • 個人の Signal アカウントでボットを実行した場合、ループ防止のため自分自身のメッセージは無視されます。
  • 「自分がボットにメッセージを送り、ボットが返信する」という動作をさせたい場合は、別のボット用番号を使用してください。

セットアップ方法 A:既存の Signal アカウントを連携する(QR コード)

Section titled “セットアップ方法 A:既存の Signal アカウントを連携する(QR コード)”
  1. signal-cli(JVM またはネイティブビルド)をインストールします。
  2. ボットアカウントを連携します:
    • signal-cli link -n "OpenClaw" を実行し、Signal アプリで QR コードをスキャンしてください。
  3. Signal を設定し、Gateway を起動します。

例:

{
channels: {
signal: {
enabled: true,
account: "+15551234567",
cliPath: "signal-cli",
dmPolicy: "pairing",
allowFrom: ["+15557654321"],
},
},
}

複数アカウントのサポート:アカウントごとの設定とオプションの name を指定できる channels.signal.accounts を使用してください。共通のパターンについては gateway/configuration を参照してください。

セットアップ方法 B:専用のボット番号を登録する(SMS、Linux)

Section titled “セットアップ方法 B:専用のボット番号を登録する(SMS、Linux)”

既存の Signal アプリのアカウントを連携するのではなく、専用のボット番号を使用したい場合は、この方法を選択してください。

  1. SMS(または固定電話の音声認証)を受信できる番号を用意します。
    • アカウントやセッションの競合を避けるため、専用のボット番号を使用することをおすすめします。
  2. Gateway ホストに signal-cli をインストールします:
Terminal window
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-cli は常に最新の状態に保ってください。Signal サーバーの API 変更に伴い、古いリリースは動作しなくなる可能性があると開発元から案内されています。

  1. 番号の登録と認証を行います:
Terminal window
signal-cli -a +<BOT_PHONE_NUMBER> register

キャプチャが必要な場合:

  1. https://signalcaptchas.org/registration/generate.html を開きます。
  2. キャプチャを完了し、「Open Signal」から signalcaptcha://... で始まるリンク先をコピーします。
  3. 可能な限り、ブラウザセッションと同じ外部 IP からコマンドを実行してください。
  4. キャプチャトークンの期限は短いため、すぐに登録を再実行します:
Terminal window
signal-cli -a +<BOT_PHONE_NUMBER> register --captcha '<SIGNALCAPTCHA_URL>'
signal-cli -a +<BOT_PHONE_NUMBER> verify <VERIFICATION_CODE>
  1. OpenClaw を設定し、Gateway を再起動して、チャンネルを確認します:
Terminal window
# If you run the gateway as a user systemd service:
systemctl --user restart openclaw-gateway
# Then verify:
openclaw doctor
openclaw channels status --probe
  1. DM 送信者のペアリング:
    • ボットの番号に任意のメッセージを送信します。
    • サーバー側でコードを承認します:openclaw pairing approve signal <PAIRING_CODE>。
    • 「不明な連絡先」と表示されないよう、ボットの番号をスマートフォンの連絡先に保存しておきましょう。

重要:signal-cli で電話番号アカウントを登録すると、その番号を使用しているメインの Signal アプリのセッションが解除されることがあります。専用のボット番号を用意するか、既存のスマートフォンの設定を維持したい場合は QR コードによる連携モードを使用してください。

関連リファレンス:

  • 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)

JVM のコールドスタートが遅い場合や、コンテナの初期化、CPU リソースの共有などの理由で signal-cli を自分で管理したい場合は、デーモンを個別に実行して OpenClaw からそこを参照するように設定できます。

{
channels: {
signal: {
httpUrl: "http://127.0.0.1:8080",
autoStart: false,
},
},
}

これにより、OpenClaw 内部での自動起動や起動待ちをスキップできます。自動起動時の起動が遅い場合は、channels.signal.startupTimeoutMs を設定してください。

Signalでのやり取りを安全に保つための設定について解説します。

DM(ダイレクトメッセージ)の場合:

  • デフォルト設定は channels.signal.dmPolicy = "pairing" です。
  • 未知の送信者からはペアリングコードが届きます。承認されるまでメッセージは無視されます(コードの有効期限は1時間です)。
  • 承認するには以下のコマンドを使用します:
    • openclaw pairing list signal
    • openclaw pairing approve signal <CODE>
  • ペアリングは Signal DM における標準的なトークン交換方式です。詳細はこちら:Pairing
  • 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 の設定が完全に欠落している場合、グループチェックのランタイムは(channels.defaults.groupPolicy が設定されていても)groupPolicy="allowlist" にフォールバックします。

OpenClawがどのように Signal と連携しているのか、その裏側を見ていきましょう。

  • signal-cli はデーモンとして動作し、Gateway は SSE(Server-Sent Events)経由でイベントを読み取ります。
  • 受信したメッセージは、共通のチャネルエンベロープに正規化されます。
  • 返信は常に、元の電話番号またはグループに対してルーティングされます。

メッセージの長さやファイルサイズに関する制限事項について説明します。

  • 送信テキストは channels.signal.textChunkLimit(デフォルトは 4000)ごとに分割されます。
  • オプションの改行分割:channels.signal.chunkMode="newline" を設定すると、長さによる分割の前に、空行(段落の境界)で分割を試みます。
  • 添付ファイルをサポートしています(signal-cli から base64 形式で取得します)。
  • デフォルトのメディア容量制限:channels.signal.mediaMaxMb(デフォルトは 8MB)です。
  • メディアのダウンロードをスキップしたい場合は、channels.signal.ignoreAttachments を使用してください。
  • グループ履歴のコンテキストには channels.signal.historyLimit(または channels.signal.accounts.*.historyLimit)が使用され、設定がない場合は messages.groupChat.historyLimit が適用されます。無効にするには 0 を設定してください(デフォルトは 50)。

より自然なチャット体験のための機能です。

  • タイピング通知: OpenClaw は signal-cli sendTyping を通じてタイピング信号を送信し、返信の生成中はその状態を更新し続けます。
  • 既読確認: channels.signal.sendReadReceipts が true の場合、許可された DM に対して既読確認を転送します。
  • Signal-cli はグループチャットの既読確認には対応していません。

Signalでリアクションを送信するには、message action=react を使い、channel=signal を指定します。

送信先(target)には、送信者の E.164 形式の電話番号、または UUID を使用してください。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 を指定すると、エージェントによるリアクションが無効になります(この状態でメッセージツールの 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 アカウントがサポートしている場合のみ)。

まずは、以下のコマンドを順番に実行して状態を確認しましょう。

Terminal window
openclaw status
openclaw gateway status
openclaw logs --follow
openclaw doctor
openclaw channels status --probe

次に、必要に応じて DM のペアリング状態を確認します。

Terminal window
openclaw pairing list signal

よくあるトラブルの原因は以下の通りです。

  • デーモンには接続できるが返信がない場合:アカウントやデーモンの設定(httpUrl, account)および受信モードを確認してください。
  • DM が無視される場合:送信者がペアリングの承認待ち状態になっています。
  • グループメッセージが無視される場合:グループ送信者やメンションのフィルタリング設定によって配信がブロックされています。
  • 設定編集後のバリデーションエラー:openclaw doctor --fix を実行してください。
  • 診断結果に Signal が表示されない場合:channels.signal.enabled: true になっているか確認してください。

追加のチェック項目はこちらです。

Terminal window
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 認証は登録やリカバリーの際にのみ必要ですが、電話番号やアカウントの管理権限を失うと再登録が難しくなる可能性があるため注意してください。

完全な設定については Configuration を確認してください。

プロバイダーのオプションは以下の通りです。

  • channels.signal.enabled: チャネルの起動を有効または無効にします。
  • channels.signal.account: ボットアカウントの電話番号(E.164 形式)です。
  • channels.signal.cliPath: signal-cli へのパスを指定します。
  • channels.signal.httpUrl: デーモンのフル URL です(ホストやポートの設定を上書きします)。
  • channels.signal.httpHost, channels.signal.httpPort: デーモンのバインド設定です(デフォルトは 127.0.0.1:8080)。
  • channels.signal.autoStart: デーモンを自動で起動します(httpUrl が未設定の場合、デフォルトは true です)。
  • channels.signal.startupTimeoutMs: 起動時の待機タイムアウトをミリ秒で指定します(最大 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 を使用してください。
  • 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。
  • Channels Overview — サポートされているすべてのチャネル
  • Pairing — DM の認証とペアリングの流れ
  • Groups — グループチャットの動作とメンションによる制限
  • Channel Routing — メッセージのセッションルーティング
  • Security — アクセスモデルとセキュリティ強化
OpenClaw

OpenClaw Expert

まだ解決しませんか?

このページで解決しない場合は、OpenClaw Expertに直接質問してください。