OpenClawとSignalを連携:signal-cliでボットを構築
Signalを連携させる前に、以下の準備ができているか確認してください。
- サーバーにOpenClawがインストールされていること(Linuxでの手順はUbuntu 24でテスト済みです)。
- Gatewayが動作するホストで
signal-cliが利用可能なこと。 - 認証用のSMSを受信できる電話番号(SMS登録パスを使用する場合に必要です)。
- 登録時のSignalキャプチャ(
signalcaptchas.org)を解決するためのブラウザ環境。
クイックセットアップ(初心者向け)
Section titled “クイックセットアップ(初心者向け)”- ボット用には、普段使いのものとは別の専用のSignal番号を用意することをおすすめします。
signal-cliをインストールします(JVMビルドを使用する場合はJavaが必要です)。- 次のいずれかのセットアップ方法を選んでください。
- 方法A(QRリンク):
signal-cli link -n "OpenClaw"を実行し、手元のSignalアプリでQRコードをスキャンします。 - 方法B(SMS登録): キャプチャ解決とSMS認証を行い、専用の番号を登録します。
- 方法A(QRリンク):
- OpenClawの設定を行い、Gatewayを再起動します。
- 最初のDMを送信し、ペアリングを承認します(
openclaw pairing approve signal <CODE>)。
最小限の設定例はこちらです:
{ channels: { signal: { enabled: true, account: "+15551234567", cliPath: "signal-cli", dmPolicy: "pairing", allowFrom: ["+15557654321"], }, },}各項目の説明:
| 項目 | 説明 |
|---|---|
account | ボットの電話番号。E.164形式(+15551234567)で入力します。 |
cliPath | signal-cli へのパス(PATH が通っている場合は signal-cli)。 |
dmPolicy | DMのアクセス制御ポリシー(pairing を推奨します)。 |
allowFrom | DMを許可する電話番号、または uuid:<id> のリスト。 |
Signal チャンネルの概要
Section titled “Signal チャンネルの概要”このチャンネルの仕組みと特徴について説明します。
- このチャンネルは、埋め込みの libsignal ではなく
signal-cliを介して動作します。GatewayはHTTP JSON-RPCとSSEを利用して通信を行い、返信が常にSignalへ送り返される確定的なルーティングを採用しています。 - DMはエージェントのメインセッションを共有しますが、グループチャットは
agent:<agentId>:signal:group:<groupId>の形式で個別に分離されて管理されます。
設定の書き込み
Section titled “設定の書き込み”デフォルトでは、Signal経由で /config set|unset コマンドを実行して設定を更新することが許可されています(これには commands.config: true の設定が必要です)。
もしこの機能を無効にしたい場合は、以下のように設定してください。
{ channels: { signal: { configWrites: false } },}番号モデル(重要)
Section titled “番号モデル(重要)”- Gateway は Signal デバイス(
signal-cliアカウント)に接続します。 - 個人の Signal アカウントでボットを実行した場合、ループ防止のため自分自身のメッセージは無視されます。
- 「自分がボットにメッセージを送り、ボットが返信する」という動作をさせたい場合は、別のボット用番号を使用してください。
セットアップ方法 A:既存の Signal アカウントを連携する(QR コード)
Section titled “セットアップ方法 A:既存の Signal アカウントを連携する(QR コード)”signal-cli(JVM またはネイティブビルド)をインストールします。- ボットアカウントを連携します:
signal-cli link -n "OpenClaw"を実行し、Signal アプリで QR コードをスキャンしてください。
- 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 アプリのアカウントを連携するのではなく、専用のボット番号を使用したい場合は、この方法を選択してください。
- SMS(または固定電話の音声認証)を受信できる番号を用意します。
- アカウントやセッションの競合を避けるため、専用のボット番号を使用することをおすすめします。
- Gateway ホストに
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 /optsudo ln -sf /opt/signal-cli /usr/local/bin/signal-cli --versionJVM ビルド(signal-cli-${VERSION}.tar.gz)を使用する場合は、先に JRE 25 以上をインストールしてください。
signal-cli は常に最新の状態に保ってください。Signal サーバーの API 変更に伴い、古いリリースは動作しなくなる可能性があると開発元から案内されています。
- 番号の登録と認証を行います:
signal-cli -a +<BOT_PHONE_NUMBER> registerキャプチャが必要な場合:
https://signalcaptchas.org/registration/generate.htmlを開きます。- キャプチャを完了し、「Open Signal」から
signalcaptcha://...で始まるリンク先をコピーします。 - 可能な限り、ブラウザセッションと同じ外部 IP からコマンドを実行してください。
- キャプチャトークンの期限は短いため、すぐに登録を再実行します:
signal-cli -a +<BOT_PHONE_NUMBER> register --captcha '<SIGNALCAPTCHA_URL>'signal-cli -a +<BOT_PHONE_NUMBER> verify <VERIFICATION_CODE>- OpenClaw を設定し、Gateway を再起動して、チャンネルを確認します:
# If you run the gateway as a user systemd service:systemctl --user restart openclaw-gateway
# Then verify:openclaw doctoropenclaw channels status --probe- DM 送信者のペアリング:
- ボットの番号に任意のメッセージを送信します。
- サーバー側でコードを承認します:
openclaw pairing approve signal <PAIRING_CODE>。 - 「不明な連絡先」と表示されないよう、ボットの番号をスマートフォンの連絡先に保存しておきましょう。
重要:signal-cli で電話番号アカウントを登録すると、その番号を使用しているメインの Signal アプリのセッションが解除されることがあります。専用のボット番号を用意するか、既存のスマートフォンの設定を維持したい場合は QR コードによる連携モードを使用してください。
関連リファレンス:
signal-cliREADME: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)
外部デーモンモード(httpUrl)
Section titled “外部デーモンモード(httpUrl)”JVM のコールドスタートが遅い場合や、コンテナの初期化、CPU リソースの共有などの理由で signal-cli を自分で管理したい場合は、デーモンを個別に実行して OpenClaw からそこを参照するように設定できます。
{ channels: { signal: { httpUrl: "http://127.0.0.1:8080", autoStart: false, }, },}これにより、OpenClaw 内部での自動起動や起動待ちをスキップできます。自動起動時の起動が遅い場合は、channels.signal.startupTimeoutMs を設定してください。
アクセス制御(DMとグループ)
Section titled “アクセス制御(DMとグループ)”Signalでのやり取りを安全に保つための設定について解説します。
DM(ダイレクトメッセージ)の場合:
- デフォルト設定は
channels.signal.dmPolicy = "pairing"です。 - 未知の送信者からはペアリングコードが届きます。承認されるまでメッセージは無視されます(コードの有効期限は1時間です)。
- 承認するには以下のコマンドを使用します:
openclaw pairing list signalopenclaw 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"にフォールバックします。
仕組み(動作について)
Section titled “仕組み(動作について)”OpenClawがどのように Signal と連携しているのか、その裏側を見ていきましょう。
signal-cliはデーモンとして動作し、Gateway は SSE(Server-Sent Events)経由でイベントを読み取ります。- 受信したメッセージは、共通のチャネルエンベロープに正規化されます。
- 返信は常に、元の電話番号またはグループに対してルーティングされます。
メディアと制限
Section titled “メディアと制限”メッセージの長さやファイルサイズに関する制限事項について説明します。
- 送信テキストは
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)。
タイピング通知と既読確認
Section titled “タイピング通知と既読確認”より自然なチャット体験のための機能です。
- タイピング通知: OpenClaw は
signal-cli sendTypingを通じてタイピング信号を送信し、返信の生成中はその状態を更新し続けます。 - 既読確認:
channels.signal.sendReadReceiptsが true の場合、許可された DM に対して既読確認を転送します。 - Signal-cli はグループチャットの既読確認には対応していません。
リアクション (message tool)
Section titled “リアクション (message tool)”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=truemessage 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)
Section titled “配信ターゲット (CLI/cron)”CLI や cron からメッセージを送信する際のターゲット指定には、以下の形式が利用可能です。
- DM(ダイレクトメッセージ):
signal:+15551234567(または E.164 形式の番号のみ)。 - UUID 指定の DM:
uuid:<id>(または UUID 単体)。 - グループ:
signal:group:<groupId>。 - ユーザー名:
username:<name>(お使いの Signal アカウントがサポートしている場合のみ)。
トラブルシューティング
Section titled “トラブルシューティング”まずは、以下のコマンドを順番に実行して状態を確認しましょう。
openclaw statusopenclaw gateway statusopenclaw logs --followopenclaw doctoropenclaw channels status --probe次に、必要に応じて DM のペアリング状態を確認します。
openclaw pairing list signalよくあるトラブルの原因は以下の通りです。
- デーモンには接続できるが返信がない場合:アカウントやデーモンの設定(
httpUrl,account)および受信モードを確認してください。 - DM が無視される場合:送信者がペアリングの承認待ち状態になっています。
- グループメッセージが無視される場合:グループ送信者やメンションのフィルタリング設定によって配信がブロックされています。
- 設定編集後のバリデーションエラー:
openclaw doctor --fixを実行してください。 - 診断結果に Signal が表示されない場合:
channels.signal.enabled: trueになっているか確認してください。
追加のチェック項目はこちらです。
openclaw pairing list signalpgrep -af signal-cligrep -i "signal" "/tmp/openclaw/openclaw-$(date +%Y-%m-%d).log" | tail -20詳細な調査フローについては、こちらを参照してください:/channels/troubleshooting
セキュリティに関する注意点
Section titled “セキュリティに関する注意点”signal-cliはアカウントキーをローカル(通常は~/.local/share/signal-cli/data/)に保存します。- サーバーの移行や再構築を行う前に、Signal のアカウント状態をバックアップしておきましょう。
- 明示的に広範な DM アクセスが必要な場合を除き、
channels.signal.dmPolicy: "pairing"の設定を維持することをおすすめします。 - SMS 認証は登録やリカバリーの際にのみ必要ですが、電話番号やアカウントの管理権限を失うと再登録が難しくなる可能性があるため注意してください。
Signal 設定リファレンス
Section titled “Signal 設定リファレンス”完全な設定については 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 Expert
まだ解決しませんか?
このページで解決しない場合は、OpenClaw Expertに直接質問してください。