Discord (Bot API)

Статус: готов к работе в личных сообщениях и каналах серверов через официальный Discord-шлюз.

Быстрая настройка

Вам нужно создать приложение с ботом, добавить его на свой сервер и связать с OpenClaw. Рекомендуем добавить бота на собственный приватный сервер. Если его ещё нет, создайте новый (выберите Create My Own > For me and my friends).

Шаг 1: Создайте приложение и бота Discord

Откройте [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** (рекомендуется; необходим для allowlist по ролям и сопоставления имён с ID)
- **Presence Intent** (опционально; нужен только для обновлений присутствия)

Шаг 3: Скопируйте токен бота

Вернитесь наверх на странице **Bot** и нажмите **Reset Token**.

> **Примечание:** Несмотря на название, эта кнопка генерирует ваш первый токен — ничего не «сбрасывается».

Скопируйте токен и сохраните его. Это ваш **Bot Token**, он понадобится далее.

Шаг 4: Сгенерируйте ссылку-приглашение и добавьте бота на сервер

Перейдите в раздел **OAuth2** на боковой панели. Здесь вы сгенерируете ссылку-приглашение с нужными разрешениями.

Прокрутите до **OAuth2 URL Generator** и включите:

- `bot`
- `applications.commands`

Ниже появится раздел **Bot Permissions**. Включите:

- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (опционально)

Скопируйте сгенерированный URL внизу, вставьте в браузер, выберите свой сервер и нажмите **Continue**. Теперь бот должен появиться на сервере Discord.

Шаг 5: Включите режим разработчика и соберите ID

В приложении Discord включите режим разработчика, чтобы копировать внутренние ID.

1. Нажмите **Настройки пользователя** (значок шестерёнки рядом с аватаром) → **Расширенные** → включите **Режим разработчика**
2. Правой кнопкой мыши по **иконке сервера** → **Копировать ID сервера**
3. Правой кнопкой мыши по **вашему аватару** → **Копировать ID пользователя**

Сохраните **Server ID** и **User ID** вместе с Bot Token — все три значения потребуются на следующем шаге.

Шаг 6: Разрешите ЛС от участников сервера

Чтобы спаривание работало, Discord должен позволять боту отправлять вам ЛС. Правой кнопкой мыши по **иконке сервера** → **Настройки приватности** → включите **Личные сообщения**.

Это позволяет участникам сервера (включая ботов) отправлять вам ЛС. Оставьте эту опцию включённой, если хотите использовать Discord DM с OpenClaw. Если планируете использовать только каналы сервера, можно отключить ЛС после спаривания.

Шаг 7: Установите токен бота безопасно (не отправляйте в чат)

Токен Discord-бота — это секрет (как пароль). Задайте его на машине с 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 и выполните спаривание

  #### Через агента
    Напишите агенту OpenClaw в любом существующем канале (например, Telegram). Если Discord — ваш первый канал, используйте CLI / config.

    > «Я уже задал токен Discord-бота в конфиге. Пожалуйста, заверши настройку Discord с User ID `<user_id>` и Server ID `<server_id>`.»

  #### CLI / config
    Если предпочитаете конфигурацию через файл:
{
  channels: {
    discord: {
      enabled: true,
      token: "YOUR_BOT_TOKEN",
    },
  },
}
    Резервный вариант через переменную окружения (для аккаунта по умолчанию):
DISCORD_BOT_TOKEN=...
    Для `channels.discord.token` также поддерживаются значения SecretRef (провайдеры env/file/exec). См. [Управление секретами](/docs/gateway/secrets).

Шаг 9: Подтвердите первое спаривание через ЛС

Дождитесь запуска шлюза, затем напишите боту в ЛС в Discord. Он ответит кодом спаривания.


  #### Через агента
    Отправьте код спаривания агенту в существующем канале:

    > «Подтверди этот код спаривания Discord: `<CODE>`»

  #### CLI
openclaw pairing list discord
openclaw pairing approve discord <CODE>
Коды спаривания действуют 1 час.

Теперь вы можете общаться с агентом в Discord через ЛС.

Примечание: Разрешение токена учитывает аккаунт. Токен из конфигурации имеет приоритет над переменной окружения. DISCORD_BOT_TOKEN используется только для аккаунта по умолчанию. Для продвинутых исходящих вызовов (инструмент message / действия канала) используется явный token для каждого вызова. Политики аккаунта и настройки повторов берутся из выбранного аккаунта в текущем снимке конфигурации.

Рекомендуется: настройте рабочее пространство на сервере

Когда ЛС заработают, вы можете настроить Discord-сервер как полноценное рабочее пространство, где каждый канал получает собственную сессию агента с изолированным контекстом. Это рекомендуется для приватных серверов, где только вы и ваш бот.

Шаг 1: Добавьте сервер в allowlist серверов

Это позволит агенту отвечать в любом канале сервера, а не только в ЛС.


  #### Через агента
    > «Добавь мой Discord Server ID `<server_id>` в allowlist серверов»

  #### Config
{
  channels: {
    discord: {
      groupPolicy: "allowlist",
      guilds: {
        YOUR_SERVER_ID: {
          requireMention: true,
          users: ["YOUR_USER_ID"],
        },
      },
    },
  },
}

Шаг 2: Разрешите ответы без @упоминания

По умолчанию агент отвечает в каналах сервера только при @упоминании. На приватном сервере обычно удобнее, чтобы он реагировал на каждое сообщение.


  #### Через агента
    > «Разреши агенту отвечать на этом сервере без @упоминания»

  #### Config
    Установите `requireMention: false` в конфигурации сервера:
{
  channels: {
    discord: {
      guilds: {
        YOUR_SERVER_ID: {
          requireMention: false,
        },
      },
    },
  },
}

Шаг 3: Планирование работы с памятью в каналах сервера

По умолчанию долговременная память (MEMORY.md) загружается только в ЛС-сессиях. В каналах сервера MEMORY.md не подгружается автоматически.


  #### Через агента
    > «Когда я задаю вопросы в каналах Discord, используй memory_search или memory_get, если нужен долговременный контекст из MEMORY.md.»

  #### Вручную
    Если нужен общий контекст в каждом канале, поместите стабильные инструкции в `AGENTS.md` или `USER.md` (они подключаются в каждую сессию). Долгосрочные заметки храните в `MEMORY.md` и обращайтесь к ним по запросу через инструменты памяти.

Создайте каналы на Discord-сервере и начинайте общаться. Агент видит название канала, и каждый канал получает изолированную сессию — можно организовать #coding, #home, #research или любую другую структуру под ваши задачи.

Модель выполнения

  • Шлюз управляет Discord-соединением.
  • Маршрутизация ответов детерминирована: входящие из Discord возвращаются обратно в Discord.
  • По умолчанию (session.dmScope=main) личные чаты используют основную сессию агента (agent:main:main).
  • Каналы сервера получают изолированные ключи сессий (agent:<agentId>:discord:channel:<channelId>).
  • Групповые ЛС игнорируются по умолчанию (channels.discord.dm.groupEnabled=false).
  • Нативные слеш-команды выполняются в изолированных сессиях (agent:<agentId>:discord:slash:<userId>), передавая при этом CommandTargetSessionKey в маршрутизированную сессию разговора.

Форумные каналы

Форумные и медиаканалы Discord принимают только посты-треды. OpenClaw поддерживает два способа их создания:

  • Отправить сообщение в родительский форум (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 components v2 для сообщений агента. Используйте инструмент message с полезной нагрузкой components. Результаты взаимодействий маршрутизируются обратно агенту как обычные входящие сообщения и следуют настройкам replyToMode Discord.

Поддерживаемые блоки:

  • text, section, separator, actions, media-gallery, file
  • Action rows допускают до 5 кнопок или один select-меню
  • Типы select: string, user, role, mentionable, channel

По умолчанию компоненты одноразовые. Установите components.reusable=true, чтобы кнопки, select-меню и формы можно было использовать многократно до истечения срока.

Чтобы ограничить, кто может нажать кнопку, задайте allowedUsers на этой кнопке (Discord user 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" },
          ],
        },
      ],
    },
  },
}

Управление доступом и маршрутизация

Политика ЛС

`channels.discord.dmPolicy` управляет доступом к ЛС (устаревшее: `channels.discord.dm.policy`):

- `pairing` (по умолчанию)
- `allowlist`
- `open` (требует, чтобы `channels.discord.allowFrom` содержал `"*"`; устаревшее: `channels.discord.dm.allowFrom`)
- `disabled`

Если политика ЛС не `open`, неизвестные пользователи блокируются (или получают запрос на спаривание в режиме `pairing`).

Приоритет в мультиаккаунтном режиме:

- `channels.discord.accounts.default.allowFrom` применяется только к аккаунту `default`.
- Именованные аккаунты наследуют `channels.discord.allowFrom`, если собственный `allowFrom` не задан.
- Именованные аккаунты не наследуют `channels.discord.accounts.default.allowFrom`.

Формат адресата ЛС для доставки:

- `user:<id>`
- `<@id>` упоминание

Голые числовые ID неоднозначны и отклоняются, если не указан явный тип адресата (user/channel).

Политика сервера

Обработка серверов управляется через `channels.discord.groupPolicy`:

- `open`
- `allowlist`
- `disabled`

Безопасный базовый режим при наличии `channels.discord` — `allowlist`.

Поведение `allowlist`:

- сервер должен совпадать с `channels.discord.guilds` (предпочтительны `id`, slug допускается)
- опциональные allowlist отправителей: `users` (рекомендуются стабильные ID) и `roles` (только ID ролей); если настроен хотя бы один, отправители допускаются при совпадении с `users` ИЛИ `roles`
- прямое сопоставление по имени/тегу отключено по умолчанию; включите `channels.discord.dangerouslyAllowNameMatching: true` только как аварийный режим
- имена/теги поддерживаются для `users`, но ID безопаснее; `openclaw security audit` предупреждает при использовании записей с именами/тегами
- если у сервера настроены `channels`, каналы вне списка отклоняются
- если у сервера нет блока `channels`, разрешены все каналы этого сервера из allowlist

Пример:
{
  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`, при запуске используется `groupPolicy="allowlist"` (с предупреждением в логах), даже если `channels.defaults.groupPolicy` установлен в `open`.

Упоминания и групповые ЛС

Сообщения на серверах по умолчанию требуют упоминания.

Детекция упоминания включает:

- явное упоминание бота
- настроенные паттерны упоминаний (`agents.list[].groupChat.mentionPatterns`, резервно `messages.groupChat.mentionPatterns`)
- неявное поведение reply-to-bot в поддерживаемых случаях

`requireMention` настраивается для каждого сервера/канала (`channels.discord.guilds...`).
`ignoreOtherMentions` опционально отбрасывает сообщения, которые упоминают другого пользователя/роль, но не бота (исключая @everyone/@here).

Групповые ЛС:

- по умолчанию игнорируются (`dm.groupEnabled=false`)
- опциональный allowlist через `dm.groupChannels` (ID каналов или slug)

Маршрутизация агентов по ролям

Используйте 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

Создание приложения и бота
1. Discord Developer Portal -> **Applications** -> **New Application**
2. **Bot** -> **Add Bot**
3. Скопируйте токен бота
Привилегированные интенты
В **Bot -> Privileged Gateway Intents** включите:

- Message Content Intent
- Server Members Intent (рекомендуется)

Presence intent опционален и нужен только для получения обновлений присутствия. Установка присутствия бота (`setPresence`) не требует включения обновлений присутствия участников.
Области OAuth и базовые разрешения
Генератор URL OAuth:

- scopes: `bot`, `applications.commands`

Типичные базовые разрешения:

- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (опционально)

Избегайте `Administrator`, если только это не требуется явно.
Копирование ID
Включите режим разработчика Discord, затем скопируйте:

- server ID
- channel ID
- user ID

В конфигурации OpenClaw предпочтительны числовые ID для надёжного аудита и проверок.

Нативные команды и авторизация команд

  • commands.native по умолчанию "auto" и включён для Discord.
  • Переопределение для канала: channels.discord.commands.native.
  • commands.native=false явно удаляет ранее зарегистрированные нативные команды Discord.
  • Авторизация нативных команд использует те же allowlist/политики Discord, что и обычная обработка сообщений.
  • Команды могут быть видны в UI Discord для неавторизованных пользователей; при выполнении 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` принимается для кросс-канальной совместимости и соответствует `partial` в Discord.
- `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` — отключить

Управление историей ЛС:

- `channels.discord.dmHistoryLimit`
- `channels.discord.dms["<user_id>"].historyLimit`

Поведение тредов:

- Треды Discord маршрутизируются как сессии канала
- Метаданные родительского треда могут использоваться для привязки к родительской сессии
- Конфигурация тредов наследуется от родительского канала, если нет записи для конкретного треда

Темы каналов внедряются как **ненадёжный** контекст (не как системный промпт).
Привязка тредов к сессиям для подагентов
Discord может привязать тред к целевой сессии, чтобы последующие сообщения в этом треде продолжали маршрутизироваться в ту же сессию (включая сессии подагентов).

Команды:

- `/focus <target>` — привязать текущий/новый тред к подагенту или целевой сессии
- `/unfocus` — снять привязку текущего треда
- `/agents` — показать активные запуски и состояние привязок
- `/session idle <duration|off>` — просмотр/обновление авто-отвязки по неактивности для focused-привязок
- `/session max-age <duration|off>` — просмотр/обновление жёсткого максимального возраста для focused-привязок

Конфигурация:
{
  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` должен быть `true` для автоматического создания/привязки тредов при `sessions_spawn({ thread: true })`.
- `spawnAcpSessions` должен быть `true` для автоматического создания/привязки тредов для ACP (`/acp spawn ... --thread ...` или `sessions_spawn({ runtime: "acp", thread: true })`).
- Если привязки тредов отключены для аккаунта, `/focus` и связанные операции недоступны.

См. [Подагенты](/docs/tools/subagents), [ACP-агенты](/docs/tools/acp-agents) и [Справочник конфигурации](/docs/gateway/configuration-reference).
Постоянные привязки ACP-каналов
Для стабильных «всегда активных» рабочих пространств ACP настройте типизированные ACP-привязки верхнего уровня, нацеленные на Discord-разговоры.

Путь в конфигурации:

- `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`
- резервный эмодзи из идентичности агента (`agents.list[].identity.emoji`, иначе "👀")

Замечания:

- Discord принимает unicode-эмодзи или имена кастомных эмодзи.
- Используйте `""` для отключения реакции для канала или аккаунта.
Запись конфигурации
Запись конфигурации из канала включена по умолчанию.

Это затрагивает процессы `/config set|unset` (при включённых функциях команд).

Отключение:
{
  channels: {
    discord: {
      configWrites: false,
    },
  },
}
Прокси шлюза
Направляйте трафик Discord gateway WebSocket и REST-запросы при старте (получение ID приложения + разрешение allowlist) через HTTP(S) прокси с `channels.discord.proxy`.
{
  channels: {
    discord: {
      proxy: "http://proxy.example:8080",
    },
  },
}
Переопределение для аккаунта:
{
  channels: {
    discord: {
      accounts: {
        primary: {
          proxy: "http://proxy.example:8080",
        },
      },
    },
  },
}
Поддержка PluralKit
Включите разрешение PluralKit для сопоставления проксированных сообщений с идентичностью участника системы:
{
  channels: {
    discord: {
      pluralkit: {
        enabled: true,
        token: "pk_live_...", // опционально; нужен для приватных систем
      },
    },
  },
}
Замечания:

- allowlist могут использовать `pk:<memberId>`
- отображаемые имена участников сопоставляются по имени/slug только при `channels.discord.dangerouslyAllowNameMatching: true`
- поиск использует ID исходного сообщения и ограничен временным окном
- при ошибке поиска проксированные сообщения трактуются как сообщения ботов и отбрасываются, если `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` (поддерживает placeholder `{reason}`)
Одобрения exec в Discord
Discord поддерживает одобрения 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 откатывается к доставке в ЛС.

Авторизация шлюза для этого обработчика использует тот же контракт разрешения общих учётных данных, что и другие клиенты Gateway:

- приоритетная локальная авторизация через env (`OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD`, затем `gateway.auth.*`)
- в локальном режиме `gateway.remote.*` может использоваться как резерв только при отсутствии `gateway.auth.*`; настроенные, но неразрешённые локальные 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 использует Discord components v2 для одобрений exec и кросс-контекстных маркеров. Действия с сообщениями Discord также могут принимать components для пользовательского UI (продвинутое; требует экземпляров Carbon component), тогда как устаревшие embeds по-прежнему доступны, но не рекомендуются.

  • channels.discord.ui.components.accentColor задаёт акцентный цвет контейнеров Discord component (hex).
  • Установка для аккаунта: channels.discord.accounts.<id>.ui.components.accentColor.
  • embeds игнорируются при наличии components v2.

Пример:

{
  channels: {
    discord: {
      ui: {
        components: {
          accentColor: "#5865F2",
        },
      },
    },
  },
}

Голосовые каналы

OpenClaw может подключаться к голосовым каналам Discord для непрерывных разговоров в реальном времени. Это отличается от голосовых сообщений-вложений.

Требования:

  • Включите нативные команды (commands.native или channels.discord.commands.native).
  • Настройте channels.discord.voice.
  • Боту нужны разрешения Connect + Speak в целевом голосовом канале.

Используйте нативную Discord-команду /vc join|leave|status для управления сессиями. Команда использует агента по умолчанию для аккаунта и следует тем же allowlist и правилам групповой политики, что и другие 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.
  • По умолчанию @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 при необходимости.

Пример:

message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)

Устранение неполадок

Used disallowed intents или бот не видит сообщения на сервере
- включите Message Content Intent
- включите Server Members Intent, если зависите от разрешения user/member
- перезапустите шлюз после изменения интентов
Сообщения на сервере неожиданно блокируются
- проверьте `groupPolicy`
- проверьте allowlist сервера в `channels.discord.guilds`
- если в конфигурации сервера есть карта `channels`, разрешены только перечисленные каналы
- проверьте поведение `requireMention` и паттерны упоминаний

Полезные команды:
openclaw doctor
openclaw channels status --probe
openclaw logs --follow
requireMention false, но сообщения всё равно блокируются
Частые причины:

- `groupPolicy="allowlist"` без соответствующего allowlist сервера/канала
- `requireMention` настроен не в том месте (должен быть в `channels.discord.guilds` или записи канала)
- отправитель заблокирован allowlist `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 каналов.

Если вы используете slug-ключи, сопоставление в рантайме работает, но probe не может полностью проверить разрешения.
Проблемы с ЛС и спариванием
- ЛС отключены: `channels.discord.dm.enabled=false`
- Политика ЛС отключена: `channels.discord.dmPolicy="disabled"` (устаревшее: `channels.discord.dm.policy`)
- ожидание подтверждения спаривания в режиме `pairing`
Петли между ботами
По умолчанию сообщения от ботов игнорируются.

Если вы установили `channels.discord.allowBots=true`, используйте строгие правила упоминаний и allowlist, чтобы избежать циклического поведения.
Предпочтительно `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, retry
    • mediaMaxMb ограничивает исходящие загрузки в Discord (по умолчанию: 8MB)
  • действия: actions.*
  • присутствие: activity, status, activityType, activityUrl
  • UI: ui.components.accentColor
  • функции: threadBindings, верхнеуровневые bindings[] (type: "acp"), pluralkit, execApprovals, intents, agentComponents, heartbeat, responsePrefix

Безопасность и эксплуатация

  • Обращайтесь с токенами ботов как с секретами (DISCORD_BOT_TOKEN предпочтителен в управляемых средах).
  • Предоставляйте Discord-разрешения по принципу минимальных привилегий.
  • Если развёртывание или состояние команд устарело, перезапустите шлюз и проверьте через openclaw channels status --probe.

Связанные разделы