Перейти к основному содержанию
Готово для личных сообщений и каналов серверов через официальный Discord gateway.

Сопряжение

Личные сообщения Discord по умолчанию используют режим сопряжения.

Slash commands

Нативное поведение команд и каталог команд.

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

Межканальная диагностика и процесс исправления.

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

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

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

Перейдите в Discord Developer Portal и нажмите New Application. Назовите его, например, “OpenClaw”.Нажмите Bot на боковой панели. Задайте для Username любое имя, которым вы называете своего агента OpenClaw.
2

Включите привилегированные intents

Оставаясь на странице Bot, прокрутите вниз до Privileged Gateway Intents и включите:
  • Message Content Intent (обязательно)
  • Server Members Intent (рекомендуется; требуется для списков разрешенных ролей и сопоставления имени с ID)
  • Presence Intent (необязательно; требуется только для обновлений присутствия)
3

Скопируйте токен бота

Прокрутите страницу Bot обратно вверх и нажмите Reset Token.
Несмотря на название, это генерирует ваш первый токен — ничего не “сбрасывается”.
Скопируйте токен и сохраните его где-нибудь. Это ваш Bot Token, и он скоро понадобится.
4

Сгенерируйте URL приглашения и добавьте бота на сервер

Нажмите OAuth2 на боковой панели. Вы сгенерируете URL приглашения с правильными разрешениями для добавления бота на сервер.Прокрутите вниз до OAuth2 URL Generator и включите:
  • bot
  • applications.commands
Ниже появится раздел Bot Permissions. Включите как минимум:General Permissions
  • Просмотр каналов Text Permissions
  • Отправка сообщений
  • Чтение истории сообщений
  • Встраивание ссылок
  • Прикрепление файлов
  • Добавление реакций (необязательно)
Это базовый набор для обычных текстовых каналов. Если вы планируете публиковать сообщения в ветках Discord, включая рабочие процессы форумных или медиа-каналов, которые создают или продолжают ветку, также включите Send Messages in Threads. Скопируйте сгенерированный URL внизу, вставьте его в браузер, выберите свой сервер и нажмите Continue, чтобы подключить. Теперь вы должны увидеть своего бота на сервере Discord.
5

Включите режим разработчика и соберите свои ID

Вернувшись в приложение Discord, нужно включить режим разработчика, чтобы копировать внутренние ID.
  1. Нажмите User Settings (значок шестеренки рядом с вашим аватаром) → прокрутите до Developer на боковой панели → включите Developer Mode (Примечание: в мобильном приложении Discord режим разработчика находится в App SettingsAdvanced)
  2. Щелкните правой кнопкой мыши по значку сервера на боковой панели → Copy Server ID
  3. Щелкните правой кнопкой мыши по собственному аватаруCopy User ID
Сохраните Server ID и User ID рядом с Bot Token — на следующем шаге вы отправите все три значения в OpenClaw.
6

Разрешите личные сообщения от участников сервера

Чтобы сопряжение работало, Discord должен разрешить вашему боту отправлять вам личные сообщения. Щелкните правой кнопкой мыши по значку сервераPrivacy Settings → включите Direct Messages.Это позволяет участникам сервера (включая ботов) отправлять вам личные сообщения. Оставьте это включенным, если хотите использовать личные сообщения Discord с OpenClaw. Если вы планируете использовать только каналы сервера, можно отключить личные сообщения после сопряжения.
7

Безопасно задайте токен бота (не отправляйте его в чат)

Токен бота Discord — это секрет (как пароль). Задайте его на машине, где работает OpenClaw, перед тем как писать агенту.
export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN"
cat > discord.patch.json5 <<'JSON5'
{
  channels: {
    discord: {
      enabled: true,
      token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN" },
    },
  },
}
JSON5
openclaw config patch --file ./discord.patch.json5 --dry-run
openclaw config patch --file ./discord.patch.json5
openclaw gateway
Если OpenClaw уже работает как фоновая служба, перезапустите его через приложение OpenClaw для Mac или остановив и снова запустив процесс openclaw gateway run. Для установок управляемой службы выполните openclaw gateway install из shell, где присутствует DISCORD_BOT_TOKEN, или сохраните переменную в ~/.openclaw/.env, чтобы служба могла разрешить env SecretRef после перезапуска. Если ваш хост заблокирован или ограничен по частоте стартовым поиском приложения в Discord, задайте ID приложения/клиента Discord из Developer Portal, чтобы запуск мог пропустить этот REST-вызов. Используйте channels.discord.applicationId для учетной записи по умолчанию или channels.discord.accounts.<accountId>.applicationId, когда запускаете несколько ботов Discord.
8

Настройте OpenClaw и выполните сопряжение

Напишите своему агенту OpenClaw в любом существующем канале (например, Telegram) и сообщите ему это. Если Discord — ваш первый канал, используйте вместо этого вкладку CLI / конфигурации.
“Я уже указал токен бота Discord в конфигурации. Заверши настройку Discord с User ID <user_id> и Server ID <server_id>.”
9

Одобрите первое сопряжение через личные сообщения

Дождитесь, пока gateway запустится, затем отправьте личное сообщение своему боту в Discord. Он ответит кодом сопряжения.
Отправьте код сопряжения своему агенту в существующем канале:
“Одобри этот код сопряжения Discord: <CODE>
Коды сопряжения истекают через 1 час.Теперь вы должны иметь возможность общаться со своим агентом в Discord через личные сообщения.
Разрешение токенов учитывает учетные записи. Значения токенов из конфигурации имеют приоритет над резервным значением env. DISCORD_BOT_TOKEN используется только для учетной записи по умолчанию. Если две включенные учетные записи Discord разрешаются в один и тот же токен бота, OpenClaw запускает только один монитор gateway для этого токена. Токен из конфигурации имеет приоритет над резервным значением env по умолчанию; в противном случае первая включенная учетная запись побеждает, а дублирующая учетная запись помечается как отключенная. Для расширенных исходящих вызовов (инструмент сообщений/действия канала) явный token для каждого вызова используется для этого вызова. Это относится к действиям отправки и чтения/проверки (например, read/search/fetch/thread/pins/permissions). Политика учетной записи и настройки повторных попыток по-прежнему берутся из выбранной учетной записи в активном снимке runtime.

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

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

Добавьте свой сервер в allowlist серверов

Это позволяет вашему агенту отвечать в любом канале на вашем сервере, а не только в личных сообщениях.
“Добавь мой Discord Server ID <server_id> в allowlist серверов”
2

Разрешите ответы без @mention

По умолчанию ваш агент отвечает в каналах сервера только при @mention. Для приватного сервера, вероятно, вы захотите, чтобы он отвечал на каждое сообщение.В каналах сервера обычные ответы по умолчанию публикуются автоматически. Для общих постоянно активных комнат включите messages.groupChat.visibleReplies: "message_tool", чтобы агент мог находиться в режиме наблюдения и публиковать сообщение только когда решит, что ответ в канале полезен. Это лучше всего работает с моделями последнего поколения с надежной работой инструментов, такими как GPT 5.5. Фоновые события комнаты остаются тихими, если инструмент не отправляет сообщение. Полную конфигурацию режима наблюдения см. в фоновых событиях комнаты.Если Discord показывает ввод текста, а журналы показывают использование токенов, но опубликованного сообщения нет, проверьте, был ли ход настроен как фоновое событие комнаты или включал видимые ответы через инструмент сообщений.
“Разреши моему агенту отвечать на этом сервере без необходимости @mention”
3

Спланируйте память в каналах сервера

По умолчанию долгосрочная память (MEMORY.md) загружается только в сессиях личных сообщений. Каналы сервера не загружают MEMORY.md автоматически.
“Когда я задаю вопросы в каналах Discord, используй memory_search или memory_get, если тебе нужен долгосрочный контекст из MEMORY.md.”
Теперь создайте несколько каналов на своем сервере Discord и начните общаться. Ваш агент видит имя канала, и каждый канал получает собственную изолированную сессию — так что можно настроить #coding, #home, #research или любые другие каналы под ваш рабочий процесс.

Модель runtime

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

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

Форумные и медиа-каналы 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 v2 для сообщений агента. Используйте инструмент сообщений с полезной нагрузкой components. Результаты взаимодействия маршрутизируются обратно агенту как обычные входящие сообщения и следуют существующим настройкам Discord replyToMode. Поддерживаемые блоки:
  • text, section, separator, actions, media-gallery, file
  • Строки действий допускают до 5 кнопок или одно меню выбора
  • Типы выбора: string, user, role, mentionable, channel
По умолчанию компоненты одноразовые. Установите components.reusable=true, чтобы разрешить многократное использование кнопок, списков выбора и форм до истечения срока их действия. Чтобы ограничить, кто может нажать кнопку, задайте allowedUsers для этой кнопки (ID пользователей Discord, теги или *). При настройке пользователи без совпадения получают ephemeral-отказ. Срок действия callback-компонентов по умолчанию истекает через 30 минут. Установите channels.discord.agentComponents.ttlMs, чтобы изменить срок жизни реестра callback для учетной записи Discord по умолчанию, или channels.discord.accounts.<accountId>.agentComponents.ttlMs, чтобы переопределить одну учетную запись в конфигурации с несколькими учетными записями. Значение указывается в миллисекундах, должно быть положительным целым числом и ограничено 86400000 (24 часа). Более длинные TTL полезны для рабочих процессов проверки или утверждения, где кнопки должны оставаться доступными, но они также расширяют окно, в течение которого старое сообщение Discord все еще может запустить действие. Предпочитайте самый короткий TTL, подходящий для рабочего процесса, и оставляйте значение по умолчанию, когда устаревшие callback были бы неожиданными. Slash-команды /model и /models открывают интерактивный выбор модели с выпадающими списками провайдера, модели и совместимой среды выполнения, а также шагом Submit. /models add устарела и теперь возвращает сообщение об устаревании вместо регистрации моделей из чата. Ответ выбора является ephemeral, и использовать его может только пользователь, который его вызвал. Меню выбора Discord ограничены 25 вариантами, поэтому добавляйте записи provider/* в agents.defaults.models, когда хотите, чтобы выбор показывал динамически обнаруженные модели только для выбранных провайдеров, таких как openai или vllm. Вложения файлов:
  • Блоки 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 управляет доступом DM. channels.discord.allowFrom является каноническим списком разрешений для DM.
  • pairing (по умолчанию)
  • allowlist
  • open (требует, чтобы channels.discord.allowFrom включал "*")
  • disabled
Если политика DM не открыта, неизвестные пользователи блокируются (или получают запрос на pairing в режиме pairing).Приоритет для нескольких учетных записей:
  • channels.discord.accounts.default.allowFrom применяется только к учетной записи default.
  • Для одной учетной записи allowFrom имеет приоритет над устаревшим dm.allowFrom.
  • Именованные учетные записи наследуют channels.discord.allowFrom, когда их собственные allowFrom и устаревший dm.allowFrom не заданы.
  • Именованные учетные записи не наследуют channels.discord.accounts.default.allowFrom.
Устаревшие channels.discord.dm.policy и channels.discord.dm.allowFrom по-прежнему читаются для совместимости. openclaw doctor --fix переносит их в dmPolicy и allowFrom, когда это можно сделать без изменения доступа.Формат цели DM для доставки:
  • user:<id>
  • упоминание <@id>
Голые числовые ID обычно разрешаются как ID каналов, когда активен канал по умолчанию, но ID, перечисленные в эффективном DM allowFrom учетной записи, рассматриваются как цели пользовательских DM для совместимости.

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

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

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

  • commands.native по умолчанию имеет значение "auto" и включен для Discord.
  • Переопределение для отдельного канала: channels.discord.commands.native.
  • commands.native=false пропускает регистрацию и очистку слэш-команд Discord при запуске. Ранее зарегистрированные команды могут оставаться видимыми в Discord, пока вы не удалите их из приложения Discord.
  • Авторизация нативных команд использует те же списки разрешений/политики Discord, что и обычная обработка сообщений.
  • Команды могут по-прежнему быть видимыми в UI Discord для неавторизованных пользователей; выполнение все равно применяет авторизацию OpenClaw и возвращает “не авторизован”.
См. Слэш-команды, чтобы узнать о каталоге команд и поведении. Настройки слэш-команд по умолчанию:
  • ephemeral: true

Сведения о функциях

Discord поддерживает теги ответов в выводе агента:
  • [[reply_to_current]]
  • [[reply_to:<id>]]
Управляется через channels.discord.replyToMode:
  • off (по умолчанию)
  • first
  • all
  • batched
Примечание: off отключает неявную привязку ответов к цепочкам. Явные теги [[reply_to_*]] по-прежнему учитываются. first всегда прикрепляет неявную нативную ссылку ответа к первому исходящему сообщению Discord за ход. batched прикрепляет неявную нативную ссылку ответа Discord только тогда, когда входящее событие было отложенной пакетной обработкой нескольких сообщений. Это полезно, когда нативные ответы нужны в основном для неоднозначных всплесков чата, а не для каждого хода из одного сообщения.ID сообщений выводятся в контексте/истории, чтобы агенты могли обращаться к конкретным сообщениям.
Discord по умолчанию создает насыщенные встраивания ссылок для URL. OpenClaw по умолчанию подавляет эти сгенерированные встраивания в исходящих сообщениях Discord, поэтому отправленные агентом URL остаются обычными ссылками, если вы не включите другое поведение:
{
  channels: {
    discord: {
      suppressEmbeds: false,
    },
  },
}
Задайте channels.discord.accounts.<id>.suppressEmbeds, чтобы переопределить один аккаунт. Отправки через инструмент сообщений агента также могут передать suppressEmbeds: false для одного сообщения. Явные полезные нагрузки Discord embeds не подавляются настройкой предпросмотра ссылок по умолчанию.
OpenClaw может транслировать черновики ответов, отправляя временное сообщение и редактируя его по мере поступления текста. channels.discord.streaming принимает off | partial | block | progress (по умолчанию). progress сохраняет один редактируемый черновик статуса и обновляет его прогрессом инструментов до финальной доставки; общая начальная метка является бегущей строкой, поэтому она прокручивается вверх вместе с остальным, когда появляется достаточно работы. streamMode — устаревший псевдоним среды выполнения. Запустите openclaw doctor --fix, чтобы переписать сохраненную конфигурацию на канонический ключ.Задайте channels.discord.streaming.mode в off, чтобы отключить правки предпросмотра Discord. Если потоковая передача блоками Discord явно включена, OpenClaw пропускает поток предпросмотра, чтобы избежать двойной потоковой передачи.
{
  channels: {
    discord: {
      streaming: {
        mode: "progress",
        progress: {
          label: "auto",
          maxLines: 8,
          maxLineChars: 120,
          toolProgress: true,
          commentary: false,
        },
      },
    },
  },
}
  • partial редактирует одно сообщение предпросмотра по мере поступления токенов.
  • block отправляет фрагменты размером с черновик (используйте draftChunk, чтобы настроить размер и точки разрыва, с ограничением до textChunkLimit).
  • Медиа, ошибки и финальные сообщения с явным ответом отменяют ожидающие правки предпросмотра.
  • streaming.preview.toolProgress (по умолчанию true) управляет тем, переиспользуют ли обновления инструмента/прогресса сообщение предпросмотра.
  • Строки инструмента/прогресса отображаются как компактные эмодзи + заголовок + детали, когда доступны, например 🛠️ Bash: run tests или 🔎 Web Search: for "query".
  • streaming.progress.commentary (по умолчанию false) включает текст комментария/преамбулы ассистента во временном черновике прогресса. Комментарий очищается перед показом, остается временным и не меняет доставку финального ответа.
  • streaming.progress.maxLineChars управляет лимитом предпросмотра прогресса на строку. Проза сокращается по границам слов; сведения о командах и путях сохраняют полезные суффиксы.
  • streaming.preview.commandText / streaming.progress.commandText управляет деталями команд/exec в компактных строках прогресса: raw (по умолчанию) или status (только метка инструмента).
Скрыть необработанный текст команд/exec, сохранив компактные строки прогресса:
{
  "channels": {
    "discord": {
      "streaming": {
        "mode": "progress",
        "progress": {
          "toolProgress": true,
          "commandText": "status"
        }
      }
    }
  }
}
Потоковая передача предпросмотра поддерживает только текст; медиаответы возвращаются к обычной доставке. Когда потоковая передача block явно включена, OpenClaw пропускает поток предпросмотра, чтобы избежать двойной потоковой передачи.
Контекст истории гильдии:
  • channels.discord.historyLimit по умолчанию 20
  • резервный вариант: messages.groupChat.historyLimit
  • 0 отключает
Управление историей DM:
  • channels.discord.dmHistoryLimit
  • channels.discord.dms["<user_id>"].historyLimit
Поведение веток:
  • Ветки Discord маршрутизируются как сессии канала и наследуют конфигурацию родительского канала, если она не переопределена.
  • Сессии веток наследуют выбранную на уровне сессии родительского канала настройку /model как резервный вариант только для модели; локальные для ветки выборы /model по-прежнему имеют приоритет, а история родительской расшифровки не копируется, если наследование расшифровки не включено.
  • channels.discord.thread.inheritParent (по умолчанию false) включает для новых автоматических веток начальное заполнение из родительской расшифровки. Переопределения для отдельных аккаунтов находятся в channels.discord.accounts.<id>.thread.inheritParent.
  • Реакции инструмента сообщений могут разрешать DM-цели user:<id>.
  • guilds.<guild>.channels.<channel>.requireMention: false сохраняется при резервной активации на этапе ответа.
Темы каналов внедряются как недоверенный контекст. Списки разрешений ограничивают, кто может запустить агента, но не являются полноценной границей редактирования дополнительного контекста.
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,
        spawnSessions: true,
        defaultSpawnContext: "fork",
      },
    },
  },
}
Примечания:
  • session.threadBindings.* задает глобальные значения по умолчанию.
  • channels.discord.threadBindings.* переопределяет поведение Discord.
  • spawnSessions управляет автоматическим созданием/привязкой веток для sessions_spawn({ thread: true }) и порождений веток ACP. По умолчанию: true.
  • defaultSpawnContext управляет нативным контекстом подагента для порождений, привязанных к ветке. По умолчанию: "fork".
  • Устаревшие ключи spawnSubagentSessions/spawnAcpSessions мигрируются через openclaw doctor --fix.
  • Если привязки веток отключены для аккаунта, /focus и связанные операции привязки веток недоступны.
См. Подагенты, Агенты 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 spawn codex --bind here привязывает текущий канал или ветку на месте и сохраняет будущие сообщения в той же сессии ACP. Сообщения ветки наследуют привязку родительского канала.
  • В привязанном канале или ветке /new и /reset сбрасывают ту же сессию ACP на месте. Временные привязки веток могут переопределять разрешение цели, пока активны.
  • spawnSessions ограничивает создание/привязку дочерних веток через --thread auto|here.
См. Агенты ACP, чтобы узнать подробности о поведении привязок.
Режим уведомлений о реакциях для отдельной гильдии:
  • 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,
    },
  },
}
Направляйте WebSocket-трафик Gateway Discord и стартовые REST-запросы (ID приложения + разрешение списка разрешений) через HTTP(S)-прокси с channels.discord.proxy.
{
  channels: {
    discord: {
      proxy: "http://proxy.example:8080",
    },
  },
}
Переопределение для отдельного аккаунта:
{
  channels: {
    discord: {
      accounts: {
        primary: {
          proxy: "http://proxy.example:8080",
        },
      },
    },
  },
}
Включите разрешение PluralKit, чтобы сопоставлять проксированные сообщения с идентичностью участника системы:
{
  channels: {
    discord: {
      pluralkit: {
        enabled: true,
        token: "pk_live_...", // optional; needed for private systems
      },
    },
  },
}
Примечания:
  • списки разрешенных могут использовать pk:<memberId>
  • отображаемые имена участников сопоставляются по имени/slug только когда channels.discord.dangerouslyAllowNameMatching: true
  • поиск использует исходный ID сообщения и ограничен временным окном
  • если поиск не удается, проксированные сообщения считаются сообщениями бота и отбрасываются, если только allowBots=true
Используйте mentionAliases, когда агентам нужны детерминированные исходящие упоминания для известных пользователей Discord. Ключи — это handles без начального @; значения — ID пользователей Discord. Неизвестные handles, @everyone, @here и упоминания внутри Markdown code spans остаются без изменений.
{
  channels: {
    discord: {
      mentionAliases: {
        Vladislava: "123456789012345678",
      },
      accounts: {
        ops: {
          mentionAliases: {
            OpsLead: "234567890123456789",
          },
        },
      },
    },
  },
}
Обновления присутствия применяются, когда вы задаете поле статуса или активности либо включаете автоматическое присутствие.Пример только со статусом:
{
  channels: {
    discord: {
      status: "idle",
    },
  },
}
Пример активности (пользовательский статус — тип активности по умолчанию):
{
  channels: {
    discord: {
      activity: "Focus time",
      activityType: 4,
    },
  },
}
Пример стриминга:
{
  channels: {
    discord: {
      activity: "Live coding",
      activityType: 1,
      activityUrl: "https://twitch.tv/openclaw",
    },
  },
}
Карта типов активности:
  • 0: Игра
  • 1: Стриминг (требует activityUrl)
  • 2: Прослушивание
  • 3: Просмотр
  • 4: Пользовательский (использует текст активности как состояние статуса; emoji необязателен)
  • 5: Соревнование
Пример автоматического присутствия (сигнал состояния runtime):
{
  channels: {
    discord: {
      autoPresence: {
        enabled: true,
        intervalMs: 30000,
        minUpdateIntervalMs: 15000,
        exhaustedText: "token exhausted",
      },
    },
  },
}
Автоматическое присутствие сопоставляет доступность runtime со статусом Discord: исправен => онлайн, деградировал или неизвестен => неактивен, исчерпан или недоступен => dnd. Необязательные переопределения текста:
  • autoPresence.healthyText
  • autoPresence.degradedText
  • autoPresence.exhaustedText (поддерживает placeholder {reason})
Discord поддерживает обработку подтверждений на основе кнопок в личных сообщениях и может дополнительно публиковать запросы подтверждения в исходном канале.Путь конфигурации:
  • channels.discord.execApprovals.enabled
  • channels.discord.execApprovals.approvers (необязательно; по возможности использует fallback на commands.ownerAllowFrom)
  • channels.discord.execApprovals.target (dm | channel | both, по умолчанию: dm)
  • agentFilter, sessionFilter, cleanupAfterResolve
Discord автоматически включает нативные подтверждения exec, когда enabled не задано или равно "auto" и можно разрешить хотя бы одного подтверждающего — из execApprovals.approvers или из commands.ownerAllowFrom. Discord не выводит подтверждающих exec из allowFrom канала, legacy dm.allowFrom или defaultTo для личных сообщений. Задайте enabled: false, чтобы явно отключить Discord как нативный клиент подтверждений.Для чувствительных групповых команд только для владельца, таких как /diagnostics и /export-trajectory, OpenClaw отправляет запросы подтверждения и итоговые результаты приватно. Сначала он пробует Discord DM, когда у вызывающего владельца есть маршрут владельца Discord; если он недоступен, он использует fallback на первый доступный маршрут владельца из commands.ownerAllowFrom, например Telegram.Когда target равен channel или both, запрос подтверждения виден в канале. Кнопки могут использовать только разрешенные подтверждающие; другие пользователи получают эфемерный отказ. Запросы подтверждения включают текст команды, поэтому включайте доставку в канал только в доверенных каналах. Если ID канала нельзя получить из ключа сессии, OpenClaw использует fallback на доставку в DM.Discord также отображает общие кнопки подтверждения, используемые другими чат-каналами. Нативный адаптер Discord в основном добавляет маршрутизацию DM для подтверждающих и веерную рассылку в каналы. Когда эти кнопки присутствуют, они являются основным UX подтверждения; OpenClaw должен включать ручную команду /approve только когда результат инструмента сообщает, что чат-подтверждения недоступны или ручное подтверждение — единственный путь. Если нативный runtime подтверждений Discord не активен, OpenClaw сохраняет видимый локальный детерминированный prompt /approve <id> <decision>. Если runtime активен, но нативную карточку нельзя доставить ни одной цели, OpenClaw отправляет уведомление fallback в тот же чат с точной командой /approve из ожидающего подтверждения.Аутентификация Gateway и разрешение подтверждений следуют общему контракту клиента Gateway (plugin: IDs разрешаются через plugin.approval.resolve; другие IDs — через exec.approval.resolve). По умолчанию срок действия подтверждений истекает через 30 минут.См. Подтверждения exec.

Инструменты и action gates

Действия сообщений Discord включают отправку сообщений, администрирование каналов, модерацию, присутствие и действия с метаданными. Основные примеры:
  • сообщения: sendMessage, readMessages, editMessage, deleteMessage, threadReply
  • реакции: react, reactions, emojiList
  • модерация: timeout, kick, ban
  • присутствие: setPresence
Действие event-create принимает необязательный параметр image (URL или путь к локальному файлу), чтобы задать изображение обложки запланированного события. Action gates находятся в channels.discord.actions.*. Поведение gate по умолчанию:
Группа действийПо умолчанию
reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissionsвключено
rolesотключено
moderationотключено
presenceотключено

UI Components v2

OpenClaw использует Discord components v2 для подтверждений exec и маркеров cross-context. Действия сообщений Discord также могут принимать components для пользовательского UI (расширенный сценарий; требует создания payload компонента через инструмент discord), при этом legacy embeds остаются доступными, но не рекомендуются.
  • channels.discord.ui.components.accentColor задает цвет акцента, используемый контейнерами компонентов Discord (hex).
  • Задайте для отдельной учетной записи через channels.discord.accounts.<id>.ui.components.accentColor.
  • channels.discord.agentComponents.ttlMs управляет тем, как долго callbacks отправленных компонентов Discord остаются зарегистрированными (по умолчанию 1800000, максимум 86400000). Задайте для отдельной учетной записи через channels.discord.accounts.<id>.agentComponents.ttlMs.
  • embeds игнорируются, когда присутствуют components v2.
  • Простые предпросмотры URL по умолчанию подавляются. Задайте suppressEmbeds: false в действии сообщения, когда одна исходящая ссылка должна разворачиваться.
Пример:
{
  channels: {
    discord: {
      ui: {
        components: {
          accentColor: "#5865F2",
        },
      },
    },
  },
}

Голос

У Discord есть две разные голосовые поверхности: realtime голосовые каналы (непрерывные разговоры) и вложения голосовых сообщений (формат предпросмотра с waveform). Gateway поддерживает оба варианта.

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

Контрольный список настройки:
  1. Включите Message Content Intent в Discord Developer Portal.
  2. Включите Server Members Intent, когда используются списки разрешенных ролей/пользователей.
  3. Пригласите бота со scopes bot и applications.commands.
  4. Предоставьте Connect, Speak, Send Messages и Read Message History в целевом голосовом канале.
  5. Включите нативные команды (commands.native или channels.discord.commands.native).
  6. Настройте channels.discord.voice.
Используйте /vc join|leave|status для управления сессиями. Команда использует агента учетной записи по умолчанию и следует тем же правилам списков разрешенных и групповой политики, что и другие команды Discord.
/vc join channel:<voice-channel-id>
/vc status
/vc leave
Чтобы проверить эффективные разрешения бота перед подключением, выполните:
openclaw channels capabilities --channel discord --target channel:<voice-channel-id>
Пример автоматического подключения:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        model: "openai/gpt-5.5",
        autoJoin: [
          {
            guildId: "123456789012345678",
            channelId: "234567890123456789",
          },
        ],
        allowedChannels: [
          {
            guildId: "123456789012345678",
            channelId: "234567890123456789",
          },
        ],
        daveEncryption: true,
        decryptionFailureTolerance: 24,
        connectTimeoutMs: 30000,
        reconnectGraceMs: 15000,
        realtime: {
          provider: "openai",
          model: "gpt-realtime-2",
          speakerVoice: "cedar",
        },
      },
    },
  },
}
Примечания:
  • voice.tts переопределяет messages.tts только для голосового воспроизведения stt-tts. Режимы реального времени используют voice.realtime.speakerVoice.
  • voice.mode управляет путем разговора. По умолчанию используется agent-proxy: голосовой фронтенд реального времени обрабатывает тайминг реплик, прерывание и воспроизведение, делегирует содержательную работу маршрутизированному агенту OpenClaw через openclaw_agent_consult и обрабатывает результат как текстовый запрос Discord от этого говорящего. stt-tts сохраняет прежний пакетный поток STT плюс TTS. bidi позволяет модели реального времени вести разговор напрямую, предоставляя openclaw_agent_consult для мозга OpenClaw.
  • voice.agentSession управляет тем, какой разговор OpenClaw получает голосовые реплики. Не задавайте его, чтобы использовать собственную сессию голосового канала, или задайте { mode: "target", target: "channel:<text-channel-id>" }, чтобы голосовой канал работал как расширение микрофона/динамика существующей сессии текстового канала Discord, например #maintainers.
  • voice.model переопределяет мозг агента OpenClaw для голосовых ответов Discord и консультаций реального времени. Не задавайте его, чтобы наследовать модель маршрутизированного агента. Он отделен от voice.realtime.model.
  • voice.followUsers позволяет боту подключаться, перемещаться и выходить из голосовых каналов Discord вместе с выбранными пользователями. См. Следование за пользователями в голосе для правил поведения и примеров.
  • agent-proxy маршрутизирует речь через discord-voice, что сохраняет обычную авторизацию владельца/инструментов для говорящего и целевой сессии, но скрывает инструмент агента tts, потому что голос Discord сам отвечает за воспроизведение. По умолчанию agent-proxy предоставляет консультации полный доступ к инструментам, эквивалентный владельцу, для говорящих владельцев (voice.realtime.toolPolicy: "owner") и настоятельно предпочитает консультироваться с агентом OpenClaw перед содержательными ответами (voice.realtime.consultPolicy: "always"). В этом режиме always по умолчанию слой реального времени не произносит автоматически заполняющие фразы до ответа консультации; он захватывает и транскрибирует речь, затем произносит маршрутизированный ответ OpenClaw. Если несколько принудительных ответов консультации завершаются, пока Discord еще воспроизводит первый ответ, последующие ответы с точной речью ставятся в очередь до простоя воспроизведения вместо замены речи в середине предложения.
  • В режиме stt-tts STT использует tools.media.audio; voice.model не влияет на транскрипцию.
  • В режимах реального времени voice.realtime.provider, voice.realtime.model и voice.realtime.speakerVoice настраивают аудиосессию реального времени. Для OpenAI Realtime 2 плюс мозг Codex используйте voice.realtime.model: "gpt-realtime-2" и voice.model: "openai/gpt-5.5".
  • Голосовые режимы реального времени по умолчанию включают небольшие файлы профиля IDENTITY.md, USER.md и SOUL.md в инструкции провайдера реального времени, чтобы быстрые прямые реплики сохраняли ту же идентичность, привязку к пользователю и персону, что и маршрутизированный агент OpenClaw. Задайте voice.realtime.bootstrapContextFiles как подмножество, чтобы настроить это, или [], чтобы отключить. Поддерживаемые файлы начальной загрузки реального времени ограничены этими файлами профиля; AGENTS.md остается в обычном контексте агента. Внедренный контекст профиля не заменяет openclaw_agent_consult для работы с рабочей областью, текущих фактов, поиска в памяти или действий на основе инструментов.
  • В режиме реального времени OpenAI agent-proxy задайте voice.realtime.requireWakeName: true, чтобы голос Discord в реальном времени молчал, пока транскрипт не начнется или не закончится словом пробуждения. Настроенные имена пробуждения должны состоять из одного или двух слов. Если voice.realtime.wakeNames не задан, OpenClaw использует name маршрутизированного агента плюс OpenClaw, с откатом к идентификатору агента плюс OpenClaw. Фильтрация по имени пробуждения отключает автоответ провайдера реального времени, маршрутизирует принятые реплики через путь консультации агента OpenClaw и дает короткое устное подтверждение, когда начальное имя пробуждения распознано из частичной транскрипции до получения финального транскрипта.
  • Провайдер реального времени OpenAI принимает текущие имена событий Realtime 2 и устаревшие совместимые с Codex псевдонимы для событий выходного аудио и транскрипта, поэтому совместимые снимки провайдера могут расходиться без потери аудио ассистента.
  • voice.realtime.bargeIn управляет тем, прерывают ли события начала речи в Discord активное воспроизведение реального времени. Если не задано, следует настройке прерывания входного аудио провайдера реального времени.
  • voice.realtime.minBargeInAudioEndMs управляет минимальной длительностью воспроизведения ассистента перед тем, как перебивание OpenAI в реальном времени обрежет аудио. По умолчанию: 250. Задайте 0 для немедленного прерывания в комнатах с низким эхом или увеличьте значение для настроек с динамиками и сильным эхом.
  • Для голоса OpenAI при воспроизведении в Discord задайте voice.tts.provider: "openai" и выберите голос Text-to-speech в voice.tts.providers.openai.speakerVoice. cedar — хороший вариант с мужским звучанием на текущей модели TTS OpenAI.
  • Переопределения systemPrompt Discord для отдельных каналов применяются к голосовым транскрибированным репликам этого голосового канала.
  • Голосовые транскрибированные реплики выводят статус владельца из Discord allowFrom (или dm.allowFrom) для команд с доступом только владельцу и действий канала. Видимость инструментов агента следует настроенной политике инструментов для маршрутизированной сессии.
  • Голос Discord включается явно для конфигураций только с текстом; задайте channels.discord.voice.enabled=true (или сохраните существующий блок channels.discord.voice), чтобы включить команды /vc, голосовую среду выполнения и намерение Gateway GuildVoiceStates.
  • channels.discord.intents.voiceStates может явно переопределить подписку на намерение голосового состояния. Не задавайте его, чтобы намерение следовало эффективному включению голоса.
  • Если voice.autoJoin содержит несколько записей для одной гильдии, OpenClaw подключается к последнему настроенному каналу для этой гильдии.
  • voice.allowedChannels — необязательный список разрешенных мест пребывания. Не задавайте его, чтобы разрешить /vc join в любой авторизованный голосовой канал Discord. Если задан, /vc join, автоподключение при запуске и перемещения голосового состояния бота ограничены перечисленными записями { guildId, channelId }. Задайте пустой массив, чтобы запретить все голосовые подключения Discord. Если Discord перемещает бота за пределы списка разрешений, OpenClaw выходит из этого канала и повторно подключается к настроенной цели автоподключения, когда она доступна.
  • voice.daveEncryption и voice.decryptionFailureTolerance передаются в параметры подключения @discordjs/voice.
  • Значения по умолчанию @discordjs/voice: daveEncryption=true и decryptionFailureTolerance=24, если они не заданы.
  • OpenClaw использует встроенный кодек libopus-wasm для приема голоса Discord и воспроизведения необработанного PCM в реальном времени. Он поставляется с закрепленной сборкой libopus WebAssembly и не требует нативных дополнений opus.
  • voice.connectTimeoutMs управляет начальным ожиданием Ready @discordjs/voice для /vc join и попыток автоподключения. По умолчанию: 30000.
  • voice.reconnectGraceMs управляет тем, как долго OpenClaw ждет, пока отключенная голосовая сессия начнет переподключаться, прежде чем уничтожить ее. По умолчанию: 15000.
  • В режиме stt-tts голосовое воспроизведение не останавливается только потому, что другой пользователь начинает говорить. Чтобы избежать петель обратной связи, OpenClaw игнорирует новый голосовой захват, пока воспроизводится TTS; говорите после завершения воспроизведения для следующей реплики. Режимы реального времени передают начало речи как сигналы перебивания провайдеру реального времени.
  • В режимах реального времени эхо из динамиков в открытый микрофон может выглядеть как перебивание и прерывать воспроизведение. Для комнат Discord с сильным эхом задайте voice.realtime.providers.openai.interruptResponseOnInputAudio: false, чтобы OpenAI не прерывал ответ автоматически при входном аудио. Добавьте voice.realtime.bargeIn: true, если все еще хотите, чтобы события начала речи Discord прерывали активное воспроизведение. Мост реального времени OpenAI игнорирует усечения воспроизведения короче voice.realtime.minBargeInAudioEndMs как вероятное эхо/шум и логирует их как пропущенные вместо очистки воспроизведения Discord.
  • voice.captureSilenceGraceMs управляет тем, как долго OpenClaw ждет после сообщения Discord об остановке говорящего, прежде чем завершить этот аудиосегмент для STT. По умолчанию: 2000; увеличьте это значение, если Discord разбивает обычные паузы на рваные частичные транскрипты.
  • Когда выбранным провайдером TTS является ElevenLabs, голосовое воспроизведение Discord использует потоковый TTS и начинается из потока ответа провайдера. Провайдеры без поддержки потоковой передачи откатываются к пути с синтезированным временным файлом.
  • OpenClaw также отслеживает сбои расшифровки приема и автоматически восстанавливается, выходя из голосового канала и повторно подключаясь к нему после повторяющихся сбоев за короткое окно.
  • Если после обновления в журналах приема повторно появляется DecryptionFailed(UnencryptedWhenPassthroughDisabled), соберите отчет о зависимостях и журналы. Встроенная линия @discordjs/voice включает исправление заполнения из вышестоящего PR discord.js #11449, который закрыл issue discord.js #11419.
  • События приема The operation was aborted ожидаемы, когда OpenClaw завершает захваченный сегмент говорящего; это подробная диагностика, а не предупреждения.
  • Подробные журналы голоса Discord включают ограниченный однострочный предпросмотр STT-транскрипта для каждого принятого сегмента говорящего, поэтому отладка показывает и сторону пользователя, и сторону ответа агента без вывода неограниченного текста транскрипта.
  • В режиме agent-proxy принудительный откат консультации пропускает вероятно неполные фрагменты транскрипта, например текст, заканчивающийся на ... или завершающий соединитель вроде and, а также очевидные не требующие действия завершения вроде “be right back” или “bye”. Журналы показывают forced agent consult skipped reason=..., когда это предотвращает устаревший ответ из очереди.

Следование за пользователями в голосе

Используйте voice.followUsers, когда хотите, чтобы голосовой бот Discord оставался с одним или несколькими известными пользователями Discord вместо подключения к фиксированному каналу при запуске или ожидания /vc join.
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        followUsersEnabled: true,
        followUsers: ["discord:123456789012345678"],
        allowedChannels: [
          {
            guildId: "123456789012345678",
            channelId: "234567890123456789",
          },
        ],
      },
    },
  },
}
Поведение:
  • followUsers принимает необработанные идентификаторы пользователей Discord и значения discord:<id>. OpenClaw нормализует обе формы перед сопоставлением событий голосового состояния.
  • followUsersEnabled по умолчанию равно true, когда настроен followUsers. Задайте false, чтобы сохранить список, но остановить автоматическое следование в голосе.
  • Когда отслеживаемый пользователь подключается к разрешенному голосовому каналу, OpenClaw подключается к этому каналу. Когда пользователь перемещается, OpenClaw перемещается вместе с ним. Когда активный отслеживаемый пользователь отключается, OpenClaw выходит.
  • Если несколько отслеживаемых пользователей находятся в одной гильдии и активный отслеживаемый пользователь выходит, OpenClaw перемещается в канал другого отслеживаемого пользователя перед выходом из гильдии. Если несколько отслеживаемых пользователей перемещаются одновременно, побеждает последнее наблюдаемое событие голосового состояния.
  • allowedChannels по-прежнему применяется. Отслеживаемый пользователь в запрещенном канале игнорируется, а сессия, принадлежащая следованию, перемещается к другому отслеживаемому пользователю или выходит.
  • OpenClaw сверяет пропущенные события голосового состояния при запуске и с ограниченным интервалом. Сверка выборочно проверяет настроенные гильдии и ограничивает REST-запросы за один запуск, поэтому очень большие списки followUsers могут сходиться дольше одного интервала.
  • Если Discord или администратор перемещает бота, пока он следует за пользователем, OpenClaw перестраивает голосовую сессию и сохраняет владение следованием, когда место назначения разрешено. Если бот перемещен за пределы allowedChannels, OpenClaw выходит и повторно подключается к настроенной цели, когда она существует.
  • Восстановление приема DAVE может выйти из того же канала и повторно подключиться к нему после повторяющихся сбоев расшифровки. Сессии, принадлежащие следованию, сохраняют владение следованием на этом пути восстановления, поэтому последующее отключение отслеживаемого пользователя все равно приводит к выходу из канала.
Выберите между режимами подключения:
  • Используйте followUsers для персональных или операторских настроек, где бот должен автоматически быть в голосе, когда там находитесь вы.
  • Используйте autoJoin для ботов фиксированных комнат, которые должны присутствовать, даже когда в голосе нет отслеживаемого пользователя.
  • Используйте /vc join для разовых подключений или комнат, где автоматическое голосовое присутствие было бы неожиданным.
Кодек голоса Discord:
  • Логи приема голоса показывают discord voice: opus decoder: libopus-wasm.
  • Воспроизведение в реальном времени кодирует необработанный стерео PCM 48 кГц в Opus тем же встроенным пакетом libopus-wasm, прежде чем передать пакеты в @discordjs/voice.
  • Воспроизведение файлов и потоков провайдера перекодирует аудио в необработанный стерео PCM 48 кГц с помощью ffmpeg, а затем использует libopus-wasm для потока пакетов Opus, отправляемого в Discord.
Конвейер STT плюс TTS:
  • Захват Discord PCM преобразуется во временный WAV-файл.
  • tools.media.audio обрабатывает STT, например openai/gpt-4o-mini-transcribe.
  • Транскрипт отправляется через входящий поток Discord и маршрутизацию, пока ответная LLM запускается с политикой голосового вывода, которая скрывает инструмент агента tts и запрашивает возвращаемый текст, потому что финальным воспроизведением TTS для голоса владеет Discord.
  • voice.model, если задан, переопределяет только ответную LLM для этого обращения в голосовом канале.
  • voice.tts объединяется поверх messages.tts; провайдеры с поддержкой потоковой передачи подают данные напрямую в плеер, иначе полученный аудиофайл воспроизводится в присоединенном канале.
Пример сеанса голосового канала agent-proxy по умолчанию:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        model: "openai/gpt-5.5",
        followUsersEnabled: true,
        followUsers: ["123456789012345678"],
        realtime: {
          provider: "openai",
          model: "gpt-realtime-2",
          speakerVoice: "cedar",
        },
      },
    },
  },
}
Без блока voice.agentSession каждый голосовой канал получает собственный маршрутизируемый сеанс OpenClaw. Например, /vc join channel:234567890123456789 обращается к сеансу для этого голосового канала Discord. Модель реального времени является только голосовым фронтендом; содержательные запросы передаются настроенному агенту OpenClaw. Если модель реального времени создает финальный транскрипт без вызова инструмента consult, OpenClaw принудительно выполняет consult как резервный вариант, чтобы поведение по умолчанию по-прежнему было похоже на разговор с агентом. Устаревший пример STT плюс TTS:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        mode: "stt-tts",
        model: "openai/gpt-5.4-mini",
        tts: {
          provider: "openai",
          providers: {
            openai: {
              model: "gpt-4o-mini-tts",
              speakerVoice: "cedar",
            },
          },
        },
      },
    },
  },
}
Пример двунаправленного режима реального времени:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        mode: "bidi",
        model: "openai/gpt-5.5",
        realtime: {
          provider: "openai",
          model: "gpt-realtime-2",
          speakerVoice: "cedar",
          toolPolicy: "safe-read-only",
          consultPolicy: "always",
        },
      },
    },
  },
}
Голос как расширение существующего сеанса канала Discord:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        mode: "agent-proxy",
        model: "openai/gpt-5.5",
        agentSession: {
          mode: "target",
          target: "channel:123456789012345678",
        },
        realtime: {
          provider: "openai",
          model: "gpt-realtime-2",
          speakerVoice: "cedar",
        },
      },
    },
  },
}
В режиме agent-proxy бот присоединяется к настроенному голосовому каналу, но обращения к агенту OpenClaw используют обычный маршрутизируемый сеанс и агента целевого канала. Голосовой сеанс реального времени произносит возвращенный результат обратно в голосовой канал. Агент-супервизор по-прежнему может использовать обычные инструменты сообщений согласно своей политике инструментов, включая отправку отдельного сообщения Discord, если это правильное действие. Пока делегированный запуск OpenClaw активен, новые голосовые транскрипты Discord обрабатываются как оперативное управление запуском перед началом нового обращения к агенту. Фразы вроде “status”, “cancel that”, “use the smaller fix” или “when you’re done also check tests” классифицируются как запрос статуса, отмена, корректировка или последующий ввод для активного сеанса. Статус, отмена, принятая корректировка и результаты последующих вводов проговариваются обратно в голосовой канал, чтобы вызывающий знал, обработал ли OpenClaw запрос. Полезные формы цели:
  • target: "channel:123456789012345678" маршрутизирует через сеанс текстового канала Discord.
  • target: "123456789012345678" обрабатывается как цель канала.
  • target: "dm:123456789012345678" или target: "user:123456789012345678" маршрутизирует через этот сеанс личных сообщений.
Пример OpenAI Realtime с сильным эхом:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        mode: "bidi",
        model: "openai/gpt-5.5",
        realtime: {
          provider: "openai",
          model: "gpt-realtime-2",
          speakerVoice: "cedar",
          bargeIn: true,
          minBargeInAudioEndMs: 500,
          consultPolicy: "always",
          providers: {
            openai: {
              interruptResponseOnInputAudio: false,
            },
          },
        },
      },
    },
  },
}
Используйте это, когда модель слышит собственное воспроизведение Discord через открытый микрофон, но вы все равно хотите прерывать ее речью. OpenClaw не дает OpenAI автоматически прерываться на необработанном входном аудио, а bargeIn: true позволяет событиям начала речи в Discord и уже активному аудио говорящего отменять активные ответы реального времени до того, как следующий захваченный фрагмент достигнет OpenAI. Очень ранние сигналы вмешательства с audioEndMs ниже minBargeInAudioEndMs считаются вероятным эхом или шумом и игнорируются, чтобы модель не обрывалась на первом кадре воспроизведения. Ожидаемые голосовые логи:
  • При присоединении: discord voice: joining ... voiceSession=... supervisorSession=... agentSessionMode=... voiceModel=... realtimeModel=...
  • При запуске реального времени: discord voice: realtime bridge starting ... autoRespond=false interruptResponse=false bargeIn=false minBargeInAudioEndMs=...
  • При аудио говорящего: discord voice: realtime speaker turn opened ..., discord voice: realtime input audio started ... outputAudioMs=... outputActive=... и discord voice: realtime speaker turn closed ... chunks=... discordBytes=... realtimeBytes=... interruptedPlayback=...
  • При пропущенной устаревшей речи: discord voice: realtime forced agent consult skipped reason=incomplete-transcript ... или reason=non-actionable-closing ...
  • При завершении ответа реального времени: discord voice: realtime audio playback finishing reason=response.done ... audioMs=... chunks=...
  • При остановке/сбросе воспроизведения: discord voice: realtime audio playback stopped reason=... audioMs=... elapsedMs=... chunks=...
  • При consult в реальном времени: discord voice: realtime consult requested ... voiceSession=... supervisorSession=... question=...
  • При ответе агента: discord voice: agent turn answer ...
  • При постановке точной речи в очередь: discord voice: realtime exact speech queued ... queued=... outputAudioMs=... outputActive=..., затем discord voice: realtime exact speech dequeued reason=player-idle ...
  • При обнаружении вмешательства: discord voice: realtime barge-in detected source=speaker-start ... или discord voice: realtime barge-in detected source=active-speaker-audio ..., затем discord voice: realtime barge-in requested reason=... outputAudioMs=... outputActive=...
  • При прерывании реального времени: discord voice: realtime model interrupt requested client:response.cancel reason=barge-in, затем либо discord voice: realtime model audio truncated client:conversation.item.truncate reason=barge-in audioEndMs=..., либо discord voice: realtime model interrupt confirmed server:response.done status=cancelled ...
  • При проигнорированном эхе/шуме: discord voice: realtime model interrupt ignored client:conversation.item.truncate.skipped reason=barge-in audioEndMs=0 minAudioEndMs=250
  • При отключенном вмешательстве: discord voice: realtime capture ignored during playback (barge-in disabled) ...
  • При простое воспроизведения: discord voice: realtime barge-in ignored reason=... outputActive=false ... playbackChunks=0
Чтобы отладить обрывающееся аудио, читайте голосовые логи реального времени как временную шкалу:
  1. realtime audio playback started означает, что Discord начал воспроизводить аудио ассистента. С этого момента мост начинает считать чанки вывода ассистента, байты Discord PCM, байты провайдера реального времени и длительность синтезированного аудио.
  2. realtime speaker turn opened отмечает, что говорящий в Discord стал активен. Если воспроизведение уже активно и bargeIn включен, за этим может последовать barge-in detected source=speaker-start.
  3. realtime input audio started отмечает первый фактический аудиокадр, полученный для этого фрагмента речи. outputActive=true или ненулевое значение outputAudioMs здесь означает, что микрофон отправляет ввод, пока воспроизведение ассистента все еще активно.
  4. barge-in detected source=active-speaker-audio означает, что OpenClaw увидел живое аудио говорящего, пока воспроизведение ассистента было активно. Это полезно для отличения реального прерывания от события начала речи в Discord без полезного аудио.
  5. barge-in requested reason=... означает, что OpenClaw попросил провайдера реального времени отменить или обрезать активный ответ. Он включает outputAudioMs, outputActive и playbackChunks, чтобы можно было увидеть, сколько аудио ассистента фактически воспроизвелось до прерывания.
  6. realtime audio playback stopped reason=... является локальной точкой сброса воспроизведения Discord. Причина показывает, кто остановил воспроизведение: barge-in, player-idle, provider-clear-audio, forced-agent-consult, stream-close или session-close.
  7. realtime speaker turn closed суммирует захваченный входной фрагмент. chunks=0 или hasAudio=false означает, что фрагмент речи открылся, но пригодное аудио не дошло до моста реального времени. interruptedPlayback=true означает, что этот входной фрагмент пересекся с выводом ассистента и запустил логику вмешательства.
Полезные поля:
  • outputAudioMs: длительность аудио ассистента, сгенерированного провайдером реального времени до этой строки лога.
  • audioMs: длительность аудио ассистента, которую OpenClaw посчитал до остановки воспроизведения.
  • elapsedMs: время по настенным часам между открытием и закрытием потока воспроизведения или фрагмента речи.
  • discordBytes: байты стерео PCM 48 кГц, отправленные в Discord voice или полученные из него.
  • realtimeBytes: байты PCM в формате провайдера, отправленные провайдеру реального времени или полученные от него.
  • playbackChunks: чанки аудио ассистента, пересланные в Discord для активного ответа.
  • sinceLastAudioMs: промежуток между последним захваченным аудиокадром говорящего и закрытием фрагмента речи.
Распространенные шаблоны:
  • Немедленное обрывание с source=active-speaker-audio, малым outputAudioMs и тем же пользователем рядом обычно указывает на попадание эха динамика в микрофон. Увеличьте voice.realtime.minBargeInAudioEndMs, снизьте громкость динамиков, используйте наушники или задайте voice.realtime.providers.openai.interruptResponseOnInputAudio: false.
  • source=speaker-start, за которым следует speaker turn closed ... hasAudio=false, означает, что Discord сообщил о начале речи, но аудио не дошло до OpenClaw. Это может быть временное событие Discord voice, поведение шумоподавления или кратковременное включение микрофона клиентом.
  • audio playback stopped reason=stream-close без близкого вмешательства или provider-clear-audio означает, что локальный поток воспроизведения Discord неожиданно завершился. Проверьте предшествующие логи провайдера и плеера Discord.
  • capture ignored during playback (barge-in disabled) означает, что OpenClaw намеренно отбросил ввод, пока аудио ассистента было активно. Включите voice.realtime.bargeIn, если хотите, чтобы речь прерывала воспроизведение.
  • barge-in ignored ... outputActive=false означает, что Discord или VAD провайдера сообщил о речи, но у OpenClaw не было активного воспроизведения для прерывания. Это не должно обрывать аудио.
Учетные данные разрешаются отдельно для каждого компонента: авторизация маршрута LLM для voice.model, авторизация STT для tools.media.audio, авторизация TTS для messages.tts/voice.tts и авторизация провайдера реального времени для voice.realtime.providers или обычной конфигурации авторизации провайдера.

Голосовые сообщения

Голосовые сообщения 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)

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

  • включите Message Content Intent
  • включите Server Members Intent, если вы зависите от разрешения пользователей/участников
  • перезапустите gateway после изменения intents
  • проверьте groupPolicy
  • проверьте allowlist гильдий в channels.discord.guilds
  • если существует карта channels для гильдии, разрешены только перечисленные каналы
  • проверьте поведение requireMention и шаблоны упоминаний
Полезные проверки:
openclaw doctor
openclaw channels status --probe
openclaw logs --follow
Частые причины:
  • groupPolicy="allowlist" без соответствующей allowlist гильдии/канала
  • requireMention настроен не в том месте (должен быть в channels.discord.guilds или записи канала)
  • отправитель заблокирован allowlist users гильдии/канала
Типичные журналы:
  • Slow listener detected ...
  • stuck session: sessionKey=agent:...:discord:... state=processing ...
Параметры очереди Discord gateway:
  • одна учетная запись: channels.discord.eventQueue.listenerTimeout
  • несколько учетных записей: channels.discord.accounts.<accountId>.eventQueue.listenerTimeout
  • это управляет только работой слушателя Discord gateway, а не временем жизни хода агента
Discord не применяет тайм-аут, принадлежащий каналу, к поставленным в очередь ходам агента. Слушатели сообщений сразу передают работу дальше, а поставленные в очередь запуски Discord сохраняют порядок в рамках каждой сессии, пока жизненный цикл сессии/инструмента/среды выполнения не завершит или не прервет работу.
{
  channels: {
    discord: {
      accounts: {
        default: {
          eventQueue: {
            listenerTimeout: 120000,
          },
        },
      },
    },
  },
}
OpenClaw получает метаданные Discord /gateway/bot перед подключением. При временных сбоях используется резервный стандартный URL Gateway Discord, а записи в журналах ограничиваются по частоте.Параметры тайм-аута метаданных:
  • одна учетная запись: channels.discord.gatewayInfoTimeoutMs
  • несколько учетных записей: channels.discord.accounts.<accountId>.gatewayInfoTimeoutMs
  • резервное значение env, если конфигурация не задана: OPENCLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS
  • значение по умолчанию: 30000 (30 секунд), максимум: 120000
OpenClaw ожидает событие READY Gateway Discord во время запуска и после повторных подключений среды выполнения. Настройкам с несколькими учетными записями и разнесенным запуском может потребоваться более длинное окно READY при запуске, чем значение по умолчанию.Параметры тайм-аута READY:
  • запуск, одна учетная запись: channels.discord.gatewayReadyTimeoutMs
  • запуск, несколько учетных записей: channels.discord.accounts.<accountId>.gatewayReadyTimeoutMs
  • резервное значение env при запуске, если конфигурация не задана: OPENCLAW_DISCORD_READY_TIMEOUT_MS
  • значение по умолчанию при запуске: 15000 (15 секунд), максимум: 120000
  • среда выполнения, одна учетная запись: channels.discord.gatewayRuntimeReadyTimeoutMs
  • среда выполнения, несколько учетных записей: channels.discord.accounts.<accountId>.gatewayRuntimeReadyTimeoutMs
  • резервное значение env среды выполнения, если конфигурация не задана: OPENCLAW_DISCORD_RUNTIME_READY_TIMEOUT_MS
  • значение по умолчанию для среды выполнения: 30000 (30 секунд), максимум: 120000
Проверки разрешений channels status --probe работают только для числовых идентификаторов каналов.Если вы используете ключи-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", чтобы принимать только сообщения ботов, которые упоминают бота.OpenClaw также поставляется с общей защитой от циклов ботов. Каждый раз, когда allowBots пропускает сообщения, созданные ботами, к диспетчеризации, Discord сопоставляет входящее событие с фактами (account, channel, bot pair), а общий pair guard подавляет пару после превышения настроенного бюджета событий. Guard предотвращает неконтролируемые циклы между двумя ботами, которые раньше приходилось останавливать ограничениями скорости Discord; он не влияет на развёртывания с одним ботом или однократные ответы бота, которые остаются в пределах бюджета.Настройки по умолчанию (активны, когда задан allowBots):
  • maxEventsPerWindow: 20 — пара ботов может обменяться 20 сообщениями в пределах скользящего окна
  • windowSeconds: 60 — длина скользящего окна
  • cooldownSeconds: 60 — после срабатывания бюджета каждое дополнительное сообщение между ботами в любом направлении отбрасывается в течение одной минуты
Настройте общий default один раз в channels.defaults.botLoopProtection, затем переопределите Discord, когда легитимному workflow нужен больший запас. Приоритет:
  • channels.discord.accounts.<account>.botLoopProtection
  • channels.discord.botLoopProtection
  • channels.defaults.botLoopProtection
  • встроенные значения по умолчанию
Discord использует общие ключи maxEventsPerWindow, windowSeconds и cooldownSeconds.
{
  channels: {
    defaults: {
      botLoopProtection: {
        maxEventsPerWindow: 20,
        windowSeconds: 60,
        cooldownSeconds: 60,
      },
    },
    discord: {
      // Optional Discord-wide override. Account blocks override individual
      // fields and inherit omitted fields from here.
      botLoopProtection: {
        maxEventsPerWindow: 4,
      },
      accounts: {
        mantis: {
          // Mantis listens to other bots only when they mention her.
          allowBots: "mentions",
        },
        molty: {
          // Molty listens to all bot-authored Discord messages.
          allowBots: true,
          mentionAliases: {
            // Lets Molty write a Mantis Discord mention with the configured user id.
            Mantis: "MANTIS_DISCORD_USER_ID",
          },
          botLoopProtection: {
            // Allow up to five messages per minute before suppressing the pair.
            maxEventsPerWindow: 5,
            windowSeconds: 60,
            cooldownSeconds: 90,
          },
        },
      },
    },
  },
}
  • поддерживайте OpenClaw в актуальном состоянии (openclaw update), чтобы присутствовала логика восстановления приёма голоса Discord
  • подтвердите channels.discord.voice.daveEncryption=true (по умолчанию)
  • начните с channels.discord.voice.decryptionFailureTolerance=24 (upstream default) и настраивайте только при необходимости
  • следите в логах за:
    • discord voice: DAVE decrypt failures detected
    • discord voice: repeated decrypt failures; attempting rejoin
  • если сбои продолжаются после автоматического повторного входа, соберите логи и сравните с историей upstream-приёма DAVE в discord.js #11419 и discord.js #11449

Справочник конфигурации

Основной справочник: Справочник конфигурации - Discord.
  • запуск/auth: enabled, token, accounts.*, allowBots
  • политика: groupPolicy, dm.*, guilds.*, guilds.*.channels.*
  • команда: commands.native, commands.useAccessGroups, configWrites, slashCommand.*
  • очередь событий: eventQueue.listenerTimeout (бюджет listener), eventQueue.maxQueueSize, eventQueue.maxConcurrency
  • gateway: gatewayInfoTimeoutMs, gatewayReadyTimeoutMs, gatewayRuntimeReadyTimeoutMs
  • ответ/история: replyToMode, historyLimit, dmHistoryLimit, dms.*.historyLimit
  • доставка: textChunkLimit, chunkMode, maxLinesPerMessage
  • streaming: streaming (устаревший alias: streamMode), streaming.preview.toolProgress, draftChunk, blockStreaming, blockStreamingCoalesce
  • медиа/retry: mediaMaxMb (ограничивает исходящие загрузки в Discord, по умолчанию 100MB), retry
  • действия: actions.*
  • presence: activity, status, activityType, activityUrl
  • UI: ui.components.accentColor
  • функции: threadBindings, верхнеуровневый bindings[] (type: "acp"), pluralkit, execApprovals, intents, agentComponents.enabled, agentComponents.ttlMs, heartbeat, responsePrefix

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

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

Связанные материалы

Привязка

Привяжите пользователя Discord к gateway.

Группы

Поведение группового чата и allowlist.

Маршрутизация каналов

Направляйте входящие сообщения агентам.

Безопасность

Модель угроз и усиление защиты.

Маршрутизация нескольких агентов

Сопоставляйте серверы и каналы с агентами.

Slash commands

Поведение нативных команд.