Mainstream messaging

Discord

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

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

Создайте приложение Discord с ботом, добавьте бота на свой сервер и выполните его сопряжение с OpenClaw. По возможности используйте частный сервер; при необходимости сначала создайте его (Create My Own > For me and my friends).

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

    На портале разработчика Discord нажмите New Application и укажите название (например, «OpenClaw»).

    Откройте Bot на боковой панели и задайте для Username имя своего агента.

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

    Оставаясь на странице Bot, в разделе Privileged Gateway Intents включите:

    • Message Content Intent (обязательно)
    • Server Members Intent (рекомендуется; обязательно для списков разрешённых ролей, сопоставления имён с идентификаторами и групп доступа к аудитории канала)
    • Presence Intent (необязательно; только для обновлений присутствия)
  • Скопируйте токен бота

    На странице Bot нажмите Reset Token и скопируйте токен.

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

    Откройте OAuth2 на боковой панели. В разделе OAuth2 URL Generator включите области действия:

    • bot
    • applications.commands

    В появившемся разделе Bot Permissions включите как минимум:

    General Permissions

    • View Channels

    Text Permissions

    • Send Messages
    • Read Message History
    • Embed Links
    • Attach Files
    • Add Reactions (необязательно)

    Это базовый набор для обычных текстовых каналов. Если бот будет публиковать сообщения в ветках, в том числе при работе с форумами или медиаканалами, где создаётся или продолжается ветка, также включите Send Messages in Threads.

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

  • Включите режим разработчика и соберите идентификаторы

    В приложении Discord включите режим разработчика, чтобы можно было копировать идентификаторы:

    1. User Settings (значок шестерёнки) → Developer → включите Developer Mode (на мобильном устройстве: App SettingsAdvanced)
    2. Нажмите правой кнопкой мыши на значок сервераCopy Server ID
    3. Нажмите правой кнопкой мыши на свой аватарCopy User ID

    Сохраните идентификаторы сервера и пользователя вместе с токеном бота: далее понадобятся все три значения.

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

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

    Не отключайте этот параметр, если используете личные сообщения Discord с OpenClaw. Если вы используете только каналы сервера, после сопряжения его можно отключить.

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

    Токен бота является секретом. Задайте его на компьютере, где работает OpenClaw, прежде чем отправлять сообщения агенту:

    bash
    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" },},},}JSON5openclaw config patch --file ./discord.patch.json5 --dry-runopenclaw config patch --file ./discord.patch.json5openclaw gateway

    Если OpenClaw уже работает как фоновая служба, перезапустите её через приложение OpenClaw для Mac либо остановив и снова запустив процесс openclaw gateway run. Для установок с управляемой службой запустите openclaw gateway install из оболочки, где задана переменная DISCORD_BOT_TOKEN, либо сохраните переменную в ~/.openclaw/.env, чтобы после перезапуска служба могла разрешить ссылку на секрет среды SecretRef. Если Discord блокирует или ограничивает частоту запросов с вашего хоста при начальном поиске приложения, задайте идентификатор приложения/клиента с портала разработчика, чтобы при запуске можно было пропустить этот REST-вызов: channels.discord.applicationId для учётной записи по умолчанию или channels.discord.accounts.<accountId>.applicationId для каждого бота.

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

    Попросить агента

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

    «Я уже задал токен бота Discord в конфигурации. Заверши настройку Discord с идентификатором пользователя <user_id> и идентификатором сервера <server_id>».

    CLI / конфигурация

    Файловая конфигурация:

    json5
    {channels: {discord: {enabled: true,token: {source: "env",provider: "default",id: "DISCORD_BOT_TOKEN",},},},}

    Резервное значение из среды для учётной записи по умолчанию:

    bash
    DISCORD_BOT_TOKEN=...

    Для сценарной или удалённой настройки запишите тот же блок JSON5 с помощью openclaw config patch --file ./discord.patch.json5 --dry-run, затем повторите запуск без --dry-run. Также поддерживаются строки token в виде открытого текста и значения SecretRef для channels.discord.token из поставщиков env/file/exec. См. Управление секретами.

    При использовании нескольких ботов Discord храните токен и идентификатор приложения каждого бота в его учётной записи. Значение верхнего уровня channels.discord.applicationId наследуется учётными записями, поэтому задавайте его там, только если все учётные записи используют один идентификатор приложения.

    json5
    {channels: {discord: {enabled: true,accounts: {personal: {  token: { source: "env", provider: "default", id: "DISCORD_PERSONAL_TOKEN" },  applicationId: "111111111111111111",},work: {  token: { source: "env", provider: "default", id: "DISCORD_WORK_TOKEN" },  applicationId: "222222222222222222",},},},},}
  • Подтвердите первое сопряжение через личные сообщения

    После запуска gateway отправьте боту личное сообщение в Discord. Он ответит кодом сопряжения.

    Попросить агента

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

    «Подтверди этот код сопряжения Discord: &lt;CODE&gt;»

    CLI

    bash
    openclaw pairing list discordopenclaw pairing approve discord &lt;CODE&gt;

    Срок действия кодов сопряжения истекает через 1 час. После подтверждения общайтесь с агентом в личных сообщениях Discord.

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

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

  • Добавьте свой сервер в список разрешённых серверов

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

    Попросить агента

    «Добавь идентификатор моего сервера Discord <server_id> в список разрешённых серверов»

    Конфигурация

    json5
    {channels: {discord: {groupPolicy: "allowlist",guilds: {YOUR_SERVER_ID: {  requireMention: true,  users: ["YOUR_USER_ID"],},},},},}
  • Разрешите ответы без @упоминания

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

    По умолчанию обычные ответы в каналах сервера публикуются автоматически. Для общих постоянно активных комнат включите messages.groupChat.visibleReplies: "message_tool", чтобы агент мог наблюдать за обсуждением и публиковать сообщения только тогда, когда сочтёт ответ в канале полезным. Лучше всего это работает с моделями последнего поколения, надёжно использующими инструменты, например GPT-5.6 Sol. События фоновой комнаты не приводят к публикациям, если инструмент ничего не отправляет. Полную конфигурацию режима наблюдения см. в разделе События фоновой комнаты.

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

    Попросить агента

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

    Конфигурация

    Задайте requireMention: false в конфигурации сервера:

    json5
    {channels: {discord: {guilds: {YOUR_SERVER_ID: {  requireMention: false,},},},},}

    Чтобы для видимых ответов в группах и каналах требовалась отправка через инструмент сообщений, задайте messages.groupChat.visibleReplies: "message_tool".

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

    Долговременная память (MEMORY.md) автоматически загружается только в сеансах личных сообщений; в каналах сервера она не загружается.

    Попросить агента

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

    Вручную

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

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

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

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

    Каналы форумов

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

    • Отправьте сообщение в родительский канал форума (channel:<forumId>), чтобы автоматически создать ветку. Заголовком ветки станет первая непустая строка сообщения (обрезанная до установленного Discord ограничения имени ветки в 100 символов).
    • Используйте openclaw message thread create, чтобы создать ветку напрямую. Не передавайте --message-id для каналов форумов.

    Отправьте сообщение в родительский канал форума, чтобы создать ветку:

    bash
    openclaw message send --channel discord --target channel:<forumId> \  --message "Заголовок темы\nТекст публикации"

    Создайте ветку форума явно:

    bash
    openclaw message thread create --channel discord --target channel:<forumId> \  --thread-name "Заголовок темы" --message "Текст публикации"

    Родительские каналы форумов не принимают компоненты 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 (идентификаторы пользователей Discord, теги или *). Пользователи, не соответствующие условию, получают временное сообщение с отказом.

    По умолчанию срок действия обратных вызовов компонентов истекает через 30 минут. Установите channels.discord.agentComponents.ttlMs, чтобы изменить время жизни реестра обратных вызовов для учётной записи по умолчанию, или channels.discord.accounts.<accountId>.agentComponents.ttlMs для отдельной учётной записи. Значение задаётся в миллисекундах, должно быть положительным целым числом и ограничено величиной 86400000 (24 часа). Более длительные значения TTL подходят для процессов проверки и утверждения, в которых кнопки должны дольше оставаться доступными, но они увеличивают период, в течение которого старое сообщение Discord всё ещё может инициировать действие. Выбирайте минимальный подходящий TTL и сохраняйте значение по умолчанию, если срабатывание устаревших обратных вызовов будет неожиданным.

    Слеш-команды /model и /models открывают интерактивное средство выбора модели с раскрывающимися списками поставщиков, моделей и совместимых сред выполнения, а также этапом Submit. Команда /models add устарела и вместо регистрации моделей из чата возвращает сообщение об устаревании. Ответ средства выбора является временным и доступен только вызвавшему его пользователю. Меню выбора 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 автоматически добавляет кнопку запуска

    Пример:

    json5
    {  channel: "discord",  action: "send",  to: "channel:123456789012345678",  message: "Необязательный резервный текст",  components: {    reusable: true,    text: "Выберите вариант",    blocks: [      {        type: "actions",        buttons: [          {            label: "Утвердить",            style: "success",            allowedUsers: ["123456789012345678"],          },          { label: "Отклонить", style: "danger" },        ],      },      {        type: "actions",        select: {          type: "string",          placeholder: "Выберите вариант",          options: [            { label: "Вариант A", value: "a" },            { label: "Вариант B", value: "b" },          ],        },      },    ],    modal: {      title: "Подробности",      triggerLabel: "Открыть форму",      fields: [        { type: "text", label: "Заявитель" },        {          type: "select",          label: "Приоритет",          options: [            { label: "Низкий", value: "low" },            { label: "Высокий", value: "high" },          ],        },      ],    },  },}

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

    Политика личных сообщений

    channels.discord.dmPolicy управляет доступом к личным сообщениям. channels.discord.allowFrom является каноническим списком разрешённых отправителей личных сообщений.

    • pairing (по умолчанию)
    • allowlist (требуется хотя бы один отправитель allowFrom)
    • open (требуется, чтобы channels.discord.allowFrom включал "*")
    • disabled

    Если политика личных сообщений не является открытой, неизвестные пользователи блокируются (или получают запрос на сопряжение в режиме 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, когда это можно сделать без изменения доступа.

    Формат цели личного сообщения для доставки:

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

    Простые числовые идентификаторы обычно разрешаются как идентификаторы каналов, если активен канал по умолчанию, но идентификаторы из фактического списка allowFrom личных сообщений учётной записи для совместимости рассматриваются как цели личных сообщений пользователей.

    Группы доступа

    Для авторизации личных сообщений и текстовых команд Discord можно использовать динамические записи accessGroup:<name> в channels.discord.allowFrom.

    Имена групп доступа общие для всех каналов сообщений. Используйте type: "message.senders" для статической группы, участники которой задаются в обычном синтаксисе allowFrom каждого канала, или type: "discord.channelAudience", когда состав группы должна динамически определять текущая аудитория ViewChannel канала Discord. Общее поведение групп доступа: Группы доступа.

    json5
    {accessGroups: {operators: {  type: "message.senders",  members: {    "*": ["global-owner-id"],    discord: ["discord:123456789012345678"],    telegram: ["987654321"],  },},},channels: {discord: {  dmPolicy: "allowlist",  allowFrom: ["accessGroup:operators"],},},}

    У текстового канала Discord нет отдельного списка участников. type: "discord.channelAudience" моделирует членство следующим образом: отправитель личного сообщения является участником настроенного сервера и в данный момент имеет фактическое разрешение ViewChannel для настроенного канала после применения переопределений ролей и канала.

    Пример: разрешить отправлять боту личные сообщения всем, кто видит #maintainers, при этом сохранив личные сообщения закрытыми для всех остальных.

    json5
    {accessGroups: {maintainers: {  type: "discord.channelAudience",  guildId: "1456350064065904867",  channelId: "1456744319972282449",  membership: "canViewChannel",},},channels: {discord: {  dmPolicy: "allowlist",  allowFrom: ["accessGroup:maintainers"],},},}

    Динамические и статические записи можно сочетать:

    json5
    {accessGroups: {maintainers: {  type: "discord.channelAudience",  guildId: "1456350064065904867",  channelId: "1456744319972282449",},},channels: {discord: {  dmPolicy: "allowlist",  allowFrom: ["accessGroup:maintainers", "discord:123456789012345678"],},},}

    При сбое поиска доступ запрещается. Если Discord возвращает Missing Access, поиск участника завершается с ошибкой или канал принадлежит другому серверу, отправитель личного сообщения считается неавторизованным.

    При использовании групп доступа на основе аудитории канала включите Server Members Intent в Discord Developer Portal. Личные сообщения не содержат состояние участника сервера, поэтому OpenClaw получает сведения об участнике через Discord REST во время авторизации.

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

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

    • open
    • allowlist
    • disabled

    Безопасным базовым вариантом при наличии channels.discord является allowlist.

    Поведение allowlist:

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

    Пример:

    json5
    {channels: {discord: {  groupPolicy: "allowlist",  guilds: {    "123456789012345678": {      requireMention: true,      ignoreOtherMentions: true,      users: ["987654321098765432"],      roles: ["123456789012345678"],      channels: {        general: { enabled: true },        help: { enabled: true, requireMention: true },      },    },  },},},}

    Устаревший поканальный ключ allow переносится в enabled командой openclaw doctor --fix.

    Если задать только DISCORD_BOT_TOKEN и не создавать блок channels.discord, резервным значением среды выполнения будет groupPolicy="allowlist" (с предупреждением в журналах), даже если channels.defaults.groupPolicy имеет значение open.

    Упоминания и групповые личные сообщения

    По умолчанию сообщения сервера обрабатываются только при наличии упоминания.

    Обнаружение упоминаний включает:

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

    При создании исходящих сообщений Discord используйте канонический синтаксис упоминаний: <@USER_ID> для пользователей, <#CHANNEL_ID> для каналов и <@&ROLE_ID> для ролей. Не используйте устаревшую форму упоминания по псевдониму <@!USER_ID>.

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

    Групповые личные сообщения:

    • по умолчанию: игнорируются (dm.groupEnabled=false)
    • необязательный список разрешённых через dm.groupChannels (идентификаторы или символьные идентификаторы каналов)

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

    Используйте bindings[].match.roles, чтобы направлять участников сервера Discord разным агентам по идентификатору роли. Привязки на основе ролей принимают только идентификаторы ролей и проверяются после привязок к собеседнику или родительскому собеседнику, но до привязок только к серверу. Если привязка также задаёт другие поля сопоставления (например, peer + guildId + roles), должны совпасть все настроенные поля.

    json5
    {  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, что и обычная обработка сообщений.
    • Команды могут по-прежнему отображаться в интерфейсе Discord для неавторизованных пользователей; при выполнении OpenClaw проверяет авторизацию и отвечает «нет авторизации».
    • Настройки слеш-команд по умолчанию: ephemeral: true (channels.discord.slashCommand.ephemeral).

    Каталог команд и описание их поведения см. в разделе Слеш-команды.

    Подробности функций

    Теги ответов и нативные ответы

    Discord поддерживает теги ответов в выводе агента:

    • [[reply_to_current]]
    • [[reply_to:<id>]]

    Управляется параметром channels.discord.replyToMode:

    • off (по умолчанию): без неявного создания веток ответов; явные теги [[reply_to_*]] по-прежнему учитываются
    • first: прикрепляет неявную ссылку нативного ответа к первому исходящему сообщению Discord в текущем ходе
    • all: прикрепляет её к каждому исходящему сообщению
    • batched: прикрепляет её только тогда, когда входящее событие представляло собой сгруппированный с задержкой пакет из нескольких сообщений — это удобно, если нативные ответы нужны преимущественно для неоднозначных всплесков активности в чатах, а не для каждого хода с одним сообщением

    Идентификаторы сообщений доступны в контексте и истории, поэтому агенты могут обращаться к конкретным сообщениям.

    Предпросмотр ссылок

    По умолчанию Discord создаёт для URL расширенные встроенные карточки. OpenClaw по умолчанию подавляет такие автоматически созданные карточки в исходящих сообщениях Discord, поэтому отправленные агентом URL остаются обычными ссылками, если вы явно не включите эту возможность:

    json5
    {channels: {discord: {  suppressEmbeds: false,},},}

    Задайте channels.discord.accounts.<id>.suppressEmbeds, чтобы переопределить настройку для одной учётной записи. При отправке через инструмент сообщений агент также может передать suppressEmbeds: false для одного сообщения. Явно заданные полезные нагрузки Discord embeds не подавляются настройкой предпросмотра ссылок по умолчанию.

    Предпросмотр потоковой передачи в реальном времени

    OpenClaw может передавать черновик ответа потоково, отправляя временное сообщение и редактируя его по мере поступления текста. channels.discord.streaming.mode принимает значения off | partial | block | progress (значение по умолчанию, если не задан ключ streaming или устаревший ключ streamMode). streamMode — устаревший псевдоним; выполните openclaw doctor --fix, чтобы преобразовать сохранённую конфигурацию в каноническую вложенную структуру streaming.

    json5
    {channels: {discord: {  streaming: {    mode: "progress",    progress: {      label: "auto",      maxLines: 8,      maxLineChars: 120,      toolProgress: true,      commentary: false,    },  },},},}
    • off отключает редактирование предпросмотра Discord.
    • partial редактирует одно сообщение предпросмотра по мере поступления токенов.
    • block выводит фрагменты размером с черновик; их размер и точки разбиения настраиваются с помощью streaming.preview.chunk (minChars, maxChars, breakPreference) с ограничением до textChunkLimit. Если потоковая передача блоками включена явно, OpenClaw пропускает поток предпросмотра, чтобы избежать двойной потоковой передачи.
    • progress сохраняет один редактируемый черновик состояния и обновляет его сведениями о ходе работы инструментов до окончательной доставки. Необработанные сведения о ходе работы используют общую начальную метку как обновляемую строку; описательное состояние показывает только описание, если метка не настроена явно.
    • Медиафайлы, ошибки и окончательные ответы с явной привязкой отменяют ожидающие изменения предпросмотра.
    • streaming.preview.toolProgress (по умолчанию true) определяет, используют ли обновления инструментов и хода работы повторно сообщение предпросмотра.
    • Строки инструментов и хода работы отображаются в компактном виде: эмодзи, заголовок и подробности, если они доступны, например 🛠️ Bash: run tests или 🔎 Web Search: for "query".
    • streaming.progress.commentary (по умолчанию false) включает поясняющий или вводный текст ассистента во временном черновике хода работы. Перед отображением пояснения очищаются, остаются временными и не влияют на доставку окончательного ответа.
    • streaming.progress.maxLineChars задаёт лимит предпросмотра хода работы для каждой строки. Обычный текст сокращается по границам слов; в командах и путях сохраняются полезные окончания.
    • streaming.preview.commandText / streaming.progress.commandText управляет подробностями команд и их выполнения в компактных строках хода работы: raw (по умолчанию) или status (только метка инструмента).

    Чтобы скрыть необработанный текст команд и их выполнения, сохранив компактные строки хода работы:

    json
    {  "channels": {    "discord": {      "streaming": {        "mode": "progress",        "progress": {          "toolProgress": true,          "commandText": "status"        }      }    }  }}

    Потоковый предпросмотр поддерживает только текст; ответы с медиафайлами доставляются обычным способом.

    История, контекст и поведение веток

    Контекст истории сервера:

    • channels.discord.historyLimit по умолчанию 20
    • резервное значение: messages.groupChat.historyLimit
    • 0 отключает

    Управление историей личных сообщений:

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

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

    • Ветки Discord маршрутизируются как сеансы каналов и наследуют конфигурацию родительского канала, если она не переопределена.
    • Сеансы веток наследуют выбранное на уровне сеанса родительского канала значение /model как резервное значение только для модели; локальные для ветки значения /model имеют приоритет, а история расшифровки родительского канала не копируется, если не включено наследование расшифровки.
    • channels.discord.thread.inheritParent (по умолчанию false) включает для новых автоматически создаваемых веток начальное заполнение из расшифровки родительского канала. Переопределение для отдельной учётной записи: channels.discord.accounts.<id>.thread.inheritParent.
    • Реакции инструмента сообщений могут разрешать цели личных сообщений user:<id>.
    • guilds.<guild>.channels.<channel>.requireMention: false сохраняется при резервной активации на этапе ответа.

    Темы каналов добавляются как недоверенный контекст. Списки разрешений определяют, кто может активировать агента, но не образуют полноценную границу редактирования дополнительного контекста.

    Сеансы субагентов, привязанные к веткам

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

    Команды:

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

    Конфигурация:

    json5
    {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 настройте типизированные привязки ACP верхнего уровня, нацеленные на беседы Discord.

    Путь конфигурации: bindings[] с type: "acp" и match.channel: "discord".

    json5
    {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.

    Уведомления о реакциях

    Режим уведомлений о реакциях для каждого сервера (guilds.<id>.reactionNotifications):

    • 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 или имена пользовательских эмодзи.
    • Используйте "", чтобы отключить реакцию для канала или учётной записи.

    Область действия (messages.ackReactionScope):

    Значения: "all" (личные сообщения и группы, включая фоновые события комнат), "direct" (только личные сообщения), "group-all" (каждое групповое сообщение, кроме фоновых событий комнат; без личных сообщений), "group-mentions" (группы, когда бот упомянут; без личных сообщений, по умолчанию), "off" / "none" (отключено).

    Запись конфигурации

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

    Чтобы отключить:

    json5
    {channels: {discord: {  configWrites: false,},},}
    Прокси Gateway

    Направляйте WebSocket-трафик шлюза Discord и начальные REST-запросы (идентификатор приложения + разрешение списка разрешённых значений) через HTTP(S)-прокси с помощью channels.discord.proxy. Проксирование WebSocket шлюза Discord задаётся явно; WebSocket-соединения не наследуют переменные окружения прокси из процесса Gateway. Начальные REST-запросы используют этот прокси, когда настроен channels.discord.proxy.

    json5
    {channels: {discord: {  proxy: "http://proxy.example:8080",},},}

    Переопределение для отдельной учётной записи:

    json5
    {channels: {discord: {  accounts: {    primary: {      proxy: "http://proxy.example:8080",    },  },},},}
    Поддержка PluralKit

    Включите разрешение PluralKit, чтобы сопоставлять проксированные сообщения с идентичностью участника системы:

    json5
    {channels: {discord: {  pluralkit: {    enabled: true,    token: "pk_live_...", // optional; needed for private systems  },},},}

    Примечания:

    • в списках разрешённых значений можно использовать pk:<memberId>
    • отображаемые имена участников сопоставляются только по имени/слагу, когда channels.discord.dangerouslyAllowNameMatching: true
    • при поиске выполняется запрос к API PluralKit с исходным идентификатором сообщения
    • если поиск завершается неудачно, проксированные сообщения считаются сообщениями бота и отбрасываются, если только allowBots не разрешает их обработку
    Псевдонимы исходящих упоминаний

    Используйте mentionAliases, когда агентам нужны детерминированные исходящие упоминания известных пользователей Discord. Ключи — это идентификаторы без начального @; значения — идентификаторы пользователей Discord. Неизвестные идентификаторы, @everyone, @here и упоминания внутри фрагментов кода Markdown остаются без изменений.

    json5
    {channels: {discord: {  mentionAliases: {    SupportLead: "123456789012345678",  },  accounts: {    ops: {      mentionAliases: {        OpsLead: "234567890123456789",      },    },  },},},}
    Настройка присутствия

    Обновления присутствия применяются, когда вы задаёте поле статуса или активности либо включаете автоматическое присутствие.

    Только статус:

    json5
    {channels: {discord: {  status: "idle",},},}

    Активность (пользовательский статус является типом активности по умолчанию, когда задан activity):

    json5
    {channels: {discord: {  activity: "Focus time",  activityType: 4,},},}

    Трансляция:

    json5
    {channels: {discord: {  activity: "Live coding",  activityType: 1,  activityUrl: "https://twitch.tv/openclaw",},},}

    Карта типов активности:

    • 0: Играет
    • 1: Транслирует (требуется activityUrl; для activityUrl, в свою очередь, требуется activityType: 1)
    • 2: Слушает
    • 3: Смотрит
    • 4: Пользовательский (текст активности используется как состояние статуса; эмодзи необязателен)
    • 5: Соревнуется

    Автоматическое присутствие (сигнал состояния среды выполнения):

    json5
    {channels: {discord: {  autoPresence: {    enabled: true,    intervalMs: 30000,    minUpdateIntervalMs: 15000,    exhaustedText: "token exhausted",  },},},}

    Автоматическое присутствие сопоставляет доступность среды выполнения со статусом Discord: исправна => online, нарушена или неизвестна => idle, исчерпана или недоступна => dnd. Значения по умолчанию: intervalMs 30000, minUpdateIntervalMs 15000 (должно быть меньше или равно intervalMs). Необязательные переопределения текста:

    • autoPresence.healthyText
    • autoPresence.degradedText
    • autoPresence.exhaustedText (поддерживает заполнитель {reason})
    Подтверждения в Discord

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

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

    • channels.discord.execApprovals.enabled
    • channels.discord.execApprovals.approvers (необязательно; при возможности используется резервное значение commands.ownerAllowFrom)
    • channels.discord.execApprovals.target (dm | channel | both, по умолчанию: dm)
    • agentFilter, sessionFilter, cleanupAfterResolve

    Discord автоматически включает встроенные подтверждения выполнения, когда enabled не задан или имеет значение "auto" и удаётся определить хотя бы одного подтверждающего — из execApprovals.approvers или commands.ownerAllowFrom. Discord не определяет подтверждающих выполнение из allowFrom канала, устаревшего dm.allowFrom или defaultTo личных сообщений. Задайте enabled: false, чтобы явно отключить Discord как встроенный клиент подтверждений.

    Для конфиденциальных групповых команд, доступных только владельцу, таких как /diagnostics и /export-trajectory, OpenClaw отправляет запросы подтверждения и окончательные результаты в частном порядке. Сначала используется личное сообщение Discord, если для вызвавшего команду владельца существует маршрут владельца Discord; иначе используется первый доступный маршрут владельца из commands.ownerAllowFrom, например Telegram.

    Когда target имеет значение channel или both, запрос подтверждения виден в канале. Использовать кнопки могут только определённые подтверждающие; остальные пользователи получают временное уведомление об отказе. Запросы подтверждения содержат текст команды, поэтому включайте доставку в канал только в доверенных каналах. Если идентификатор канала нельзя получить из ключа сеанса, OpenClaw использует доставку в личные сообщения.

    Discord отображает общие кнопки подтверждения, используемые другими каналами чатов; встроенный адаптер Discord главным образом добавляет маршрутизацию личных сообщений подтверждающим и рассылку по каналам. Когда эти кнопки присутствуют, они являются основным интерфейсом подтверждения; OpenClaw должен включать ручную команду /approve только тогда, когда результат инструмента указывает, что подтверждения в чате недоступны или ручное подтверждение является единственным вариантом. Если встроенная среда выполнения подтверждений Discord не активна, OpenClaw сохраняет видимым локальный детерминированный запрос /approve <id> <decision>. Если среда выполнения активна, но встроенную карточку невозможно доставить ни одному получателю, OpenClaw отправляет в тот же чат резервное уведомление с точной командой /approve из ожидающего подтверждения.

    Аутентификация Gateway и разрешение подтверждений следуют общему контракту клиента Gateway (идентификаторы plugin: разрешаются через plugin.approval.resolve; остальные идентификаторы — через exec.approval.resolve). По умолчанию срок действия подтверждений истекает через 30 минут.

    См. Подтверждения выполнения.

    Инструменты и ограничения действий

    Действия с сообщениями Discord охватывают обмен сообщениями, администрирование каналов, модерацию, присутствие и метаданные.

    Основные примеры:

    • обмен сообщениями: sendMessage, readMessages, editMessage, deleteMessage, threadReply
    • реакции: react, reactions, emojiList
    • модерация: timeout, kick, ban
    • присутствие: setPresence

    Действие event-create принимает необязательный параметр image (URL или путь к локальному файлу), чтобы задать обложку запланированного события.

    Ограничения действий находятся в channels.discord.actions.*.

    Поведение ограничений по умолчанию:

    Группа действий По умолчанию
    reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions включено
    roles отключено
    moderation отключено
    presence отключено

    Интерфейс компонентов v2

    OpenClaw использует компоненты Discord v2 для подтверждений выполнения и маркеров между контекстами. Действия с сообщениями Discord также могут принимать components для пользовательского интерфейса (расширенная возможность; требуется сформировать полезную нагрузку компонента с помощью инструмента Discord), при этом устаревшие embeds по-прежнему доступны, но не рекомендуются.

    • channels.discord.ui.components.accentColor задаёт акцентный цвет контейнеров компонентов Discord (шестнадцатеричный формат). Для отдельной учётной записи: channels.discord.accounts.<id>.ui.components.accentColor.
    • channels.discord.agentComponents.ttlMs определяет, как долго отправленные обратные вызовы компонентов Discord остаются зарегистрированными (по умолчанию 1800000, максимум 86400000). Для отдельной учётной записи: channels.discord.accounts.<id>.agentComponents.ttlMs.
    • embeds игнорируются при наличии компонентов v2.
    • Предварительный просмотр обычных URL по умолчанию отключён. Задайте suppressEmbeds: false для действия с сообщением, если требуется развернуть одну исходящую ссылку.

    Пример:

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

    Голосовая связь

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

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

    Контрольный список настройки:

    1. Включите Message Content Intent в Discord Developer Portal.
    2. Включите Server Members Intent, если используются списки разрешённых ролей или пользователей.
    3. Пригласите бота с областями доступа 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.

    bash
    /vc join channel:<voice-channel-id>/vc status/vc leave

    Чтобы проверить фактические разрешения бота перед подключением:

    bash
    openclaw channels capabilities --channel discord --target channel:<voice-channel-id>

    Пример автоматического подключения:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        model: "openai/gpt-5.6-sol",        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.1",          speakerVoice: "cedar",        },      },    },  },}

    Примечания:

    • Голосовой режим Discord включается явно для конфигураций, предназначенных только для текста; задайте channels.discord.voice.enabled=true (или сохраните существующий блок channels.discord.voice), чтобы включить команды /vc, голосовую среду выполнения и намерение Gateway GuildVoiceStates. Параметр channels.discord.intents.voiceStates может явно переопределить подписку на намерение; не задавайте его, чтобы она определялась фактическим состоянием голосового режима.
    • 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.1 с интеллектуальным ядром Codex используйте voice.realtime.model: "gpt-realtime-2.1" и voice.model: "openai/gpt-5.6-sol".
    • По умолчанию голосовые режимы реального времени включают небольшие файлы профиля 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 для немедленного прерывания в помещениях с малым эхом или увеличьте значение для конфигураций динамиков с сильным эхом.
    • voice.tts переопределяет messages.tts только для голосового воспроизведения stt-tts; вместо этого режимы реального времени используют voice.realtime.speakerVoice. Чтобы использовать голос OpenAI для воспроизведения в Discord, задайте voice.tts.provider: "openai" и выберите голос синтеза речи в voice.tts.providers.openai.speakerVoice. cedar — хороший вариант с мужским звучанием в текущей модели TTS OpenAI.
    • Переопределения Discord systemPrompt для отдельных каналов применяются к репликам, полученным из расшифровки речи в соответствующем голосовом канале.
    • Для реплик из расшифровки речи и команд /vc статус владельца Discord определяется по записям Discord в commands.ownerAllowFrom. Если владелец команд Discord не настроен, OpenClaw использует allowFrom выбранной учётной записи Discord (или устаревший dm.allowFrom). Доступность инструментов агента определяется настроенной политикой инструментов для выбранного сеанса.
    • Если voice.autoJoin содержит несколько записей для одной и той же гильдии, OpenClaw подключается к последнему настроенному каналу этой гильдии.
    • voice.allowedChannels — необязательный список разрешённых мест пребывания. Не задавайте его, чтобы разрешить /vc join подключение к любому авторизованному голосовому каналу Discord. Если параметр задан, /vc join, автоматическое подключение при запуске и перемещения голосового состояния бота ограничиваются перечисленными записями { guildId, channelId }. Задайте пустой массив, чтобы запретить все подключения к голосовым каналам Discord. Если Discord перемещает бота за пределы списка разрешённых каналов, OpenClaw покидает этот канал и повторно подключается к настроенному целевому каналу автоматического подключения, если он доступен.
    • voice.daveEncryption и voice.decryptionFailureTolerance передаются в параметры подключения @discordjs/voice; значения по умолчанию в вышестоящем проекте — daveEncryption=true и decryptionFailureTolerance=24.
    • OpenClaw использует встроенный кодек libopus-wasm для приёма голоса Discord и воспроизведения необработанного PCM в реальном времени. В поставку входит закреплённая версия сборки libopus для WebAssembly, поэтому нативные дополнения opus не требуются.
    • voice.connectTimeoutMs задаёт время первоначального ожидания состояния @discordjs/voice Ready для /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, закрывшего проблему discord.js #11419.
    • События приёма The operation was aborted ожидаемы, когда OpenClaw завершает захваченный сегмент речи пользователя; это подробная диагностика, а не предупреждения.
    • Подробные журналы голосового режима Discord содержат ограниченный однострочный предварительный просмотр расшифровки STT для каждого принятого сегмента речи, поэтому при отладке видны и реплика пользователя, и ответ агента без вывода неограниченного объёма текста расшифровки.
    • В режиме agent-proxy резервный механизм принудительного обращения пропускает предположительно незавершённые фрагменты расшифровки, например текст, заканчивающийся на ... или союзом вроде «и», а также очевидные не требующие действий завершающие фразы вроде «скоро вернусь» или «пока». Когда это предотвращает выдачу устаревшего ответа из очереди, в журналах отображается forced agent consult skipped reason=....

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

    Используйте voice.followUsers, если голосовой бот Discord должен оставаться с одним или несколькими известными пользователями Discord, а не подключаться к фиксированному каналу при запуске или ожидать /vc join.

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        followUsersEnabled: true,        followUsers: ["discord:123456789012345678"],        allowedChannels: [          {            guildId: "123456789012345678",            channelId: "234567890123456789",          },        ],      },    },  },}

    Поведение:

    • followUsers принимает необработанные идентификаторы пользователей Discord и значения discord:<id>. OpenClaw нормализует обе формы перед сопоставлением событий состояния голосового канала.
    • followUsersEnabled по умолчанию имеет значение true, когда настроен followUsers. Установите значение false, чтобы сохранить список, но отключить автоматическое следование в голосовых каналах.
    • followUsers управляет только присутствием в голосовом канале. Он не предоставляет доступ к роли говорящего или полномочия владельца; настройте commands.ownerAllowFrom, а также пользователей и роли сервера или канала отдельно.
    • Когда отслеживаемый пользователь подключается к разрешённому голосовому каналу, 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.
    • При воспроизведении файлов и потоков от провайдера данные перекодируются с помощью ffmpeg в необработанный стереофонический PCM с частотой 48 кГц, после чего 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; провайдеры с поддержкой потоковой передачи отправляют данные непосредственно проигрывателю, а в противном случае полученный аудиофайл воспроизводится в подключённом канале.

    Пример стандартного сеанса голосового канала с проксированием через агента:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        model: "openai/gpt-5.6-sol",        followUsersEnabled: true,        followUsers: ["123456789012345678"],        realtime: {          provider: "openai",          model: "gpt-realtime-2.1",          speakerVoice: "cedar",        },      },    },  },}

    Если блок voice.agentSession отсутствует, каждый голосовой канал получает отдельный маршрутизируемый сеанс OpenClaw. Например, /vc join channel:234567890123456789 взаимодействует с сеансом соответствующего голосового канала Discord. Модель реального времени служит только голосовым интерфейсом; содержательные запросы передаются настроенному агенту OpenClaw. Если модель реального времени создаёт окончательную транскрипцию без вызова инструмента консультации, OpenClaw принудительно вызывает консультацию как резервный механизм, чтобы стандартное поведение по-прежнему соответствовало разговору с агентом.

    Пример устаревшего режима STT и TTS:

    json5
    {  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",            },          },        },      },    },  },}

    Пример двунаправленного режима реального времени:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        mode: "bidi",        model: "openai/gpt-5.6-sol",        realtime: {          provider: "openai",          model: "gpt-realtime-2.1",          speakerVoice: "cedar",          toolPolicy: "safe-read-only",          consultPolicy: "always",        },      },    },  },}

    Голосовой режим как расширение существующего сеанса канала Discord:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        mode: "agent-proxy",        model: "openai/gpt-5.6-sol",        agentSession: {          mode: "target",          target: "channel:123456789012345678",        },        realtime: {          provider: "openai",          model: "gpt-realtime-2.1",          speakerVoice: "cedar",        },      },    },  },}

    В режиме agent-proxy бот подключается к настроенному голосовому каналу, но обращения к агенту OpenClaw используют обычный маршрутизируемый сеанс и агента целевого канала. Голосовой сеанс реального времени озвучивает возвращённый результат в голосовом канале. Агент-супервизор по-прежнему может использовать обычные инструменты сообщений в соответствии со своей политикой инструментов, включая отправку отдельного сообщения в Discord, если это подходящее действие.

    Пока выполняется делегированный запуск OpenClaw, новые голосовые транскрипции Discord рассматриваются как команды управления активным запуском, прежде чем будет начато очередное обращение к агенту. Фразы наподобие «статус», «отмени это», «используй более компактное исправление» или «когда закончишь, также проверь тесты» классифицируются как запрос состояния, отмена, корректирующее указание или последующее действие для активного сеанса. Результаты запроса состояния, отмены, принятого корректирующего указания и последующего действия озвучиваются в голосовом канале, чтобы вызывающий пользователь знал, обработал ли OpenClaw запрос.

    Полезные формы целевых объектов:

    • target: "channel:123456789012345678" направляет запрос через сеанс текстового канала Discord.
    • target: "123456789012345678" рассматривается как целевой канал.
    • target: "dm:123456789012345678" или target: "user:123456789012345678" направляет запрос через соответствующий сеанс личных сообщений.

    Пример OpenAI Realtime для среды с сильным эхом:

    json5
    {  channels: {    discord: {      voice: {        enabled: true,        mode: "bidi",        model: "openai/gpt-5.6-sol",        realtime: {          provider: "openai",          model: "gpt-realtime-2.1",          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=...
    • При консультации в реальном времени: 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 начал воспроизводить аудио ассистента. С этого момента мост начинает подсчитывать фрагменты вывода ассистента, байты PCM Discord, байты данных реального времени провайдера и длительность синтезированного аудио.
    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 или полученные из него.
    • 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, работа шумового порога или кратковременное включение микрофона клиентом.
    • 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 означает, что VAD Discord или провайдера обнаружил речь, но в 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.
    bash
    message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)

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

    Использованы запрещенные намерения или бот не видит сообщения сервера
    • включите Message Content Intent
    • включите Server Members Intent, если используете разрешение пользователей или участников
    • перезапустите Gateway после изменения намерений
    Сообщения сервера неожиданно блокируются
    • проверьте groupPolicy
    • проверьте список разрешений сервера в channels.discord.guilds
    • если существует карта channels сервера, разрешены только перечисленные каналы
    • проверьте поведение requireMention и шаблоны упоминаний

    Полезные проверки:

    bash
    openclaw doctoropenclaw channels status --probeopenclaw logs --follow
    Упоминание не требуется, но сообщения по-прежнему блокируются

    Распространенные причины:

    • groupPolicy="allowlist" без соответствующего списка разрешений сервера или канала
    • requireMention настроен не там, где нужно (он должен находиться в channels.discord.guilds или записи канала)
    • отправитель заблокирован списком разрешений users сервера или канала
    Длительные операции Discord или дублирующиеся ответы

    Типичные записи журнала:

    • Slow listener detected ...
    • stuck session: sessionKey=agent:...:discord:... state=processing ...

    Параметры очереди Gateway Discord:

    • одна учетная запись: channels.discord.eventQueue.listenerTimeout
    • несколько учетных записей: channels.discord.accounts.<accountId>.eventQueue.listenerTimeout
    • это управляет только работой прослушивателя Gateway Discord, а не временем существования операции агента

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

    json5
    {channels: {discord: {  accounts: {    default: {      eventQueue: {        listenerTimeout: 120000,      },    },  },},},}
    Предупреждения о тайм-ауте получения метаданных Gateway

    Перед подключением OpenClaw получает метаданные /gateway/bot Discord. При временных сбоях используется URL-адрес Gateway Discord по умолчанию, а частота записей в журнале ограничивается.

    Параметры тайм-аута метаданных:

    • одна учетная запись: channels.discord.gatewayInfoTimeoutMs
    • несколько учетных записей: channels.discord.accounts.<accountId>.gatewayInfoTimeoutMs
    • резервное значение из переменной среды, если параметр не задан: OPENCLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS
    • по умолчанию: 30000 (30 секунд), максимум: 120000
    Перезапуски из-за тайм-аута READY Gateway

    OpenClaw ожидает событие READY Gateway Discord при запуске и после повторных подключений среды выполнения. В конфигурациях с несколькими учетными записями и поэтапным запуском может потребоваться более длительное окно READY при запуске, чем предусмотрено по умолчанию.

    Параметры тайм-аута READY:

    • запуск с одной учетной записью: channels.discord.gatewayReadyTimeoutMs
    • запуск с несколькими учетными записями: channels.discord.accounts.<accountId>.gatewayReadyTimeoutMs
    • резервное значение из переменной среды при запуске, если параметр не задан: OPENCLAW_DISCORD_READY_TIMEOUT_MS
    • значение при запуске по умолчанию: 15000 (15 секунд), максимум: 120000
    • среда выполнения с одной учетной записью: channels.discord.gatewayRuntimeReadyTimeoutMs
    • среда выполнения с несколькими учетными записями: channels.discord.accounts.<accountId>.gatewayRuntimeReadyTimeoutMs
    • резервное значение из переменной среды для среды выполнения, если параметр не задан: OPENCLAW_DISCORD_RUNTIME_READY_TIMEOUT_MS
    • значение среды выполнения по умолчанию: 30000 (30 секунд), максимум: 120000
    Несоответствия при аудите разрешений

    Проверки разрешений channels status --probe работают только с числовыми идентификаторами каналов.

    Если вы используете ключи-краткие имена, сопоставление во время выполнения может по-прежнему работать, но проверка не сможет полностью проверить разрешения.

    Проблемы с личными сообщениями и сопряжением
    • личные сообщения отключены: channels.discord.dm.enabled=false
    • политика личных сообщений отключена: channels.discord.dmPolicy="disabled" (устаревшее: channels.discord.dm.policy)
    • ожидание подтверждения сопряжения в режиме pairing
    Циклы между ботами

    По умолчанию сообщения от ботов игнорируются.

    Если вы задаете channels.discord.allowBots=true, используйте строгие правила упоминаний и списков разрешений, чтобы избежать циклического поведения. Предпочтительно использовать channels.discord.allowBots="mentions", чтобы принимать только сообщения ботов, в которых упомянут этот бот.

    OpenClaw также включает общую защиту от циклов ботов. Каждый раз, когда allowBots позволяет сообщениям от ботов поступать на диспетчеризацию, Discord преобразует входящее событие в факты (account, channel, bot pair), а общий ограничитель пар блокирует пару после превышения настроенного бюджета событий. Ограничитель предотвращает неуправляемые циклы между двумя ботами, которые ранее приходилось останавливать с помощью ограничений частоты Discord; он не влияет на развертывания с одним ботом или однократные ответы ботов, не превышающие бюджет.

    Настройки по умолчанию (активны, когда задан allowBots):

    • maxEventsPerWindow: 20 -- пара ботов может обменяться 20 сообщениями в пределах скользящего окна
    • windowSeconds: 60 -- длительность скользящего окна
    • cooldownSeconds: 60 -- после исчерпания бюджета каждое дополнительное сообщение между ботами в любом направлении отбрасывается в течение одной минуты

    Настройте общее значение по умолчанию один раз в channels.defaults.botLoopProtection, а затем переопределите его для Discord, если допустимому рабочему процессу требуется больший запас. Приоритет следующий:

    • channels.discord.accounts.<account>.botLoopProtection
    • channels.discord.botLoopProtection
    • channels.defaults.botLoopProtection
    • встроенные значения по умолчанию

    Discord использует общие ключи maxEventsPerWindow, windowSeconds и cooldownSeconds.

    json5
    {channels: {defaults: {  botLoopProtection: {    maxEventsPerWindow: 20,    windowSeconds: 60,    cooldownSeconds: 60,  },},discord: {  // Необязательное переопределение для всего Discord. Блоки учетных записей переопределяют отдельные  // поля и наследуют отсюда пропущенные поля.  botLoopProtection: {    maxEventsPerWindow: 4,  },  accounts: {    alpha: {      // Alpha принимает сообщения других ботов, только когда они упоминают его.      allowBots: "mentions",    },    bravo: {      // Bravo принимает все сообщения Discord, созданные ботами.      allowBots: true,      mentionAliases: {        // Позволяет Bravo записать упоминание Alpha в Discord с настроенным идентификатором пользователя.        Alpha: "ALPHA_DISCORD_USER_ID",      },      botLoopProtection: {        // Разрешить до пяти сообщений в минуту перед блокировкой пары.        maxEventsPerWindow: 5,        windowSeconds: 60,        cooldownSeconds: 90,      },    },  },},},}
    Пропуски голосового 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
    • если сбои продолжаются после автоматического повторного подключения, соберите журналы и сопоставьте их с историей приема DAVE в исходном проекте: discord.js #11419 и discord.js #11449

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

    Основной справочник: Справочник по конфигурации — Discord.

    Ключевые поля Discord
    • запуск и аутентификация: enabled, token, applicationId, accounts.*, allowBots
    • политика: groupPolicy, dmPolicy, allowFrom, dm.*, guilds.*, guilds.*.channels.*
    • команды: commands.native, commands.useAccessGroups (глобально), configWrites, slashCommand.ephemeral
    • очередь событий: eventQueue.listenerTimeout (бюджет прослушивателя, по умолчанию 120000), eventQueue.maxQueueSize (по умолчанию 10000), eventQueue.maxConcurrency (по умолчанию 50)
    • Gateway: proxy, gatewayInfoTimeoutMs, gatewayReadyTimeoutMs, gatewayRuntimeReadyTimeoutMs
    • ответы и история: replyToMode, historyLimit, dmHistoryLimit, dms.*.historyLimit
    • доставка: textChunkLimit (по умолчанию 2000), maxLinesPerMessage (по умолчанию 17)
    • потоковая передача: streaming.mode, streaming.chunkMode, streaming.preview.*, streaming.progress.*, streaming.block.* (устаревшие плоские ключи streamMode, draftChunk, blockStreaming, blockStreamingCoalesce, chunkMode переносятся в streaming.* с помощью openclaw doctor --fix)
    • медиа и повторные попытки: mediaMaxMb (ограничивает исходящие загрузки Discord, по умолчанию 100), retry
    • действия: actions.*
    • присутствие: activity, status, activityType, activityUrl, autoPresence.*
    • интерфейс: ui.components.accentColor
    • возможности: threadBindings, верхнеуровневый bindings[] (type: "acp"), pluralkit, execApprovals, intents, agentComponents.enabled, agentComponents.ttlMs, heartbeat, responsePrefix

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

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

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

    Was this useful?
    On this page

    On this page