メインコンテンツへスキップ

Discord (Bot API)

ステータス: 公式Discord Gateway経由のDMおよびguild channelに対応済みです。

ペアリング

Discord DMはデフォルトでペアリングモードになります。

スラッシュコマンド

ネイティブコマンドの動作とコマンドカタログ。

channelのトラブルシューティング

channel横断の診断と修復フロー。

クイックセットアップ

新しいアプリケーションとbotを作成し、そのbotをサーバーに追加して、OpenClawとペアリングする必要があります。botは自分専用のプライベートサーバーに追加することをおすすめします。まだ持っていない場合は、まず作成してくださいCreate My Own > For me and my friendsを選択)。
1

Discordアプリケーションとbotを作成する

Discord Developer Portalにアクセスして、New Applicationをクリックします。「OpenClaw」のような名前を付けてください。サイドバーのBotをクリックします。Usernameを、自分のOpenClaw agentの呼び名に設定します。
2

特権intentを有効にする

引き続きBotページで、下にスクロールしてPrivileged Gateway Intentsに移動し、次を有効にします。
  • Message Content Intent(必須)
  • Server Members Intent(推奨。role allowlistと名前からIDへの照合に必要)
  • Presence Intent(任意。presence更新が必要な場合のみ)
3

bot tokenをコピーする

Botページの上部に戻り、Reset Tokenをクリックします。
名前に反して、これは最初のtokenを生成します。何かが「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

Developer Modeを有効にしてIDを収集する

Discordアプリに戻り、内部IDをコピーできるようにDeveloper Modeを有効にする必要があります。
  1. User Settings(アバター横の歯車アイコン)→ AdvancedDeveloper Modeをオンにする
  2. サイドバーのserver iconを右クリック → Copy Server ID
  3. 自分のavatarを右クリック → Copy User ID
Server IDUser IDをBot Tokenと一緒に保存してください。次の手順で、この3つすべてをOpenClawに送ります。
6

サーバーメンバーからのDMを許可する

ペアリングを機能させるには、Discordでbotから自分へのDMを許可する必要があります。server iconを右クリック → Privacy SettingsDirect Messagesをオンにします。これにより、サーバーメンバー(botを含む)が自分にDMを送れるようになります。OpenClawでDiscord DMを使いたい場合は、これを有効のままにしてください。guild channelsだけを使う予定なら、ペアリング後にDMを無効にしてもかまいません。
7

bot tokenを安全に設定する(chatで送信しない)

Discord bot tokenはシークレットです(パスワードのようなものです)。agentにメッセージを送る前に、OpenClawを実行しているマシンで設定してください。
export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN"
openclaw config set channels.discord.token --ref-provider default --ref-source env --ref-id DISCORD_BOT_TOKEN --dry-run
openclaw config set channels.discord.token --ref-provider default --ref-source env --ref-id DISCORD_BOT_TOKEN
openclaw config set channels.discord.enabled true --strict-json
openclaw gateway
OpenClawがすでにバックグラウンドサービスとして動作している場合は、OpenClaw Mac appから、またはopenclaw gateway runプロセスを停止して再起動してください。
8

OpenClawを設定してペアリングする

既存の任意のchannel(例: Telegram)でOpenClaw agentと会話し、設定を依頼してください。Discordが最初のchannelである場合は、代わりにCLI / configタブを使用してください。
「Discord bot tokenはすでにconfigに設定しました。User ID <user_id> と Server ID <server_id> を使ってDiscordのセットアップを完了してください。」
9

最初のDMペアリングを承認する

Gatewayが実行中になるまで待ってから、DiscordでbotにDMしてください。botがペアリングコードを返します。
既存のchannel上のagentにペアリングコードを送信します。
「このDiscordペアリングコードを承認してください: <CODE>
ペアリングコードの有効期限は1時間です。これでDiscord上でDM経由でagentと会話できるようになります。
token解決はaccount対応です。config内のtoken値がenvフォールバックより優先されます。DISCORD_BOT_TOKENはdefault accountでのみ使われます。 高度な送信呼び出し(message tool/channel action)では、呼び出しごとの明示的なtokenがその呼び出しに使用されます。これはsendおよびread/probe系action(たとえばread/search/fetch/thread/pins/permissions)に適用されます。account policy/retry設定は、アクティブなruntime snapshot内で選択されたaccountから引き続き取得されます。

推奨: guild workspaceを設定する

DMが機能したら、Discordサーバーを完全なworkspaceとして設定できます。各channelが独自のコンテキストを持つ独立したagent sessionになります。これは、自分とbotだけのプライベートサーバーにおすすめです。
1

サーバーをguild allowlistに追加する

これにより、agentはDMだけでなく、サーバー上の任意のchannelで応答できるようになります。
「私のDiscord Server ID <server_id> をguild allowlistに追加してください」
2

@mentionなしでの応答を許可する

デフォルトでは、agentはguild channelsでは@mentionされたときだけ応答します。プライベートサーバーなら、おそらくすべてのメッセージに応答させたいはずです。
「このサーバーでは、@mentionしなくてもagentが応答できるようにしてください」
3

guild channelsでのmemory利用を計画する

デフォルトでは、長期memory(MEMORY.md)はDM sessionでのみ読み込まれます。guild channelsではMEMORY.mdは自動読み込みされません。
「Discord channelsで質問するとき、MEMORY.mdの長期コンテキストが必要ならmemory_searchまたはmemory_getを使ってください。」
次に、Discordサーバーにいくつかchannelsを作成して会話を始めてください。agentはchannel名を見ることができ、各channelは独立したsessionを持ちます。そのため、#coding#home#researchなど、ワークフローに合ったものを設定できます。

Runtime model

  • GatewayがDiscord接続を所有します。
  • 返信ルーティングは決定的です。Discordからの受信への返信はDiscordに返されます。
  • デフォルト(session.dmScope=main)では、ダイレクトchatはagentのメインsession(agent:main:main)を共有します。
  • Guild channelsは分離されたsession key(agent:<agentId>:discord:channel:<channelId>)です。
  • Group DMはデフォルトで無視されます(channels.discord.dm.groupEnabled=false)。
  • ネイティブスラッシュコマンドは分離されたコマンドsession(agent:<agentId>:discord:slash:<userId>)で実行されつつ、ルーティング先の会話sessionにはCommandTargetSessionKeyが保持されます。

Forum channels

Discord forumおよびmedia channelsはthread投稿のみ受け付けます。OpenClawはそれらを作成する2つの方法をサポートしています。
  • forum親(channel:<forumId>)にメッセージを送信してthreadを自動作成します。thread titleには、メッセージ内の最初の空でない行が使われます。
  • openclaw message thread createを使って直接threadを作成します。forum channelsでは--message-idを渡さないでください。
例: forum親に送信してthreadを作成する
openclaw message send --channel discord --target channel:<forumId> \
  --message "Topic title\nBody of the post"
例: forum threadを明示的に作成する
openclaw message thread create --channel discord --target channel:<forumId> \
  --thread-name "Topic title" --message "Body of the post"
forum親はDiscord componentsを受け付けません。componentsが必要な場合は、thread自体(channel:<threadId>)に送信してください。

Interactive components

OpenClawは、agentメッセージ向けにDiscord components v2コンテナをサポートしています。componentsペイロード付きでmessage toolを使用してください。interaction結果は通常の受信メッセージとしてagentに返送され、既存のDiscord replyToMode設定に従います。 サポートされるblock:
  • textsectionseparatoractionsmedia-galleryfile
  • action rowでは最大5個のbutton、または単一のselect menuを使用可能
  • select type: stringuserrolementionablechannel
デフォルトでは、componentsは単回使用です。components.reusable=trueを設定すると、button、select、formを有効期限が切れるまで複数回使用できます。 buttonをクリックできるユーザーを制限するには、そのbuttonにallowedUsersを設定します(Discord user ID、tag、または*)。設定されている場合、一致しないユーザーにはephemeralの拒否応答が返されます。 /modelおよび/modelsスラッシュコマンドは、providerとmodelのドロップダウン、およびSubmitステップを備えたinteractive model pickerを開きます。pickerの返信はephemeralで、呼び出したユーザーのみが使用できます。 ファイル添付:
  • file blockは添付参照(attachment://<filename>)を指している必要があります
  • 添付はmedia/path/filePath(単一ファイル)で指定します。複数ファイルにはmedia-galleryを使用してください
  • アップロード名を添付参照と一致させたい場合は、filenameを使って上書きします
Modal form:
  • 最大5フィールドのcomponents.modalを追加します
  • フィールドtype: textcheckboxradioselectrole-selectuser-select
  • OpenClawが自動的にトリガーbuttonを追加します
例:
{
  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" },
          ],
        },
      ],
    },
  },
}

アクセス制御とルーティング

channels.discord.dmPolicyがDMアクセスを制御します(レガシー: channels.discord.dm.policy)。
  • pairing(デフォルト)
  • allowlist
  • openchannels.discord.allowFrom"*"を含める必要があります。レガシー: channels.discord.dm.allowFrom
  • disabled
DMポリシーがopenでない場合、未知のユーザーはブロックされます(pairingモードではペアリングを促されます)。マルチaccountの優先順位:
  • channels.discord.accounts.default.allowFromdefault accountにのみ適用されます。
  • 名前付きaccountsは、自身のallowFromが未設定の場合、channels.discord.allowFromを継承します。
  • 名前付きaccountsはchannels.discord.accounts.default.allowFromを継承しません。
配信時のDM target形式:
  • user:<id>
  • <@id> mention
数字だけのIDは曖昧であり、明示的なuser/channel target種別が指定されていない限り拒否されます。

roleベースのagentルーティング

bindings[].match.rolesを使うと、Discord guild memberをrole IDごとに異なるagentへルーティングできます。roleベースのbindingはrole IDのみ受け付け、peerまたはparent-peer bindingの後、guildのみのbindingの前に評価されます。bindingに他のmatchフィールド(たとえばpeer + guildId + roles)も設定されている場合、設定されたすべてのフィールドが一致する必要があります。
{
  bindings: [
    {
      agentId: "opus",
      match: {
        channel: "discord",
        guildId: "123456789012345678",
        roles: ["111111111111111111"],
      },
    },
    {
      agentId: "sonnet",
      match: {
        channel: "discord",
        guildId: "123456789012345678",
      },
    },
  ],
}

Developer Portalセットアップ

  1. Discord Developer Portal -> Applications -> New Application
  2. Bot -> Add Bot
  3. bot tokenをコピー
Bot -> Privileged Gateway Intentsで、次を有効にします。
  • Message Content Intent
  • Server Members Intent(推奨)
Presence intentは任意で、presence更新を受け取りたい場合にのみ必要です。bot presence(setPresence)の設定自体には、メンバーのpresence更新を有効にする必要はありません。
OAuth URL generator:
  • scope: botapplications.commands
一般的なベースライン権限:
  • View Channels
  • Send Messages
  • Read Message History
  • Embed Links
  • Attach Files
  • Add Reactions(任意)
明示的に必要でない限り、Administratorは避けてください。
Discord Developer Modeを有効にしてから、次をコピーします。
  • server ID
  • channel ID
  • user ID
OpenClaw configでは、信頼性の高いauditとprobeのために数値IDを推奨します。

ネイティブコマンドとコマンド認証

  • commands.nativeのデフォルトは"auto"で、Discordでは有効です。
  • channelごとの上書き: channels.discord.commands.native
  • commands.native=falseは、以前登録されたDiscordネイティブコマンドを明示的にクリアします。
  • ネイティブコマンド認証は、通常のメッセージ処理と同じDiscord allowlist/policyを使用します。
  • 権限のないユーザーにもDiscord UI上ではコマンドが表示されることがありますが、実行時には引き続きOpenClaw認証が適用され、「not authorized」が返されます。
コマンドカタログと挙動については、Slash commandsを参照してください。 デフォルトのスラッシュコマンド設定:
  • ephemeral: true

機能の詳細

Discordはagent出力内の返信タグをサポートします。
  • [[reply_to_current]]
  • [[reply_to:<id>]]
制御するのはchannels.discord.replyToModeです。
  • off(デフォルト)
  • first
  • all
注: offは暗黙的な返信threadingを無効にします。明示的な[[reply_to_*]]タグは引き続き尊重されます。message IDはcontext/historyに含まれるため、agentは特定のメッセージをターゲットにできます。
OpenClawは、一時メッセージを送信し、テキストの到着に応じて編集することで返信ドラフトをストリーミングできます。
  • channels.discord.streamingがプレビューのストリーミングを制御します(off | partial | block | progress、デフォルト: off)。
  • Discordのプレビュー編集はすぐにレート制限に達する可能性があるため、特に複数のbotsやgatewaysが同じaccountやguildトラフィックを共有する場合、デフォルトはoffのままです。
  • progressはchannel間の一貫性のために受け付けられ、Discordではpartialにマップされます。
  • channels.discord.streamModeはレガシーaliasで、自動移行されます。
  • partialは、token到着に合わせて単一のプレビューメッセージを編集します。
  • blockは、ドラフトサイズのチャンクを出力します(サイズと改行位置はdraftChunkで調整します)。
例:
{
  channels: {
    discord: {
      streaming: "partial",
    },
  },
}
blockモードのチャンク分割デフォルト(channels.discord.textChunkLimitでクランプされます):
{
  channels: {
    discord: {
      streaming: "block",
      draftChunk: {
        minChars: 200,
        maxChars: 800,
        breakPreference: "paragraph",
      },
    },
  },
}
プレビューのストリーミングはテキスト専用で、メディア返信は通常の配信にフォールバックします。注: プレビューのストリーミングはblock streamingとは別です。Discordでblock streamingが明示的に 有効になっている場合、OpenClawは二重ストリーミングを避けるためプレビューストリームをスキップします。
Guild履歴コンテキスト:
  • channels.discord.historyLimit デフォルト 20
  • フォールバック: messages.groupChat.historyLimit
  • 0で無効化
DM履歴の制御:
  • channels.discord.dmHistoryLimit
  • channels.discord.dms["<user_id>"].historyLimit
Threadの挙動:
  • Discord threadsはchannel sessionとしてルーティングされます
  • 親threadメタデータは親sessionリンクに使用できます
  • thread固有のエントリがない限り、thread configは親channel configを継承します
channel topicは信頼されていないコンテキストとして注入されます(system promptとしてではありません)。 返信および引用メッセージのコンテキストは、現在のところ受信時のまま保持されます。 Discord allowlistは主に、誰がagentをトリガーできるかを制御するものであり、完全な補助コンテキストの秘匿境界ではありません。
Discordはthreadをsession targetにバインドできるため、そのthread内の後続メッセージは同じsession(subagent sessionを含む)にルーティングされ続けます。コマンド:
  • /focus <target> 現在または新規threadをsubagent/session targetにバインド
  • /unfocus 現在のthread bindingを削除
  • /agents アクティブな実行とbinding状態を表示
  • /session idle <duration|off> フォーカスされたbindingの非アクティブ時自動unfocusを確認/更新
  • /session max-age <duration|off> フォーカスされたbindingのハード最大期間を確認/更新
Config:
{
  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の挙動を上書きします。
  • sessions_spawn({ thread: true })でthreadを自動作成/バインドするには、spawnSubagentSessionsをtrueにする必要があります。
  • ACP(/acp spawn ... --thread ...またはsessions_spawn({ runtime: "acp", thread: true }))でthreadを自動作成/バインドするには、spawnAcpSessionsをtrueにする必要があります。
  • accountでthread bindingが無効になっている場合、/focusおよび関連するthread binding操作は利用できません。
詳細はSub-agentsACP Agents、およびConfiguration Referenceを参照してください。
安定した「常時稼働」ACP workspaceには、Discord会話を対象とするトップレベルの型付きACP bindingを設定します。Configパス:
  • 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 spawn codex --bind hereは、現在のDiscord channelまたはthreadをその場でバインドし、以後のメッセージを同じACP sessionにルーティングし続けます。
  • これは「新しいCodex ACP sessionを開始する」を意味することもありますが、それ自体で新しいDiscord threadを作成するわけではありません。既存のchannelがchat surfaceのままです。
  • Codexは引き続き、ディスク上の独自のcwdまたはbackend workspaceで実行される場合があります。そのworkspaceはruntime stateであり、Discord threadではありません。
  • threadメッセージは親channel ACP bindingを継承できます。
  • バインドされたchannelまたはthreadでは、/new/resetは同じACP sessionをその場でリセットします。
  • 一時的なthread bindingも引き続き機能し、有効な間はtarget解決を上書きできます。
  • spawnAcpSessionsが必要なのは、OpenClawが--thread auto|here経由で子threadを作成/バインドする必要がある場合だけです。現在のchannelでの/acp spawn ... --bind hereには不要です。
binding動作の詳細はACP Agentsを参照してください。
guildごとのリアクション通知モード:
  • off
  • own(デフォルト)
  • all
  • allowlistguilds.<id>.usersを使用)
リアクションイベントはsystem eventに変換され、ルーティング先のDiscord sessionに付加されます。
ackReactionは、OpenClawが受信メッセージを処理している間、確認用の絵文字リアクションを送信します。解決順序:
  • channels.discord.accounts.<accountId>.ackReaction
  • channels.discord.ackReaction
  • messages.ackReaction
  • agent identity絵文字へのフォールバック(agents.list[].identity.emoji、なければ"👀"
注:
  • Discordはunicode絵文字またはカスタム絵文字名を受け付けます。
  • channelまたはaccountでリアクションを無効にするには""を使います。
channel起点のconfig書き込みはデフォルトで有効です。これは/config set|unsetフローに影響します(コマンド機能が有効な場合)。無効にするには:
{
  channels: {
    discord: {
      configWrites: false,
    },
  },
}
channels.discord.proxyを使うと、Discord GatewayのWebSocketトラフィックと、起動時REST参照(application ID + allowlist解決)をHTTP(S)プロキシ経由でルーティングできます。
{
  channels: {
    discord: {
      proxy: "http://proxy.example:8080",
    },
  },
}
accountごとの上書き:
{
  channels: {
    discord: {
      accounts: {
        primary: {
          proxy: "http://proxy.example:8080",
        },
      },
    },
  },
}
proxied messageをsystem member identityにマッピングするPluralKit解決を有効にするには:
{
  channels: {
    discord: {
      pluralkit: {
        enabled: true,
        token: "pk_live_...", // 任意。プライベートsystemに必要
      },
    },
  },
}
注:
  • allowlistではpk:<memberId>を使用できます
  • member display nameは、channels.discord.dangerouslyAllowNameMatching: trueの場合にのみ名前/slugで照合されます
  • lookupは元のmessage IDを使い、時間窓制約があります
  • lookupに失敗すると、proxied messageはbot messageとして扱われ、allowBots=trueでない限り破棄されます
presence更新は、statusまたはactivityフィールドを設定したとき、またはauto presenceを有効にしたときに適用されます。statusのみの例:
{
  channels: {
    discord: {
      status: "idle",
    },
  },
}
activityの例(custom statusがデフォルトのactivity typeです):
{
  channels: {
    discord: {
      activity: "Focus time",
      activityType: 4,
    },
  },
}
streamingの例:
{
  channels: {
    discord: {
      activity: "Live coding",
      activityType: 1,
      activityUrl: "https://twitch.tv/openclaw",
    },
  },
}
activity typeマップ:
  • 0: Playing
  • 1: Streaming(activityUrlが必要)
  • 2: Listening
  • 3: Watching
  • 4: Custom(activityテキストをstatus stateとして使用。絵文字は任意)
  • 5: Competing
auto presenceの例(runtime正常性シグナル):
{
  channels: {
    discord: {
      autoPresence: {
        enabled: true,
        intervalMs: 30000,
        minUpdateIntervalMs: 15000,
        exhaustedText: "token exhausted",
      },
    },
  },
}
auto presenceはruntime可用性をDiscord statusにマッピングします: healthy => online、degradedまたはunknown => idle、exhaustedまたはunavailable => dnd。任意のテキスト上書き:
  • autoPresence.healthyText
  • autoPresence.degradedText
  • autoPresence.exhaustedText{reason}プレースホルダーをサポート)
DiscordはDMでのbuttonベース承認処理をサポートし、必要に応じて元のchannelに承認プロンプトを投稿することもできます。Configパス:
  • channels.discord.execApprovals.enabled
  • channels.discord.execApprovals.approvers(任意。可能な場合はcommands.ownerAllowFromにフォールバック)
  • channels.discord.execApprovals.targetdm | channel | both、デフォルト: dm
  • agentFiltersessionFiltercleanupAfterResolve
Discordは、enabledが未設定または"auto"で、execApprovals.approversまたはcommands.ownerAllowFromから少なくとも1人の承認者を解決できる場合、ネイティブexec approvalsを自動有効化します。Discordは、channel allowFrom、レガシーdm.allowFrom、またはダイレクトメッセージdefaultToからexec approverを推論しません。Discordをネイティブ承認clientとして明示的に無効にするには、enabled: falseを設定してください。targetchannelまたはbothの場合、承認プロンプトはそのchannelに表示されます。buttonを使用できるのは解決済みの承認者のみで、その他のユーザーにはephemeralの拒否応答が返されます。承認プロンプトにはコマンドテキストが含まれるため、channel配信は信頼できるchannelsでのみ有効にしてください。session keyからchannel IDを導出できない場合、OpenClawはDM配信にフォールバックします。Discordは、他のchat channelsで使われる共有承認buttonも描画します。ネイティブDiscord adapterは主に、承認者DMルーティングとchannel fanoutを追加します。 それらのbuttonが存在する場合、それが主要な承認UXです。OpenClaw は、tool resultがchat approvalsを利用できないと示す場合、または 手動承認しか手段がない場合にのみ、手動の/approveコマンドを含めるべきです。このハンドラーのGateway認証は、他のGateway clientsと同じ共有認証情報解決契約を使います。
  • env優先のローカル認証(OPENCLAW_GATEWAY_TOKEN / OPENCLAW_GATEWAY_PASSWORD、次にgateway.auth.*
  • ローカルモードでは、gateway.auth.*が未設定の場合に限りgateway.remote.*をフォールバックとして使用可能。設定済みだが未解決のローカルSecretRefはfail closedします
  • 該当する場合はgateway.remote.*経由のリモートモードサポート
  • URL overrideは安全に上書きされます。CLI overrideは暗黙的な認証情報を再利用せず、env overrideはenv認証情報のみを使用します
承認解決の挙動:
  • plugin:で始まるIDはplugin.approval.resolve経由で解決されます。
  • それ以外のIDはexec.approval.resolve経由で解決されます。
  • Discordはここで追加のexec-to-pluginフォールバックを行いません。id のprefixが、どのgateway methodを呼ぶかを決定します。
Exec approvalsのデフォルト有効期限は30分です。unknown approval IDで承認に失敗する場合は、承認者の解決、機能の有効化、および配信されたapproval id種別が保留中リクエストと一致していることを確認してください。関連ドキュメント: Exec approvals

Toolsとaction gate

Discord message actionsには、メッセージ送信、channel管理、モデレーション、presence、メタデータactionが含まれます。 主な例:
  • messaging: sendMessagereadMessageseditMessagedeleteMessagethreadReply
  • reactions: reactreactionsemojiList
  • moderation: timeoutkickban
  • presence: setPresence
action gateはchannels.discord.actions.*配下にあります。 デフォルトのgate挙動:
Action groupデフォルト
reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissionsenabled
rolesdisabled
moderationdisabled
presencedisabled

Components v2 UI

OpenClawは、exec approvalsおよびクロスコンテキストマーカーにDiscord components v2を使用します。Discord message actionsは、カスタムUI用のcomponentsも受け付けます(高度な用途。discord tool経由でcomponent payloadを構築する必要があります)。一方、レガシーembedsも引き続き利用可能ですが、推奨されません。
  • channels.discord.ui.components.accentColorは、Discord componentコンテナで使用されるアクセントカラー(16進数)を設定します。
  • accountごとの設定はchannels.discord.accounts.<id>.ui.components.accentColor
  • components v2が存在する場合、embedsは無視されます。
例:
{
  channels: {
    discord: {
      ui: {
        components: {
          accentColor: "#5865F2",
        },
      },
    },
  },
}

Voice channels

OpenClawはDiscord voice channelsに参加して、リアルタイムで継続的な会話を行えます。これはvoice message添付とは別機能です。 要件:
  • ネイティブコマンド(commands.nativeまたはchannels.discord.commands.native)を有効にする
  • channels.discord.voiceを設定する
  • botには対象voice channelでのConnect + Speak権限が必要
セッション制御にはDiscord専用ネイティブコマンド/vc join|leave|statusを使用します。このコマンドはaccountのdefault agentを使用し、他のDiscordコマンドと同じallowlistおよびgroup policyルールに従います。 自動参加の例:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        autoJoin: [
          {
            guildId: "123456789012345678",
            channelId: "234567890123456789",
          },
        ],
        daveEncryption: true,
        decryptionFailureTolerance: 24,
        tts: {
          provider: "openai",
          openai: { voice: "alloy" },
        },
      },
    },
  },
}
注:
  • voice.ttsはvoice再生に限ってmessages.ttsを上書きします。
  • voice transcript turnはDiscord allowFrom(またはdm.allowFrom)からowner statusを導出します。ownerでない話者はowner専用tool(たとえばgatewaycron)にアクセスできません。
  • voiceはデフォルトで有効です。無効にするにはchannels.discord.voice.enabled=falseを設定してください。
  • voice.daveEncryptionvoice.decryptionFailureTolerance@discordjs/voiceのjoin optionにそのまま渡されます。
  • @discordjs/voiceのデフォルトは、未設定時にdaveEncryption=trueおよびdecryptionFailureTolerance=24です。
  • OpenClawは受信時のdecrypt failureも監視し、短時間に繰り返し失敗した場合はvoice channelから離脱・再参加して自動復旧します。
  • 受信ログにDecryptionFailed(UnencryptedWhenPassthroughDisabled)が繰り返し表示される場合、これはdiscord.js #11419で追跡されている上流の@discordjs/voice受信バグの可能性があります。

Voice messages

Discordのvoice messageは波形プレビューを表示し、OGG/Opus音声とメタデータが必要です。OpenClawは波形を自動生成しますが、音声ファイルの検査と変換のためにGateway host上でffmpegffprobeが利用可能である必要があります。 要件と制約:
  • ローカルファイルパスを指定してください(URLは拒否されます)。
  • テキスト内容は省略してください(Discordは同一payloadでテキスト + voice messageを許可していません)。
  • 任意の音声形式を受け付けます。必要に応じてOpenClawがOGG/Opusに変換します。
例:
message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)

トラブルシューティング

  • Message Content Intentを有効にする
  • user/member解決に依存する場合はServer Members Intentを有効にする
  • intent変更後はgatewayを再起動する
  • groupPolicyを確認する
  • channels.discord.guilds配下のguild allowlistを確認する
  • guildにchannelsマップがある場合、一覧にあるchannelsのみ許可される
  • requireMentionの挙動とmentionパターンを確認する
便利な確認コマンド:
openclaw doctor
openclaw channels status --probe
openclaw logs --follow
よくある原因:
  • guild/channel allowlistに一致しないままgroupPolicy="allowlist"になっている
  • requireMentionの設定場所が誤っている(channels.discord.guildsまたはchannel entryの配下である必要があります)
  • 送信者がguild/channel users allowlistでブロックされている
典型的なログ:
  • Listener DiscordMessageListener timed out after 30000ms for event MESSAGE_CREATE
  • Slow listener detected ...
  • discord inbound worker timed out after ...
Listener予算のノブ:
  • 単一account: channels.discord.eventQueue.listenerTimeout
  • マルチaccount: channels.discord.accounts.<accountId>.eventQueue.listenerTimeout
Worker実行タイムアウトのノブ:
  • 単一account: channels.discord.inboundWorker.runTimeoutMs
  • マルチaccount: channels.discord.accounts.<accountId>.inboundWorker.runTimeoutMs
  • デフォルト: 1800000(30分)。無効にするには0を設定
推奨ベースライン:
{
  channels: {
    discord: {
      accounts: {
        default: {
          eventQueue: {
            listenerTimeout: 120000,
          },
          inboundWorker: {
            runTimeoutMs: 1800000,
          },
        },
      },
    },
  },
}
eventQueue.listenerTimeoutはlistenerセットアップが遅い場合に使い、inboundWorker.runTimeoutMs は、キューに入ったagent turnに対する別の安全弁が必要な場合にのみ使ってください。
channels status --probeの権限チェックは、数値channel IDでのみ機能します。slug keyを使っている場合でもruntime照合は動作しますが、probeでは権限を完全には検証できません。
  • DM無効: channels.discord.dm.enabled=false
  • DMポリシー無効: channels.discord.dmPolicy="disabled"(レガシー: channels.discord.dm.policy
  • pairingモードでペアリング承認待ち
デフォルトでは、bot作成メッセージは無視されます。channels.discord.allowBots=trueを設定する場合は、ループ動作を避けるため、厳格なmentionおよびallowlistルールを使用してください。 botをmentionしたbot messageのみ受け入れるには、channels.discord.allowBots="mentions"を推奨します。
  • Discord voice受信の復旧ロジックが含まれるよう、OpenClawを最新に保つ(openclaw update
  • 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と比較してください

設定リファレンスへのポインタ

主要リファレンス: シグナルの強いDiscordフィールド:
  • startup/auth: enabledtokenaccounts.*allowBots
  • policy: groupPolicydm.*guilds.*guilds.*.channels.*
  • command: commands.nativecommands.useAccessGroupsconfigWritesslashCommand.*
  • event queue: eventQueue.listenerTimeout(listener予算)、eventQueue.maxQueueSizeeventQueue.maxConcurrency
  • inbound worker: inboundWorker.runTimeoutMs
  • reply/history: replyToModehistoryLimitdmHistoryLimitdms.*.historyLimit
  • delivery: textChunkLimitchunkModemaxLinesPerMessage
  • streaming: streaming(レガシーalias: streamMode)、draftChunkblockStreamingblockStreamingCoalesce
  • media/retry: mediaMaxMbretry
    • mediaMaxMbは送信するDiscordアップロードの上限を設定します(デフォルト: 8MB
  • actions: actions.*
  • presence: activitystatusactivityTypeactivityUrl
  • UI: ui.components.accentColor
  • features: threadBindings、トップレベルbindings[]type: "acp")、pluralkitexecApprovalsintentsagentComponentsheartbeatresponsePrefix

安全性と運用

  • bot tokenはシークレットとして扱ってください(監視付き環境ではDISCORD_BOT_TOKEN推奨)。
  • Discord権限は最小権限で付与してください。
  • コマンドのデプロイ/状態が古い場合は、gatewayを再起動し、openclaw channels status --probeで再確認してください。

関連