ペアリング
Discord の DM はデフォルトでペアリングモードです。
スラッシュコマンド
ネイティブコマンドの挙動とコマンド一覧を確認できます。
チャンネルトラブルシューティング
チャンネル横断の診断手順と修復フローを確認できます。
クイックセットアップ
新しいアプリケーションとボットを作成し、ボットを Discord サーバーに追加したうえで、OpenClaw とペアリングする必要があります。ボットは、自分専用のプライベートサーバーに追加する構成を推奨します。まだサーバーがない場合は、先に 作成してください(Create My Own > For me and my friends を選択します)。Discord アプリケーションとボットを作成する
Discord Developer Portal に移動し、New Application をクリックします。名前は「OpenClaw」などで構いません。左側の Bot を開き、Username を OpenClaw エージェントとして使いたい名前に設定します。
特権インテントを有効にする
引き続き Bot ページで、Privileged Gateway Intents までスクロールし、次を有効にします。
- Message Content Intent(必須)
- Server Members Intent(推奨。ロール allowlist と名前から ID への解決に必要です)
- Presence Intent(任意。プレゼンス更新を受信する場合のみ必要です)
ボットトークンをコピーする
Bot ページ上部に戻り、Reset Token をクリックします。表示されたトークンをコピーして安全な場所に保存します。これは Bot Token であり、後続の設定で使用します。
名前に反して、ここでは最初のトークンが生成されます。既存の何かが「リセット」されるわけではありません。
招待 URL を生成してボットをサーバーに追加する
左側の OAuth2 を開き、ボットをサーバーに追加するための招待 URL を生成します。OAuth2 URL Generator までスクロールし、次を有効にします。
botapplications.commands
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions(任意)
Developer Mode を有効にして ID を取得する
Discord アプリ側で Developer Mode を有効にし、内部 ID をコピーできるようにします。
- User Settings(アバター横の歯車)→ Advanced → Developer Mode をオンにする
- サイドバーの サーバーアイコン を右クリックして Copy Server ID
- 自分のアバター を右クリックして Copy User ID
サーバーメンバーからの DM を許可する
ペアリングを成立させるには、Discord 側でボットから DM を受け取れる必要があります。サーバーアイコン を右クリックし、Privacy Settings を開いて Direct Messages をオンにします。これにより、サーバーメンバー(ボットを含む)から DM を受信できます。OpenClaw で Discord DM を使う場合は、この設定を有効のままにしてください。ギルドチャンネルだけを使う予定であれば、ペアリング完了後に無効化しても構いません。
Step 0: ボットトークンを安全に設定する(チャットには送らない)
Discord のボットトークンは、パスワードと同様に機密情報です。エージェントへメッセージを送る前に、OpenClaw を動かしているマシンに設定してください。すでに OpenClaw をバックグラウンドサービスとして実行している場合は、
openclaw gateway restart を使います。OpenClaw を設定してペアリングする
- エージェントに依頼する
- CLI / config
既存のチャンネル(例: Telegram)で OpenClaw エージェントに次のように伝えます。Discord が最初のチャンネルである場合は、CLI / config タブを使ってください。
「Discord の bot token はすでに config に設定済みです。User ID<user_id>と Server ID<server_id>を使って Discord のセットアップを完了してください。」
トークン解決はアカウント単位で行われます。config に設定されたトークンが環境変数より優先されます。
DISCORD_BOT_TOKEN が使われるのはデフォルトアカウントだけです。推奨: ギルドワークスペースを用意する
DM が動作したら、Discord サーバー全体をワークスペースとして構成できます。各チャンネルは独自のコンテキストを持つ個別のエージェントセッションになり、プライベートサーバーではこの構成が特に有効です。サーバーをギルド allowlist に追加する
これにより、エージェントは DM だけでなく、サーバー内のチャンネルにも応答できるようになります。
- エージェントに依頼する
- Config
「Discord Server ID <server_id> を guild allowlist に追加してください」
@mention なしでも応答できるようにする
デフォルトでは、ギルドチャンネルではエージェントへの @mention がある場合だけ応答します。プライベートサーバーでは、すべてのメッセージに応答させたいケースが多くあります。
- エージェントに依頼する
- Config
「このサーバーでは、@mention なしでもエージェントが応答できるようにしてください」
#coding、#home、#research など、用途ごとに分けて運用できます。
ランタイムモデル
- ゲートウェイが Discord 接続を保持します。
- 応答ルーティングは決定的です。Discord から入った返信は Discord に返ります。
- デフォルトでは(
session.dmScope=main)、DM はエージェントのメインセッション(agent:main:main)を共有します。 - ギルドチャンネルは独立したセッションキー(
agent:<agentId>:discord:channel:<channelId>)として扱われます。 - グループ DM はデフォルトで無視されます(
channels.discord.dm.groupEnabled=false)。 - ネイティブスラッシュコマンドは独立したコマンドセッション(
agent:<agentId>:discord:slash:<userId>)で実行されますが、ルーティング先の会話セッションに対するCommandTargetSessionKeyは保持されます。
フォーラムチャンネル
Discord の forum チャンネルと media チャンネルでは、投稿はスレッド形式のみ受け付けられます。OpenClaw では、次の 2 通りの作成方法に対応しています。- forum 親(
channel:<forumId>)にメッセージを送信してスレッドを自動作成する openclaw message thread createでスレッドを直接作成する。forum チャンネルでは--message-idを渡さないでください
channel:<threadId>)に送信してください。
インタラクティブコンポーネント
OpenClaw は、エージェントメッセージ向けに Discord components v2 コンテナをサポートしています。components ペイロードを含む message ツールを使用してください。インタラクション結果は通常の受信メッセージとしてエージェントへ戻り、既存の Discord replyToMode 設定に従って処理されます。
サポートされるブロック:
text、section、separator、actions、media-gallery、file- action row では最大 5 個のボタン、または 1 個の select menu を使用できます
- select の型は
string、user、role、mentionable、channelです
components.reusable=true を指定すると、有効期限が切れるまでボタン、select、フォームを複数回利用できます。
ボタンを押せるユーザーを制限するには、そのボタンに allowedUsers を設定します(Discord ユーザー ID、タグ、または *)。設定されている場合、一致しないユーザーには一時的な拒否メッセージが返されます。
/model と /models スラッシュコマンドでは、プロバイダーとモデルのドロップダウン、および Submit ステップを持つ対話型モデルピッカーが開きます。ピッカーの応答は ephemeral で、実行したユーザーだけが利用できます。
ファイル添付:
fileブロックは、添付参照(attachment://<filename>)を指している必要があります- 添付ファイルは
media/path/filePath(単一ファイル)で渡します。複数ファイルにはmedia-galleryを使用してください - 添付参照名とアップロード名を一致させたい場合は、
filenameでアップロード名を上書きします
- 最大 5 フィールドまで持てる
components.modalを追加できます - フィールド型は
text、checkbox、radio、select、role-select、user-selectです - OpenClaw がトリガーボタンを自動で追加します
アクセス制御とルーティング
- DM ポリシー
- ギルドポリシー
- メンションとグループ DM
channels.discord.dmPolicy は DM へのアクセスを制御します(旧設定: channels.discord.dm.policy)。pairing(デフォルト)allowlistopen(channels.discord.allowFromに"*"を含める必要があります。旧設定:channels.discord.dm.allowFrom)disabled
open でない場合、不明なユーザーはブロックされます。pairing モードではペアリングが要求されます。マルチアカウント時の優先順位:channels.discord.accounts.default.allowFromはdefaultアカウントにのみ適用されます- 名前付きアカウントは、自身の
allowFromが未設定ならchannels.discord.allowFromを継承します - 名前付きアカウントは
channels.discord.accounts.default.allowFromを継承しません
user:<id><@id>形式の mention
ロールベースのエージェントルーティング
bindings[].match.roles を使うと、Discord ギルドメンバーをロール ID に応じて別のエージェントへ振り分けられます。ロールベースの binding はロール ID のみを受け付け、評価順は peer / parent-peer binding の後、guild 単位 binding の前です。binding に peer、guildId、roles など複数の条件がある場合は、設定されたすべての条件に一致する必要があります。
Developer Portal の設定
アプリとボットを作成する
アプリとボットを作成する
- Discord Developer Portal → Applications → New Application
- Bot → Add Bot
- ボットトークンをコピーする
特権インテント
特権インテント
Bot → Privileged Gateway Intents で次を有効にします。
- Message Content Intent
- Server Members Intent(推奨)
setPresence)だけであれば、メンバー向けの presence updates を有効化する必要はありません。OAuth スコープと基本権限
OAuth スコープと基本権限
OAuth URL generator:
- scopes:
bot,applications.commands
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions(任意)
Administrator は付与しないでください。ID をコピーする
ID をコピーする
Discord の Developer Mode を有効にしたうえで、次の ID をコピーします。
- server ID
- channel ID
- user ID
ネイティブコマンドとコマンド認可
commands.nativeのデフォルトは"auto"で、Discord では有効になります- チャンネル単位の上書きは
channels.discord.commands.nativeです commands.native=falseを指定すると、以前に登録された Discord ネイティブコマンドを明示的に削除します- ネイティブコマンドの認可には、通常メッセージ処理と同じ Discord allowlist / policy が使われます
- 権限のないユーザーにも Discord UI 上でコマンドが見えることがありますが、実行時には OpenClaw の認可が適用され、“not authorized” が返ります
ephemeral: true
機能の詳細
返信タグとネイティブ返信
返信タグとネイティブ返信
Discord は、エージェント出力に含まれる返信タグをサポートします。
[[reply_to_current]][[reply_to:<id>]]
channels.discord.replyToMode で制御されます。off(デフォルト)firstall
off は暗黙的な reply threading を無効にしますが、明示的な [[reply_to_*]] タグは引き続き有効です。メッセージ ID はコンテキストや履歴にも現れるため、エージェントは特定のメッセージを対象にできます。ライブストリームプレビュー
ライブストリームプレビュー
OpenClaw は、一時メッセージを送信し、テキストの到着にあわせて編集することで、返信ドラフトをストリーミング表示できます。プレビュー配信はテキストのみが対象で、メディア返信は通常の配信にフォールバックします。注: preview streaming と block streaming は別機能です。Discord で block streaming が明示的に有効になっている場合、OpenClaw は二重配信を避けるため preview stream をスキップします。
channels.discord.streamingはプレビュー配信を制御します(off|partial|block|progress、デフォルト:off)progressはチャンネル間の一貫性のために受け付けられ、Discord ではpartialにマッピングされますchannels.discord.streamModeは旧エイリアスで、自動移行されますpartialでは、トークン到着に応じて 1 つのプレビューメッセージを編集しますblockでは、ドラフトサイズのチャンク単位で出力します。サイズや分割位置はdraftChunkで調整できます
block モードのデフォルトチャンク設定(channels.discord.textChunkLimit の範囲内に丸められます):履歴、コンテキスト、スレッド挙動
履歴、コンテキスト、スレッド挙動
ギルド履歴コンテキスト:
channels.discord.historyLimitのデフォルトは20- フォールバックは
messages.groupChat.historyLimit 0を指定すると無効になります
channels.discord.dmHistoryLimitchannels.discord.dms["<user_id>"].historyLimit
- Discord スレッドはチャンネルセッションとしてルーティングされます
- 親スレッドのメタデータは、親セッションとの関連付けに利用できます
- スレッド固有の設定がない場合、スレッド設定は親チャンネル設定を継承します
サブエージェント向けスレッド固定セッション
サブエージェント向けスレッド固定セッション
Discord では、スレッドを特定のセッションターゲットに固定できます。これにより、そのスレッドでの後続メッセージは同じセッション(サブエージェントセッションを含む)へ継続してルーティングされます。コマンド:注意:
/focus <target>現在または新規スレッドをサブエージェント / セッションターゲットへ固定する/unfocus現在のスレッド固定を解除する/agentsアクティブな実行と binding 状態を表示する/session idle <duration|off>固定中セッションの無操作による自動 unfocus 設定を確認 / 更新する/session max-age <duration|off>固定中セッションの最大寿命を確認 / 更新する
session.threadBindings.*はグローバルデフォルトを設定しますchannels.discord.threadBindings.*は Discord 用の挙動を上書きしますsessions_spawn({ thread: true })に対してスレッドを自動作成 / 固定するにはspawnSubagentSessionsを true にする必要があります- ACP(
/acp spawn ... --thread ...またはsessions_spawn({ runtime: "acp", thread: true }))でスレッドを自動作成 / 固定するにはspawnAcpSessionsを true にする必要があります - アカウントで thread binding が無効化されている場合、
/focusおよび関連操作は利用できません
永続的な ACP チャンネル binding
永続的な ACP チャンネル binding
安定した「常時接続」型の ACP ワークスペースを実現するには、Discord 会話を対象にしたトップレベルの型付き ACP binding を設定します。設定パス:注意:
bindings[]にtype: "acp"とmatch.channel: "discord"を指定します
- スレッドメッセージは親チャンネルの ACP binding を継承できます
- binding 済みのチャンネルまたはスレッドでは、
/newと/resetは同じ ACP セッションをその場でリセットします - 一時的な thread binding も引き続き利用でき、アクティブな間はターゲット解決を上書きできます
リアクション通知
リアクション通知
ギルド単位のリアクション通知モード:
offown(デフォルト)allallowlist(guilds.<id>.usersを使用)
ack リアクション
ack リアクション
ackReaction は、OpenClaw が受信メッセージを処理中であることを示す絵文字リアクションを送ります。解決順序:channels.discord.accounts.<accountId>.ackReactionchannels.discord.ackReactionmessages.ackReaction- エージェント identity の絵文字フォールバック(
agents.list[].identity.emoji、未設定時は"👀")
- Discord は Unicode 絵文字とカスタム絵文字名の両方を受け付けます
- チャンネルまたはアカウント単位で無効化するには
""を使います
設定の書き込み
設定の書き込み
チャンネル起点の設定書き込みは、デフォルトで有効です。これは
/config set|unset のフローに影響します(コマンド機能が有効な場合)。無効化:ゲートウェイプロキシ
ゲートウェイプロキシ
channels.discord.proxy を使うと、Discord ゲートウェイの WebSocket 通信と起動時の REST 参照(application ID と allowlist 解決)を HTTP(S) プロキシ経由にできます。PluralKit サポート
PluralKit サポート
PluralKit 解決を有効にすると、プロキシされたメッセージをシステムメンバーの identity にマッピングできます。注意:
- allowlist では
pk:<memberId>を使用できます - メンバー表示名の名前 / slug 一致は、
channels.discord.dangerouslyAllowNameMatching: trueのときだけ有効です - 参照には元のメッセージ ID が使われ、時間窓の制約があります
- 解決に失敗した場合、プロキシメッセージは bot メッセージとして扱われ、
allowBots=trueでない限り破棄されます
プレゼンス設定
プレゼンス設定
Discord 上での exec 承認
Discord 上での exec 承認
Discord は、DM 内でのボタンベース exec 承認に対応しており、必要に応じて元のチャンネルに承認プロンプトを投稿することもできます。設定パス:
channels.discord.execApprovals.enabledchannels.discord.execApprovals.approverschannels.discord.execApprovals.target(dm|channel|both、デフォルト:dm)agentFilter、sessionFilter、cleanupAfterResolve
target が channel または both の場合、承認プロンプトはチャンネルにも表示されます。ボタンを使えるのは設定された承認者だけで、その他のユーザーには ephemeral の拒否が返されます。承認プロンプトにはコマンド本文が含まれるため、チャンネル配信は信頼できるチャンネルにだけ有効化してください。セッションキーからチャンネル ID を導出できない場合、OpenClaw は DM 配信へフォールバックします。このハンドラーのゲートウェイ認可には、他のゲートウェイクライアントと同じ共有認証情報解決契約が使われます。- env 優先のローカル認可(
OPENCLAW_GATEWAY_TOKEN/OPENCLAW_GATEWAY_PASSWORD、次にgateway.auth.*) - ローカルモードでは、
gateway.auth.*が未設定ならgateway.remote.*をフォールバックとして使用可能 - 必要に応じて
gateway.remote.*によるリモートモードをサポート - URL override は override-safe です。CLI override は暗黙の認証情報を再利用せず、env override は env の認証情報だけを使います
ツールとアクションゲート
Discord の message action には、メッセージ送受信、チャンネル管理、モデレーション、プレゼンス、メタデータ関連のアクションが含まれます。 代表例:- messaging:
sendMessage、readMessages、editMessage、deleteMessage、threadReply - reactions:
react、reactions、emojiList - moderation:
timeout、kick、ban - presence:
setPresence
channels.discord.actions.* 配下にあります。
デフォルトの gate 挙動:
| Action group | Default |
|---|---|
| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | enabled |
| roles | disabled |
| moderation | disabled |
| presence | disabled |
コンポーネント v2 UI
OpenClaw は、exec 承認と cross-context marker に Discord components v2 を使用します。Discord の message action では、カスタム UI 用のcomponents も受け付けられます(高度な用途。Carbon component instance が必要です)。従来の embeds も引き続き利用できますが、推奨はされません。
channels.discord.ui.components.accentColorは、Discord component container で使用するアクセントカラー(16 進数)を設定します- アカウント単位では
channels.discord.accounts.<id>.ui.components.accentColorで設定します - components v2 が存在する場合、
embedsは無視されます
音声チャンネル
OpenClaw は Discord の音声チャンネルに参加し、リアルタイムで継続的な会話を行えます。これは音声メッセージ添付とは別機能です。 要件:- ネイティブコマンド(
commands.nativeまたはchannels.discord.commands.native)を有効にする channels.discord.voiceを設定する- ボットに対象音声チャンネルでの Connect と Speak 権限を付与する
/vc join|leave|status を使います。このコマンドはアカウントのデフォルトエージェントを使い、他の Discord コマンドと同じ allowlist と group policy ルールに従います。
自動参加の例:
voice.ttsは音声再生に限ってmessages.ttsを上書きします- 音声 transcript turn の owner 判定は Discord の
allowFrom(またはdm.allowFrom)から導かれます。owner でない発話者は、gatewayやcronなどの owner 限定ツールにアクセスできません - 音声機能はデフォルトで有効です。無効化するには
channels.discord.voice.enabled=falseを設定します voice.daveEncryptionとvoice.decryptionFailureToleranceは@discordjs/voiceの join option にそのまま渡されます@discordjs/voice側のデフォルトは、未設定時にdaveEncryption=trueおよびdecryptionFailureTolerance=24です- OpenClaw は受信時の復号失敗も監視し、短時間に繰り返し失敗した場合は音声チャンネルから一度離脱して再参加することで自動回復を試みます
- 受信ログに
DecryptionFailed(UnencryptedWhenPassthroughDisabled)が繰り返し出る場合は、上流の@discordjs/voice受信バグである discord.js #11419 に該当している可能性があります
音声メッセージ
Discord の音声メッセージでは波形プレビューが表示され、OGG/Opus 音声とメタデータが必要です。OpenClaw は波形を自動生成しますが、音声ファイルを検査して変換するために、ゲートウェイホスト上でffmpeg と ffprobe が利用可能である必要があります。
要件と制約:
- ローカルファイルパス を指定してください(URL は拒否されます)
- テキスト本文は省略してください(Discord は同じペイロード内でテキストと音声メッセージを同時に送れません)
- 音声形式は任意です。必要に応じて OpenClaw が OGG/Opus に変換します
トラブルシューティング
許可されていない intent を使っている、またはボットがギルドメッセージを受信できない
許可されていない intent を使っている、またはボットがギルドメッセージを受信できない
- Message Content Intent を有効にする
- ユーザー / メンバー解決に依存する場合は Server Members Intent も有効にする
- intent を変更したあとはゲートウェイを再起動する
ギルドメッセージが予期せずブロックされる
ギルドメッセージが予期せずブロックされる
groupPolicyを確認するchannels.discord.guilds配下の guild allowlist を確認する- guild の
channelsマップが存在する場合、列挙されたチャンネルだけが許可される requireMentionの挙動と mention パターンを確認する
requireMention=false なのにブロックされる
requireMention=false なのにブロックされる
よくある原因:
groupPolicy="allowlist"だが、一致する guild / channel allowlist がないrequireMentionの設定場所が誤っている(channels.discord.guildsまたは channel entry の下である必要があります)- 送信者が guild / channel の
usersallowlist によってブロックされている
長時間実行されるハンドラーがタイムアウトする、または返信が重複する
長時間実行されるハンドラーがタイムアウトする、または返信が重複する
典型的なログ:遅い listener のための余裕を増やしたい場合は
Listener DiscordMessageListener timed out after 30000ms for event MESSAGE_CREATESlow listener detected ...discord inbound worker timed out after ...
- 単一アカウント:
channels.discord.eventQueue.listenerTimeout - マルチアカウント:
channels.discord.accounts.<accountId>.eventQueue.listenerTimeout
- 単一アカウント:
channels.discord.inboundWorker.runTimeoutMs - マルチアカウント:
channels.discord.accounts.<accountId>.inboundWorker.runTimeoutMs - デフォルト:
1800000(30 分)。無効化するには0を指定します
eventQueue.listenerTimeout を使います。キュー済みエージェントターンに別の安全弁が必要な場合にだけ inboundWorker.runTimeoutMs を調整してください。権限監査の不一致
権限監査の不一致
channels status --probe の権限チェックは、数値チャンネル ID に対してのみ完全に機能します。slug キーを使用していても、ランタイム上のマッチング自体は可能ですが、probe では権限を完全には検証できません。DM とペアリングの問題
DM とペアリングの問題
- DM が無効化されている:
channels.discord.dm.enabled=false - DM policy が無効化されている:
channels.discord.dmPolicy="disabled"(旧設定:channels.discord.dm.policy) pairingモードでペアリング承認待ちになっている
bot 同士のループ
bot 同士のループ
デフォルトでは、bot が投稿したメッセージは無視されます。
channels.discord.allowBots=true を使う場合は、ループを防ぐために厳格な mention ルールと allowlist を組み合わせてください。通常は、ボット自身への mention を含む bot メッセージだけを受け付ける channels.discord.allowBots="mentions" を推奨します。音声 STT が DecryptionFailed(...) で落ちる
音声 STT が DecryptionFailed(...) で落ちる
- Discord 音声受信の回復ロジックが入っているよう、OpenClaw を最新に保つ(
openclaw update) channels.discord.voice.daveEncryption=true(デフォルト)を確認するchannels.discord.voice.decryptionFailureTolerance=24(上流デフォルト)から始め、必要な場合だけ調整する- 次のログを確認する:
discord voice: DAVE decrypt failures detecteddiscord voice: repeated decrypt failures; attempting rejoin
- 自動再参加後も失敗が続く場合は、ログを収集して discord.js #11419 と比較する
設定リファレンスの参照先
主な参照先: 特に確認頻度の高い Discord フィールド:- 起動 / 認可:
enabled、token、accounts.*、allowBots - policy:
groupPolicy、dm.*、guilds.*、guilds.*.channels.* - command:
commands.native、commands.useAccessGroups、configWrites、slashCommand.* - event queue:
eventQueue.listenerTimeout(listener budget)、eventQueue.maxQueueSize、eventQueue.maxConcurrency - inbound worker:
inboundWorker.runTimeoutMs - reply / history:
replyToMode、historyLimit、dmHistoryLimit、dms.*.historyLimit - delivery:
textChunkLimit、chunkMode、maxLinesPerMessage - streaming:
streaming(旧エイリアス:streamMode)、draftChunk、blockStreaming、blockStreamingCoalesce - media / retry:
mediaMaxMb、retrymediaMaxMbは Discord への送信アップロード上限です(デフォルト:8MB)
- actions:
actions.* - presence:
activity、status、activityType、activityUrl - UI:
ui.components.accentColor - features:
threadBindings、トップレベルのbindings[](type: "acp")、pluralkit、execApprovals、intents、agentComponents、heartbeat、responsePrefix
セーフティと運用
- ボットトークンは機密情報として扱ってください(監視付き環境では
DISCORD_BOT_TOKENを推奨します) - Discord 権限は最小権限で付与してください
- コマンドの deploy 状態や反映状態が古い場合は、ゲートウェイを再起動し、
openclaw channels status --probeで再確認してください