Discord(Bot API)
ステータス:公式Discordゲートウェイ経由でDMおよびギルドチャンネルに対応しています。
- ペアリング — Discord DMはデフォルトでペアリングモードです。
- スラッシュコマンド — ネイティブコマンドの動作とコマンドカタログ。
- チャンネルトラブルシューティング — クロスチャンネルの診断と修復フロー。
クイックセットアップ
Botを含む新しいアプリケーションを作成し、サーバーに追加して、OpenClawとペアリングする必要があります。自分専用のプライベートサーバーにBotを追加することを推奨します。まだサーバーがない場合は、先に作成してください(自分用のサーバーを作成 > 自分と友達のため を選択)。
ステップ1:Discordアプリケーションとbotの作成
[Discord Developer Portal](https://discord.com/developers/applications)にアクセスし、**New Application** をクリックします。「OpenClaw」などの名前を付けてください。
サイドバーで **Bot** をクリックします。**Username** にOpenClawエージェントの呼び名を設定してください。
ステップ2:特権インテントの有効化
**Bot** ページで下にスクロールし、**Privileged Gateway Intents** から以下を有効にします:
- **Message Content Intent**(必須)
- **Server Members Intent**(推奨。ロール許可リストや名前からIDへの変換に必要)
- **Presence Intent**(任意。プレゼンス更新が必要な場合のみ)
ステップ3:Botトークンのコピー
**Bot** ページの上部に戻り、**Reset Token** をクリックします。
> **注意:** 名前に反して、初回トークンの生成操作です。何かが「リセット」されるわけではありません。
トークンをコピーして安全な場所に保存してください。これが **Bot Token** であり、後で使用します。
ステップ4:招待URLの生成とサーバーへのBot追加
サイドバーで **OAuth2** をクリックします。適切な権限でBotをサーバーに追加するための招待URLを生成します。
**OAuth2 URL Generator** まで下にスクロールし、以下を有効にします:
- `bot`
- `applications.commands`
下部に **Bot Permissions** セクションが表示されます。以下を有効にしてください:
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions(任意)
一番下に生成されたURLをコピーしてブラウザに貼り付け、サーバーを選択して **Continue** をクリックします。DiscordサーバーにBotが表示されるはずです。
ステップ5:開発者モードの有効化とIDの取得
Discordアプリに戻り、内部IDをコピーするために開発者モードを有効にします。
1. **ユーザー設定**(アバター横の歯車アイコン)→ **詳細設定** → **開発者モード** をオン
2. サイドバーの **サーバーアイコン** を右クリック → **サーバーIDをコピー**
3. **自分のアバター** を右クリック → **ユーザーIDをコピー**
**サーバーID** と **ユーザーID** をBotトークンと一緒に保存してください。次のステップで3つともOpenClawに送信します。
ステップ6:サーバーメンバーからのDMを許可
ペアリングを行うには、BotがDMを送信できるようにする必要があります。**サーバーアイコン** を右クリック → **プライバシー設定** → **ダイレクトメッセージ** をオンにします。
これにより、サーバーメンバー(Botを含む)がDMを送信できるようになります。Discord DMでOpenClawを使用する場合はオンのままにしてください。ギルドチャンネルのみ使用する場合は、ペアリング後にDMを無効にできます。
ステップ7:Botトークンの安全な設定(チャットで送信しないでください)
Discord Botトークンはパスワードのようなシークレットです。エージェントにメッセージを送る前に、OpenClawを実行しているマシンで設定してください。
openclaw config set channels.discord.token '"YOUR_BOT_TOKEN"' --json
openclaw config set channels.discord.enabled true --json
openclaw gateway
OpenClawが既にバックグラウンドサービスとして動作している場合は、代わりに `openclaw gateway restart` を使用してください。
ステップ8:OpenClawの設定とペアリング
#### エージェントに依頼
既存のチャンネル(例:Telegram)でOpenClawエージェントに話しかけてください。Discordが最初のチャンネルの場合は、CLI / 設定タブを使用してください。
> 「Discord Botトークンは既に設定済みです。ユーザーID `<user_id>` とサーバーID `<server_id>` でDiscordのセットアップを完了してください。」
#### CLI / 設定
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN",
},
},
}
デフォルトアカウントの環境変数フォールバック:
DISCORD_BOT_TOKEN=...
`channels.discord.token` にはSecretRef値(env/file/execプロバイダー)もサポートされています。[シークレット管理](/docs/gateway/secrets)を参照してください。
ステップ9:最初のDMペアリングの承認
Gatewayが動作したら、DiscordでBotにDMを送信します。ペアリングコードが返されます。
#### エージェントに依頼
既存のチャンネルでエージェントにペアリングコードを送信します:
> 「このDiscordペアリングコードを承認してください:`<CODE>`」
#### CLI
openclaw pairing list discord
openclaw pairing approve discord <CODE>
ペアリングコードは1時間で期限切れになります。
これでDiscord DM経由でエージェントとチャットできるようになります。
注意: トークン解決はアカウント対応です。設定のトークン値は環境変数フォールバックより優先されます。
DISCORD_BOT_TOKENはデフォルトアカウントにのみ使用されます。 高度なアウトバウンド呼び出し(メッセージツール/チャンネルアクション)では、その呼び出し用に明示的なトークンが使用されます。アカウントポリシー/リトライ設定はアクティブなランタイムスナップショットの選択されたアカウントから適用されます。
推奨:ギルドワークスペースの設定
DMが動作したら、Discordサーバーをフルワークスペースとして設定できます。各チャンネルが独自のエージェントセッションとコンテキストを持ちます。自分とBotだけのプライベートサーバーに推奨です。
ステップ1:ギルド許可リストにサーバーを追加
エージェントがDMだけでなく、サーバー内のすべてのチャンネルで応答できるようにします。
#### エージェントに依頼
> 「Discord サーバーID `<server_id>` をギルド許可リストに追加してください」
#### 設定
{
channels: {
discord: {
groupPolicy: "allowlist",
guilds: {
YOUR_SERVER_ID: {
requireMention: true,
users: ["YOUR_USER_ID"],
},
},
},
},
}
ステップ2:@メンションなしでの応答を許可
デフォルトでは、エージェントはギルドチャンネルで@メンションされた場合のみ応答します。プライベートサーバーでは、すべてのメッセージに応答させたい場合が多いでしょう。
#### エージェントに依頼
> 「このサーバーで@メンションなしでエージェントが応答できるようにしてください」
#### 設定
ギルド設定で `requireMention: false` を設定します:
{
channels: {
discord: {
guilds: {
YOUR_SERVER_ID: {
requireMention: false,
},
},
},
},
}
ステップ3:ギルドチャンネルでのメモリ計画
デフォルトでは、長期メモリ(MEMORY.md)はDMセッションでのみロードされます。ギルドチャンネルではMEMORY.mdは自動ロードされません。
#### エージェントに依頼
> 「Discordチャンネルで質問する際、MEMORY.mdからの長期コンテキストが必要な場合はmemory_searchまたはmemory_getを使用してください。」
#### 手動
すべてのチャンネルで共有コンテキストが必要な場合は、安定した指示を `AGENTS.md` または `USER.md` に入れてください(すべてのセッションに注入されます)。長期メモは `MEMORY.md` に保存し、メモリツールでオンデマンドにアクセスします。
Discordサーバーにチャンネルを作成してチャットを始めましょう。エージェントはチャンネル名を認識でき、各チャンネルは独立したセッションを持ちます。#coding、#home、#research など、ワークフローに合わせて自由に設定できます。
ランタイムモデル
- GatewayがDiscord接続を管理します。
- 返信ルーティングは決定的です:Discord着信は常にDiscordに返信されます。
- デフォルト(
session.dmScope=main)では、ダイレクトチャットはエージェントメインセッション(agent:main:main)を共有します。 - ギルドチャンネルは隔離されたセッションキー(
agent:<agentId>:discord:channel:<channelId>)です。 - グループDMはデフォルトで無視されます(
channels.discord.dm.groupEnabled=false)。 - ネイティブスラッシュコマンドは隔離されたコマンドセッション(
agent:<agentId>:discord:slash:<userId>)で実行されますが、CommandTargetSessionKeyをルーティング先の会話セッションに引き継ぎます。
フォーラムチャンネル
Discordのフォーラムチャンネルとメディアチャンネルはスレッド投稿のみを受け付けます。OpenClawでは2つの方法でスレッドを作成できます:
- フォーラム親(
channel:<forumId>)にメッセージを送信してスレッドを自動作成。スレッドタイトルにはメッセージの最初の非空行が使用されます。 openclaw message thread createでスレッドを直接作成。フォーラムチャンネルでは--message-idを渡さないでください。
例:フォーラム親に送信してスレッドを作成
openclaw message send --channel discord --target channel:<forumId> \
--message "Topic title\nBody of the post"
例:フォーラムスレッドを明示的に作成
openclaw message thread create --channel discord --target channel:<forumId> \
--thread-name "Topic title" --message "Body of the post"
フォーラム親はDiscordコンポーネントを受け付けません。コンポーネントが必要な場合は、スレッド自体(channel:<threadId>)に送信してください。
インタラクティブコンポーネント
OpenClawはエージェントメッセージにDiscord コンポーネントv2コンテナをサポートしています。メッセージツールで components ペイロードを使用してください。インタラクション結果は通常の着信メッセージとしてエージェントにルーティングされ、既存のDiscord replyToMode 設定に従います。
サポートされるブロック:
text、section、separator、actions、media-gallery、file- アクション行には最大5つのボタンまたは1つのセレクトメニュー
- セレクトタイプ:
string、user、role、mentionable、channel
デフォルトでコンポーネントは1回限りの使用です。components.reusable=true を設定すると、ボタン、セレクト、フォームを期限切れまで複数回使用できます。
ボタンをクリックできるユーザーを制限するには、ボタンに allowedUsers を設定します(DiscordユーザーID、タグ、または *)。設定時、一致しないユーザーにはエフェメラルな拒否メッセージが表示されます。
/model と /models スラッシュコマンドは、プロバイダーとモデルのドロップダウンおよびSubmitステップを持つインタラクティブなモデルピッカーを開きます。ピッカーの返信はエフェメラルで、呼び出したユーザーのみ使用できます。
ファイル添付:
fileブロックは添付参照(attachment://<filename>)を指す必要がありますmedia/path/filePath(単一ファイル)で添付を提供。複数ファイルにはmedia-galleryを使用filenameでアップロード名をオーバーライドし、添付参照と一致させます
モーダルフォーム:
components.modalに最大5つのフィールドを追加- フィールドタイプ:
text、checkbox、radio、select、role-select、user-select - OpenClawはトリガーボタンを自動的に追加します
例:
{
channel: "discord",
action: "send",
to: "channel:123456789012345678",
message: "Optional fallback text",
components: {
reusable: true,
text: "Choose a path",
blocks: [
{
type: "actions",
buttons: [
{
label: "Approve",
style: "success",
allowedUsers: ["123456789012345678"],
},
{ label: "Decline", style: "danger" },
],
},
{
type: "actions",
select: {
type: "string",
placeholder: "Pick an option",
options: [
{ label: "Option A", value: "a" },
{ label: "Option B", value: "b" },
],
},
},
],
modal: {
title: "Details",
triggerLabel: "Open form",
fields: [
{ type: "text", label: "Requester" },
{
type: "select",
label: "Priority",
options: [
{ label: "Low", value: "low" },
{ label: "High", value: "high" },
],
},
],
},
},
}
アクセス制御とルーティング
DMポリシー
`channels.discord.dmPolicy` でDMアクセスを制御します(レガシー:`channels.discord.dm.policy`):
- `pairing`(デフォルト)
- `allowlist`
- `open`(`channels.discord.allowFrom` に `"*"` を含める必要あり。レガシー:`channels.discord.dm.allowFrom`)
- `disabled`
DMポリシーがopenでない場合、不明なユーザーはブロックされます(`pairing` モードではペアリングプロンプトが表示されます)。
マルチアカウントの優先順位:
- `channels.discord.accounts.default.allowFrom` は `default` アカウントにのみ適用されます。
- 名前付きアカウントは自身の `allowFrom` が未設定の場合、`channels.discord.allowFrom` を継承します。
- 名前付きアカウントは `channels.discord.accounts.default.allowFrom` を継承しません。
DM配信先のターゲット形式:
- `user:<id>`
- `<@id>` メンション
数値のみのIDは曖昧であり、明示的なuser/channelターゲット種別が指定されない限り拒否されます。
ギルドポリシー
ギルドの処理は `channels.discord.groupPolicy` で制御されます:
- `open`
- `allowlist`
- `disabled`
`channels.discord` が存在する場合のセキュアベースラインは `allowlist` です。
`allowlist` の動作:
- ギルドが `channels.discord.guilds` に一致する必要があります(`id` 推奨、スラッグも可)
- 任意の送信者許可リスト:`users`(安定したIDを推奨)および `roles`(ロールIDのみ)。いずれかが設定されている場合、送信者は `users` または `roles` に一致すれば許可されます
- 名前/タグによる直接マッチングはデフォルトで無効。互換性のためのブレークグラスとして `channels.discord.dangerouslyAllowNameMatching: true` でのみ有効化してください
- `users` では名前/タグもサポートされていますが、IDの方が安全です。`openclaw security audit` は名前/タグエントリ使用時に警告します
- ギルドに `channels` が設定されている場合、リストにないチャンネルは拒否されます
- ギルドに `channels` ブロックがない場合、その許可リスト内ギルドのすべてのチャンネルが許可されます
例:
{
channels: {
discord: {
groupPolicy: "allowlist",
guilds: {
"123456789012345678": {
requireMention: true,
ignoreOtherMentions: true,
users: ["987654321098765432"],
roles: ["123456789012345678"],
channels: {
general: { allow: true },
help: { allow: true, requireMention: true },
},
},
},
},
},
}
`DISCORD_BOT_TOKEN` のみ設定して `channels.discord` ブロックを作成しない場合、`channels.defaults.groupPolicy` が `open` であっても、ランタイムフォールバックは `groupPolicy="allowlist"`(ログに警告)となります。
メンションとグループDM
ギルドメッセージはデフォルトでメンションゲートされます。
メンション検出の対象:
- 明示的なBotメンション
- 設定されたメンションパターン(`agents.list[].groupChat.mentionPatterns`、フォールバック `messages.groupChat.mentionPatterns`)
- サポートされるケースでの暗黙的なリプライ先Bot動作
`requireMention` はギルド/チャンネルごとに設定されます(`channels.discord.guilds...`)。
`ignoreOtherMentions` は、他のユーザー/ロールをメンションしているがBotをメンションしていないメッセージを任意でドロップします(@everyone/@hereを除く)。
グループDM:
- デフォルト:無視(`dm.groupEnabled=false`)
- `dm.groupChannels`(チャンネルIDまたはスラッグ)による任意の許可リスト
ロールベースのエージェントルーティング
bindings[].match.roles を使用して、DiscordギルドメンバーをロールIDに基づいて異なるエージェントにルーティングします。ロールベースのバインディングはロールIDのみを受け付け、peerまたはparent-peerバインディングの後、ギルドのみのバインディングの前に評価されます。バインディングが他のマッチフィールド(例:peer + guildId + roles)も設定している場合、設定されたすべてのフィールドが一致する必要があります。
{
bindings: [
{
agentId: "opus",
match: {
channel: "discord",
guildId: "123456789012345678",
roles: ["111111111111111111"],
},
},
{
agentId: "sonnet",
match: {
channel: "discord",
guildId: "123456789012345678",
},
},
],
}
Developer Portalセットアップ
アプリとBotの作成
1. Discord Developer Portal -> **Applications** -> **New Application**
2. **Bot** -> **Add Bot**
3. Botトークンをコピー
特権インテント
**Bot -> Privileged Gateway Intents** で以下を有効にします:
- Message Content Intent
- Server Members Intent(推奨)
Presenceインテントは任意で、メンバーのプレゼンス更新を受信する場合のみ必要です。Botのプレゼンス設定(`setPresence`)にはメンバーのプレゼンス更新の有効化は不要です。
OAuthスコープとベースライン権限
OAuth URLジェネレーター:
- スコープ:`bot`、`applications.commands`
一般的なベースライン権限:
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions(任意)
明示的に必要でない限り、`Administrator` は避けてください。
IDのコピー
Discord開発者モードを有効にして、以下をコピーします:
- サーバーID
- チャンネルID
- ユーザーID
信頼性の高い監査とプローブのため、OpenClaw設定では数値IDを推奨します。
ネイティブコマンドとコマンド認証
commands.nativeのデフォルトは"auto"で、Discordでは有効です。- チャンネルごとのオーバーライド:
channels.discord.commands.native commands.native=falseは以前に登録されたDiscordネイティブコマンドを明示的にクリアします。- ネイティブコマンド認証は、通常のメッセージ処理と同じDiscord許可リスト/ポリシーを使用します。
- コマンドは認可されていないユーザーにもDiscord UIで表示される場合がありますが、実行時にOpenClaw認証が適用され「not authorized」が返されます。
詳細はスラッシュコマンドを参照してください。
デフォルトのスラッシュコマンド設定:
ephemeral: true
機能詳細
返信タグとネイティブリプライ
Discordはエージェント出力で返信タグをサポートしています:
- `[[reply_to_current]]`
- `[[reply_to:<id>]]`
`channels.discord.replyToMode` で制御されます:
- `off`(デフォルト)
- `first`
- `all`
注意:`off` は暗黙的なリプライスレッドを無効にします。明示的な `[[reply_to_*]]` タグは引き続き尊重されます。
メッセージIDはコンテキスト/履歴で公開されるため、エージェントは特定のメッセージをターゲットにできます。
ライブストリームプレビュー
OpenClawは一時的なメッセージを送信し、テキストが到着するにつれて編集することで、ドラフト返信をストリームできます。
- `channels.discord.streaming` でプレビューストリーミングを制御します(`off` | `partial` | `block` | `progress`、デフォルト:`off`)。
- `progress` はクロスチャンネルの一貫性のために受け付けられ、Discordでは `partial` にマッピングされます。
- `channels.discord.streamMode` はレガシーエイリアスで、自動移行されます。
- `partial` はトークン到着に応じて単一のプレビューメッセージを編集します。
- `block` はドラフトサイズのチャンクを出力します(`draftChunk` でサイズとブレークポイントを調整)。
例:
{
channels: {
discord: {
streaming: "partial",
},
},
}
`block` モードのチャンキングデフォルト(`channels.discord.textChunkLimit` に制限):
{
channels: {
discord: {
streaming: "block",
draftChunk: {
minChars: 200,
maxChars: 800,
breakPreference: "paragraph",
},
},
},
}
プレビューストリーミングはテキストのみです。メディア返信は通常の配信にフォールバックします。
注意:プレビューストリーミングはブロックストリーミングとは別物です。Discordでブロックストリーミングが明示的に有効な場合、OpenClawは二重ストリーミングを避けるためプレビューストリームをスキップします。
履歴、コンテキスト、スレッドの動作
ギルド履歴コンテキスト:
- `channels.discord.historyLimit` デフォルト `20`
- フォールバック:`messages.groupChat.historyLimit`
- `0` で無効化
DM履歴制御:
- `channels.discord.dmHistoryLimit`
- `channels.discord.dms["<user_id>"].historyLimit`
スレッドの動作:
- Discordスレッドはチャンネルセッションとしてルーティングされます
- 親スレッドのメタデータは親セッションリンケージに使用できます
- スレッド設定はスレッド固有のエントリが存在しない限り、親チャンネル設定を継承します
チャンネルトピックは**信頼されない**コンテキストとして注入されます(システムプロンプトとしてではありません)。
サブエージェント用スレッドバウンドセッション
Discordはスレッドをセッションターゲットにバインドでき、そのスレッド内のフォローアップメッセージが同じセッション(サブエージェントセッションを含む)にルーティングされ続けます。
コマンド:
- `/focus <target>` 現在/新規スレッドをサブエージェント/セッションターゲットにバインド
- `/unfocus` 現在のスレッドバインディングを解除
- `/agents` アクティブな実行とバインディング状態を表示
- `/session idle <duration|off>` フォーカスバインディングの非活動自動アンフォーカスを確認/更新
- `/session max-age <duration|off>` フォーカスバインディングのハード最大期間を確認/更新
設定:
{
session: {
threadBindings: {
enabled: true,
idleHours: 24,
maxAgeHours: 0,
},
},
channels: {
discord: {
threadBindings: {
enabled: true,
idleHours: 24,
maxAgeHours: 0,
spawnSubagentSessions: false, // opt-in
},
},
},
}
注意事項:
- `session.threadBindings.*` はグローバルデフォルトを設定します。
- `channels.discord.threadBindings.*` はDiscordの動作をオーバーライドします。
- `spawnSubagentSessions` は `sessions_spawn({ thread: true })` 用のスレッド自動作成/バインドに `true` が必要です。
- `spawnAcpSessions` はACP(`/acp spawn ... --thread ...` または `sessions_spawn({ runtime: "acp", thread: true })`)用のスレッド自動作成/バインドに `true` が必要です。
- アカウントでスレッドバインディングが無効な場合、`/focus` および関連操作は利用できません。
[サブエージェント](/docs/tools/subagents)、[ACPエージェント](/docs/tools/acp-agents)、[設定リファレンス](/docs/gateway/configuration-reference)を参照してください。
永続的ACPチャンネルバインディング
安定した「常時稼働」ACPワークスペースには、Discordの会話をターゲットとするトップレベルの型付きACPバインディングを設定します。
設定パス:
- `bindings[]` に `type: "acp"` と `match.channel: "discord"` を指定
例:
{
agents: {
list: [
{
id: "codex",
runtime: {
type: "acp",
acp: {
agent: "codex",
backend: "acpx",
mode: "persistent",
cwd: "/workspace/openclaw",
},
},
},
],
},
bindings: [
{
type: "acp",
agentId: "codex",
match: {
channel: "discord",
accountId: "default",
peer: { kind: "channel", id: "222222222222222222" },
},
acp: { label: "codex-main" },
},
],
channels: {
discord: {
guilds: {
"111111111111111111": {
channels: {
"222222222222222222": {
requireMention: false,
},
},
},
},
},
},
}
注意事項:
- スレッドメッセージは親チャンネルのACPバインディングを継承できます。
- バインドされたチャンネルまたはスレッドでは、`/new` と `/reset` は同じACPセッションをその場でリセットします。
- 一時的なスレッドバインディングは引き続き動作し、アクティブな間はターゲット解決をオーバーライドできます。
バインディング動作の詳細は[ACPエージェント](/docs/tools/acp-agents)を参照してください。
リアクション通知
ギルドごとのリアクション通知モード:
- `off`
- `own`(デフォルト)
- `all`
- `allowlist`(`guilds.<id>.users` を使用)
リアクションイベントはシステムイベントに変換され、ルーティングされたDiscordセッションに添付されます。
確認リアクション
`ackReaction` は、OpenClawが着信メッセージを処理中に確認絵文字を送信します。
解決順序:
- `channels.discord.accounts.<accountId>.ackReaction`
- `channels.discord.ackReaction`
- `messages.ackReaction`
- エージェントIDの絵文字フォールバック(`agents.list[].identity.emoji`、なければ"👀")
注意事項:
- DiscordはUnicode絵文字またはカスタム絵文字名を受け付けます。
- `""` を使用してチャンネルまたはアカウントのリアクションを無効にできます。
設定の書き込み
チャンネルからの設定書き込みはデフォルトで有効です。
これは `/config set|unset` フロー(コマンド機能が有効な場合)に影響します。
無効化:
{
channels: {
discord: {
configWrites: false,
},
},
}
Gatewayプロキシ
`channels.discord.proxy` でDiscord GatewayのWebSocketトラフィックと起動時のREST検索(アプリケーションID + 許可リスト解決)をHTTP(S)プロキシ経由でルーティングします。
{
channels: {
discord: {
proxy: "http://proxy.example:8080",
},
},
}
アカウントごとのオーバーライド:
{
channels: {
discord: {
accounts: {
primary: {
proxy: "http://proxy.example:8080",
},
},
},
},
}
PluralKitサポート
PluralKit解決を有効にして、プロキシされたメッセージをシステムメンバーIDにマッピングします:
{
channels: {
discord: {
pluralkit: {
enabled: true,
token: "pk_live_...", // 任意。プライベートシステムに必要
},
},
},
}
注意事項:
- 許可リストで `pk:<memberId>` を使用できます
- メンバー表示名は `channels.discord.dangerouslyAllowNameMatching: true` の場合のみ名前/スラッグでマッチされます
- 検索は元のメッセージIDを使用し、タイムウィンドウ制約があります
- 検索が失敗した場合、プロキシされたメッセージはBotメッセージとして扱われ、`allowBots=true` でない限りドロップされます
プレゼンス設定
ステータスまたはアクティビティフィールドを設定するか、自動プレゼンスを有効にすると、プレゼンス更新が適用されます。
ステータスのみの例:
{
channels: {
discord: {
status: "idle",
},
},
}
アクティビティの例(カスタムステータスがデフォルトのアクティビティタイプ):
{
channels: {
discord: {
activity: "Focus time",
activityType: 4,
},
},
}
配信の例:
{
channels: {
discord: {
activity: "Live coding",
activityType: 1,
activityUrl: "https://twitch.tv/openclaw",
},
},
}
アクティビティタイプマップ:
- 0: Playing
- 1: Streaming(`activityUrl` が必要)
- 2: Listening
- 3: Watching
- 4: Custom(アクティビティテキストをステータス状態として使用。絵文字は任意)
- 5: Competing
自動プレゼンスの例(ランタイムヘルスシグナル):
{
channels: {
discord: {
autoPresence: {
enabled: true,
intervalMs: 30000,
minUpdateIntervalMs: 15000,
exhaustedText: "token exhausted",
},
},
},
}
自動プレゼンスはランタイムの利用可能状態をDiscordステータスにマッピングします:healthy => online、degraded/unknown => idle、exhausted/unavailable => dnd。テキストのオーバーライド(任意):
- `autoPresence.healthyText`
- `autoPresence.degradedText`
- `autoPresence.exhaustedText`(`{reason}` プレースホルダーサポート)
Discordでのexec承認
DiscordはDMでのボタンベースのexec承認をサポートし、発信元チャンネルに承認プロンプトをオプションで投稿できます。
設定パス:
- `channels.discord.execApprovals.enabled`
- `channels.discord.execApprovals.approvers`
- `channels.discord.execApprovals.target`(`dm` | `channel` | `both`、デフォルト:`dm`)
- `agentFilter`、`sessionFilter`、`cleanupAfterResolve`
`target` が `channel` または `both` の場合、承認プロンプトはチャンネルに表示されます。設定された承認者のみがボタンを使用でき、他のユーザーにはエフェメラルな拒否が表示されます。承認プロンプトにはコマンドテキストが含まれるため、信頼できるチャンネルでのみチャンネル配信を有効にしてください。セッションキーからチャンネルIDを導出できない場合、OpenClawはDM配信にフォールバックします。
このハンドラーのGateway認証は、他のGatewayクライアントと同じ共有認証情報解決規約を使用します:
- env優先のローカル認証(`OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD`、次に `gateway.auth.*`)
- ローカルモードでは、`gateway.auth.*` が未設定の場合のみ `gateway.remote.*` をフォールバックとして使用可能。設定済みだが解決されないローカルSecretRefはフェイルクローズ
- 該当する場合、`gateway.remote.*` によるリモートモードサポート
- URLオーバーライドはオーバーライドセーフ:CLIオーバーライドは暗黙的な認証情報を再利用せず、envオーバーライドはenv認証情報のみを使用
不明な承認IDで承認が失敗する場合は、承認者リストと機能の有効化を確認してください。
関連ドキュメント:[exec承認](/docs/tools/exec-approvals)
ツールとアクションゲート
Discordメッセージアクションには、メッセージング、チャンネル管理、モデレーション、プレゼンス、メタデータアクションが含まれます。
主な例:
- メッセージング:
sendMessage、readMessages、editMessage、deleteMessage、threadReply - リアクション:
react、reactions、emojiList - モデレーション:
timeout、kick、ban - プレゼンス:
setPresence
アクションゲートは channels.discord.actions.* に配置されます。
デフォルトのゲート動作:
| アクショングループ | デフォルト |
|---|---|
| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | 有効 |
| roles | 無効 |
| moderation | 無効 |
| presence | 無効 |
コンポーネントv2 UI
OpenClawはexec承認とクロスコンテキストマーカーにDiscordコンポーネントv2を使用します。Discordメッセージアクションでもカスタム UIとして components を受け付けることができます(高度な使用。Carbonコンポーネントインスタンスが必要)。レガシーの embeds も利用可能ですが、推奨されません。
channels.discord.ui.components.accentColorはDiscordコンポーネントコンテナで使用されるアクセントカラーを設定します(16進数)。- アカウントごとの設定:
channels.discord.accounts.<id>.ui.components.accentColor - コンポーネントv2が存在する場合、
embedsは無視されます。
例:
{
channels: {
discord: {
ui: {
components: {
accentColor: "#5865F2",
},
},
},
},
}
ボイスチャンネル
OpenClawはDiscordボイスチャンネルに参加して、リアルタイムの連続会話を行うことができます。これはボイスメッセージの添付とは別の機能です。
要件:
- ネイティブコマンドを有効にする(
commands.nativeまたはchannels.discord.commands.native)。 channels.discord.voiceを設定する。- BotにターゲットボイスチャンネルのConnect + Speak権限が必要です。
Discord専用のネイティブコマンド /vc join|leave|status でセッションを制御します。このコマンドはアカウントデフォルトエージェントを使用し、他のDiscordコマンドと同じ許可リストとグループポリシールールに従います。
自動参加の例:
{
channels: {
discord: {
voice: {
enabled: true,
autoJoin: [
{
guildId: "123456789012345678",
channelId: "234567890123456789",
},
],
daveEncryption: true,
decryptionFailureTolerance: 24,
tts: {
provider: "openai",
openai: { voice: "alloy" },
},
},
},
},
}
注意事項:
voice.ttsはボイス再生専用でmessages.ttsをオーバーライドします。- ボイストランスクリプトのターンはDiscord
allowFrom(またはdm.allowFrom)からオーナーステータスを判定します。非オーナーの発話者はオーナー専用ツール(例:gateway、cron)にアクセスできません。 - ボイスはデフォルトで有効です。
channels.discord.voice.enabled=falseで無効化できます。 voice.daveEncryptionとvoice.decryptionFailureToleranceは@discordjs/voiceのjoinオプションにパススルーされます。@discordjs/voiceのデフォルトは、未設定の場合daveEncryption=trueとdecryptionFailureTolerance=24です。- OpenClawは受信の復号失敗を監視し、短時間に繰り返し失敗した場合、ボイスチャンネルの退出/再参加で自動回復します。
- 受信ログに
DecryptionFailed(UnencryptedWhenPassthroughDisabled)が繰り返し表示される場合、discord.js #11419 で追跡されている上流の@discordjs/voice受信バグの可能性があります。
ボイスメッセージ
Discordのボイスメッセージは波形プレビューを表示し、OGG/Opusオーディオとメタデータが必要です。OpenClawは波形を自動生成しますが、Gatewayホストで ffmpeg と ffprobe が利用可能である必要があります。
要件と制約:
- ローカルファイルパスを提供してください(URLは拒否されます)。
- テキストコンテンツは省略してください(Discordでは同一ペイロードにテキスト + ボイスメッセージを含められません)。
- 任意のオーディオフォーマットを受け付けます。OpenClawは必要に応じてOGG/Opusに変換します。
例:
message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)
トラブルシューティング
不許可のインテント使用またはBotがギルドメッセージを受信しない
- Message Content Intentを有効にしてください
- ユーザー/メンバー解決に依存する場合はServer Members Intentを有効にしてください
- インテント変更後にGatewayを再起動してください
ギルドメッセージが予期せずブロックされる
- `groupPolicy` を確認
- `channels.discord.guilds` のギルド許可リストを確認
- ギルドに `channels` マップが存在する場合、リストされたチャンネルのみ許可
- `requireMention` の動作とメンションパターンを確認
診断コマンド:
openclaw doctor
openclaw channels status --probe
openclaw logs --follow
requireMentionがfalseなのにブロックされる
よくある原因:
- `groupPolicy="allowlist"` でギルド/チャンネル許可リストが未設定
- `requireMention` が間違った場所に設定されている(`channels.discord.guilds` またはチャンネルエントリ内に設定する必要があります)
- 送信者がギルド/チャンネルの `users` 許可リストでブロックされている
長時間実行ハンドラーのタイムアウトまたは重複返信
典型的なログ:
- `Listener DiscordMessageListener timed out after 30000ms for event MESSAGE_CREATE`
- `Slow 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` で無効化
推奨ベースライン:
{
channels: {
discord: {
accounts: {
default: {
eventQueue: {
listenerTimeout: 120000,
},
inboundWorker: {
runTimeoutMs: 1800000,
},
},
},
},
},
}
`eventQueue.listenerTimeout` はリスナーのセットアップ遅延用、`inboundWorker.runTimeoutMs` はキューイングされたエージェントターンの安全弁として必要な場合のみ使用してください。
権限監査の不一致
`channels status --probe` の権限チェックは数値チャンネルIDでのみ機能します。
スラッグキーを使用している場合、ランタイムマッチングは動作しますが、プローブでは権限を完全に検証できません。
DMとペアリングの問題
- DM無効:`channels.discord.dm.enabled=false`
- DMポリシー無効:`channels.discord.dmPolicy="disabled"`(レガシー:`channels.discord.dm.policy`)
- `pairing` モードでペアリング承認待ち
Bot間のループ
デフォルトではBot作成のメッセージは無視されます。
`channels.discord.allowBots=true` を設定する場合は、ループを防ぐために厳格なメンションと許可リストルールを使用してください。
Botをメンションしたメッセージのみを受け付けるには `channels.discord.allowBots="mentions"` を推奨します。
ボイスSTTのDecryptionFailed(...)ドロップ
- OpenClawを最新に保ってください(`openclaw update`)。Discord ボイス受信回復ロジックが含まれます
- `channels.discord.voice.daveEncryption=true`(デフォルト)を確認
- `channels.discord.voice.decryptionFailureTolerance=24`(上流デフォルト)から開始し、必要に応じてのみ調整
- ログで以下を監視:
- `discord voice: DAVE decrypt failures detected`
- `discord voice: repeated decrypt failures; attempting rejoin`
- 自動再参加後も失敗が続く場合は、ログを収集して [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419) と比較してください
設定リファレンスポインタ
主要リファレンス:
重要なDiscordフィールド:
- 起動/認証:
enabled、token、accounts.*、allowBots - ポリシー:
groupPolicy、dm.*、guilds.*、guilds.*.channels.* - コマンド:
commands.native、commands.useAccessGroups、configWrites、slashCommand.* - イベントキュー:
eventQueue.listenerTimeout(リスナーバジェット)、eventQueue.maxQueueSize、eventQueue.maxConcurrency - インバウンドワーカー:
inboundWorker.runTimeoutMs - 返信/履歴:
replyToMode、historyLimit、dmHistoryLimit、dms.*.historyLimit - 配信:
textChunkLimit、chunkMode、maxLinesPerMessage - ストリーミング:
streaming(レガシーエイリアス:streamMode)、draftChunk、blockStreaming、blockStreamingCoalesce - メディア/リトライ:
mediaMaxMb、retrymediaMaxMbはアウトバウンドDiscordアップロードを制限します(デフォルト:8MB)
- アクション:
actions.* - プレゼンス:
activity、status、activityType、activityUrl - UI:
ui.components.accentColor - 機能:
threadBindings、トップレベルbindings[](type: "acp")、pluralkit、execApprovals、intents、agentComponents、heartbeat、responsePrefix
セキュリティと運用
- Botトークンはシークレットとして扱ってください(管理環境では
DISCORD_BOT_TOKEN推奨)。 - Discord権限は最小権限を付与してください。
- コマンドのデプロイ/状態が古い場合は、Gatewayを再起動して
openclaw channels status --probeで再確認してください。