Mainstream messaging
Discord
Готово для особистих повідомлень і каналів гільдій через офіційний Discord Gateway.
Особисті повідомлення Discord за замовчуванням використовують режим спарювання.
Нативна поведінка команд і каталог команд.
Міжканальна діагностика та процес виправлення.
Швидке налаштування
Вам потрібно створити новий застосунок із ботом, додати бота на свій сервер і спарувати його з OpenClaw. Ми рекомендуємо додавати бота на власний приватний сервер. Якщо у вас його ще немає, спочатку створіть його (виберіть Create My Own > For me and my friends).
Create a Discord application and bot
Перейдіть до Discord Developer Portal і натисніть New Application. Назвіть його, наприклад, "OpenClaw".
Натисніть Bot на бічній панелі. Встановіть Username на те ім'я, яким ви називаєте свого агента OpenClaw.
Enable privileged intents
Залишаючись на сторінці Bot, прокрутіть униз до Privileged Gateway Intents і ввімкніть:
- Message Content Intent (обов'язково)
- Server Members Intent (рекомендовано; обов'язково для allowlist ролей і зіставлення імен з ID)
- Presence Intent (необов'язково; потрібно лише для оновлень присутності)
Copy your bot token
Прокрутіть сторінку Bot назад угору й натисніть Reset Token.
Скопіюйте токен і збережіть його десь. Це ваш Bot Token, і він вам незабаром знадобиться.
Generate an invite URL and add the bot to your server
Натисніть OAuth2 на бічній панелі. Ви згенеруєте URL запрошення з потрібними дозволами, щоб додати бота на свій сервер.
Прокрутіть униз до OAuth2 URL Generator і ввімкніть:
botapplications.commands
Нижче з'явиться розділ Bot Permissions. Увімкніть щонайменше:
General Permissions
- View Channels Text Permissions
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (необов'язково)
Це базовий набір для звичайних текстових каналів. Якщо ви плануєте писати в гілках Discord, зокрема у сценаріях каналів форуму або медіаканалів, які створюють або продовжують гілку, також увімкніть Send Messages in Threads. Скопіюйте згенерований URL внизу, вставте його у браузер, виберіть свій сервер і натисніть Continue, щоб під'єднати. Тепер ви маєте побачити свого бота на сервері Discord.
Enable Developer Mode and collect your IDs
Повернувшись у застосунок Discord, потрібно ввімкнути Developer Mode, щоб можна було копіювати внутрішні ID.
- Натисніть User Settings (значок шестерні поруч з аватаром) → Advanced → увімкніть Developer Mode
- Клацніть правою кнопкою миші значок сервера на бічній панелі → Copy Server ID
- Клацніть правою кнопкою миші власний аватар → Copy User ID
Збережіть ваші Server ID і User ID разом із Bot Token — на наступному кроці ви надішлете всі три до OpenClaw.
Allow DMs from server members
Щоб спарювання працювало, Discord має дозволяти вашому боту надсилати вам особисті повідомлення. Клацніть правою кнопкою миші значок сервера → Privacy Settings → увімкніть Direct Messages.
Це дозволяє учасникам сервера (включно з ботами) надсилати вам особисті повідомлення. Залиште це ввімкненим, якщо хочете використовувати особисті повідомлення Discord з OpenClaw. Якщо ви плануєте використовувати лише канали гільдії, можете вимкнути особисті повідомлення після спарювання.
Set your bot token securely (do not send it in chat)
Токен вашого бота 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" },},},}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, щоб служба могла визначити env SecretRef після перезапуску.
Якщо ваш хост заблокований або обмежений лімітом запитів під час стартового пошуку застосунку Discord, встановіть ID застосунку/клієнта Discord з Developer Portal, щоб запуск міг пропустити цей REST-виклик. Використовуйте channels.discord.applicationId для облікового запису за замовчуванням або channels.discord.accounts.<accountId>.applicationId, коли запускаєте кілька ботів Discord.
Configure OpenClaw and pair
Ask your agent
Поспілкуйтеся зі своїм агентом OpenClaw у будь-якому наявному каналі (наприклад, Telegram) і повідомте його. Якщо Discord є вашим першим каналом, натомість використайте вкладку CLI / config.
"I already set my Discord bot token in config. Please finish Discord setup with User ID
<user_id>and Server ID<server_id>."
CLI / config
Якщо ви віддаєте перевагу файловій конфігурації, встановіть:
{channels: {discord: {enabled: true,token: {source: "env",provider: "default",id: "DISCORD_BOT_TOKEN",},},},}Резервний env для облікового запису за замовчуванням:
DISCORD_BOT_TOKEN=...Для скриптованого або віддаленого налаштування запишіть той самий блок JSON5 за допомогою openclaw config patch --file ./discord.patch.json5 --dry-run, а потім повторно запустіть без --dry-run. Значення token у відкритому тексті підтримуються. Значення SecretRef також підтримуються для channels.discord.token через провайдери env/file/exec. Див. Керування секретами.
Для кількох ботів Discord тримайте токен кожного бота й ID застосунку в його обліковому записі. Верхньорівневий channels.discord.applicationId успадковується обліковими записами, тому встановлюйте його там лише тоді, коли кожен обліковий запис має використовувати той самий ID застосунку.
{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",},},},},}Approve first DM pairing
Зачекайте, доки Gateway запрацює, а потім надішліть особисте повідомлення своєму боту в Discord. Він відповість кодом спарювання.
Ask your agent
Надішліть код спарювання своєму агенту в наявному каналі:
"Approve this Discord pairing code:
<CODE>"
CLI
openclaw pairing list discordopenclaw pairing approve discord <CODE>Коди спарювання спливають через 1 годину.
Тепер ви маєте змогу спілкуватися зі своїм агентом у Discord через особисті повідомлення.
Рекомендовано: налаштуйте робочий простір гільдії
Коли особисті повідомлення запрацюють, ви можете налаштувати свій сервер Discord як повний робочий простір, де кожен канал отримує власну сесію агента з власним контекстом. Це рекомендовано для приватних серверів, де є лише ви та ваш бот.
Add your server to the guild allowlist
Це дає вашому агенту змогу відповідати в будь-якому каналі на вашому сервері, а не лише в особистих повідомленнях.
Ask your agent
"Add my Discord Server ID
<server_id>to the guild allowlist"
Config
{channels: {discord: {groupPolicy: "allowlist",guilds: {YOUR_SERVER_ID: { requireMention: true, users: ["YOUR_USER_ID"],},},},},}Allow responses without @mention
За замовчуванням ваш агент відповідає в каналах гільдії лише коли його згадують через @mention. Для приватного сервера ви, ймовірно, хочете, щоб він відповідав на кожне повідомлення.
У каналах гільдії звичайні фінальні відповіді асистента за замовчуванням залишаються приватними. Видимий вивід Discord потрібно надсилати явно за допомогою інструмента message, тож агент може за замовчуванням лишатися непомітним і публікувати лише тоді, коли вирішить, що відповідь у канал корисна.
Це означає, що вибрана модель має надійно викликати інструменти. Якщо Discord показує індикатор набору, а журнали показують використання токенів, але повідомлення не опубліковано, перевірте журнал сесії на наявність тексту асистента з didSendViaMessagingTool: false. Це означає, що модель створила приватну фінальну відповідь замість виклику message(action=send). Перейдіть на сильнішу модель для виклику інструментів або використайте конфігурацію нижче, щоб відновити застарілі автоматичні фінальні відповіді.
Ask your agent
"Allow my agent to respond on this server without having to be @mentioned"
Config
Встановіть requireMention: false у конфігурації вашої гільдії:
{channels: {discord: {guilds: {YOUR_SERVER_ID: { requireMention: false,},},},},}Щоб відновити застарілі автоматичні фінальні відповіді для кімнат групових чатів/каналів, встановіть messages.groupChat.visibleReplies: "automatic".
Plan for memory in guild channels
За замовчуванням довгострокова пам'ять (MEMORY.md) завантажується лише в сесіях особистих повідомлень. Канали гільдії не завантажують MEMORY.md автоматично.
Ask your agent
"When I ask questions in Discord channels, use memory_search or memory_get if you need long-term context from MEMORY.md."
Manual
Якщо вам потрібен спільний контекст у кожному каналі, помістіть стабільні інструкції в AGENTS.md або USER.md (вони інжектуються в кожну сесію). Тримайте довгострокові нотатки в MEMORY.md і звертайтеся до них за потреби за допомогою інструментів пам'яті.
Тепер створіть кілька каналів на своєму сервері Discord і почніть спілкуватися. Ваш агент може бачити назву каналу, і кожен канал отримує власну ізольовану сесію — тож ви можете налаштувати #coding, #home, #research або будь-що, що підходить вашому робочому процесу.
Модель виконання
- 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 використовує фінальну видиму асистенту відповідь один раз. Медіа та структуровані payload компонентів залишаються багатоповідомними, коли агент створює кілька deliverable payloads.
Форумні канали
Форумні та медіаканали 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 для повідомлень агента. Використовуйте інструмент повідомлень із payload components. Результати взаємодій маршрутизуються назад до агента як звичайні вхідні повідомлення й дотримуються наявних налаштувань Discord replyToMode.
Підтримувані блоки:
text,section,separator,actions,media-gallery,file- Рядки дій дозволяють до 5 кнопок або одне меню вибору
- Типи вибору:
string,user,role,mentionable,channel
За замовчуванням компоненти одноразові. Установіть components.reusable=true, щоб дозволити використовувати кнопки, меню вибору та форми кілька разів до завершення їхнього терміну дії.
Щоб обмежити, хто може натиснути кнопку, установіть allowedUsers для цієї кнопки (ID користувачів Discord, теги або *). Коли це налаштовано, користувачі без збігу отримують ефемерну відмову.
Slash-команди /model і /models відкривають інтерактивний вибір моделі з розкривними списками провайдера, моделі та сумісного runtime, а також кроком Submit. /models add застаріла й тепер повертає повідомлення про застарілість замість реєстрації моделей із чату. Відповідь вибору ефемерна, і використовувати її може лише користувач, який її викликав. Меню вибору Discord обмежені 25 варіантами, тому додавайте записи provider/* до agents.defaults.models, коли потрібно, щоб вибір показував динамічно виявлені моделі лише для вибраних провайдерів, таких як openai-codex або 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" }, ], }, ], }, },}Контроль доступу та маршрутизація
Політика DM
channels.discord.dmPolicy керує доступом до DM. channels.discord.allowFrom є канонічним allowlist DM.
pairing(за замовчуванням)allowlistopen(потребує, щоб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 користувачів для сумісності.
Групи доступу
Авторизація Discord DM і текстових команд може використовувати динамічні записи accessGroup:<name> у channels.discord.allowFrom.
Імена груп доступу спільні для каналів повідомлень. Використовуйте type: "message.senders" для статичної групи, учасники якої виражені звичайним для кожного каналу синтаксисом allowFrom, або type: "discord.channelAudience", коли поточна аудиторія Discord-каналу ViewChannel має динамічно визначати членство. Спільну поведінку груп доступу задокументовано тут: Групи доступу.
{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" моделює членство так: відправник DM є учасником налаштованої гільдії та наразі має ефективний дозвіл ViewChannel для налаштованого каналу після застосування ролей і перевизначень каналу.
Приклад: дозволити будь-кому, хто бачить #maintainers, надсилати DM боту, залишаючи DM закритими для всіх інших.
{accessGroups: {maintainers: { type: "discord.channelAudience", guildId: "1456350064065904867", channelId: "1456744319972282449", membership: "canViewChannel",},},channels: {discord: { dmPolicy: "allowlist", allowFrom: ["accessGroup:maintainers"],},},}Ви можете змішувати динамічні та статичні записи:
{accessGroups: {maintainers: { type: "discord.channelAudience", guildId: "1456350064065904867", channelId: "1456744319972282449",},},channels: {discord: { dmPolicy: "allowlist", allowFrom: ["accessGroup:maintainers", "discord:123456789012345678"],},},}Пошуки завершуються закрито. Якщо Discord повертає Missing Access, пошук учасника завершується невдало або канал належить іншій гільдії, відправник DM вважається неавторизованим.
Увімкніть Server Members Intent у Discord Developer Portal для бота, коли використовуєте групи доступу за аудиторією каналу. DM не містять стану учасника гільдії, тому OpenClaw визначає учасника через Discord REST під час авторизації.
Політика гільдії
Обробка гільдій керується channels.discord.groupPolicy:
openallowlistdisabled
Безпечний базовий рівень, коли існує channels.discord, — allowlist.
Поведінка allowlist:
- гільдія має збігатися з
channels.discord.guilds(idбажаний, slug приймається) - необов’язкові allowlist відправників:
users(рекомендовано стабільні ID) іroles(лише ID ролей); якщо налаштовано будь-який із них, відправники дозволені, коли вони збігаються зusersАБОroles - прямий збіг імен/тегів за замовчуванням вимкнено; вмикайте
channels.discord.dangerouslyAllowNameMatching: trueлише як аварійний режим сумісності - імена/теги підтримуються для
users, але ID безпечніші;openclaw security auditпопереджає, коли використовуються записи імен/тегів - якщо гільдія має налаштовані
channels, канали не зі списку відхиляються - якщо гільдія не має блоку
channels, дозволені всі канали в цій гільдії з allowlist
Приклад:
{channels: {discord: { groupPolicy: "allowlist", guilds: { "123456789012345678": { requireMention: true, ignoreOtherMentions: true, users: ["987654321098765432"], roles: ["123456789012345678"], channels: { general: { allow: true }, help: { allow: true, requireMention: true }, }, }, },},},}Якщо ви встановили лише DISCORD_BOT_TOKEN і не створили блок channels.discord, runtime fallback — groupPolicy="allowlist" (із попередженням у логах), навіть якщо channels.defaults.groupPolicy дорівнює open.
Згадки та групові DM
Повідомлення гільдії за замовчуванням обмежуються згадками.
Виявлення згадок охоплює:
- явну згадку бота
- налаштовані шаблони згадок (
agents.list[].groupChat.mentionPatterns, fallbackmessages.groupChat.mentionPatterns) - неявну поведінку reply-to-bot у підтримуваних випадках
Під час написання вихідних повідомлень Discord використовуйте канонічний синтаксис згадок: <@USER_ID> для користувачів, <#CHANNEL_ID> для каналів і <@&ROLE_ID> для ролей. Не використовуйте застарілу форму згадки псевдоніма <@!USER_ID>.
requireMention налаштовується для кожної гільдії/каналу (channels.discord.guilds...).
ignoreOtherMentions необов’язково відкидає повідомлення, що згадують іншого користувача/роль, але не бота (за винятком @everyone/@here).
Групові DM:
- за замовчуванням: ігноруються (
dm.groupEnabled=false) - необов’язковий allowlist через
dm.groupChannels(ID каналів або slugs)
Маршрутизація агентів на основі ролей
Використовуйте 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пропускає реєстрацію slash-команд Discord і очищення під час запуску. Раніше зареєстровані команди можуть залишатися видимими в Discord, доки ви не видалите їх із застосунку Discord.- Авторизація нативних команд використовує ті самі списки дозволених користувачів і політики Discord, що й звичайна обробка повідомлень.
- Команди все ще можуть бути видимими в UI Discord для користувачів без авторизації; виконання все одно застосовує авторизацію OpenClaw і повертає "not authorized".
Див. Slash-команди для каталогу команд і поведінки.
Типові налаштування slash-команд:
ephemeral: true
Деталі функцій
Теги відповіді та нативні відповіді
Discord підтримує теги відповіді у виводі агента:
[[reply_to_current]][[reply_to:<id>]]
Керується через channels.discord.replyToMode:
off(типово)firstallbatched
Примітка: off вимикає неявне створення гілок відповідей. Явні теги [[reply_to_*]] усе ще враховуються.
first завжди додає неявне нативне посилання відповіді до першого вихідного повідомлення Discord для цього ходу.
batched додає неявне нативне посилання відповіді Discord лише тоді, коли
вхідний хід був debounce-пакетом із кількох повідомлень. Це корисно,
коли ви хочете нативні відповіді переважно для неоднозначних швидких чатів, а не для кожного
ходу з одним повідомленням.
ID повідомлень показуються в контексті/історії, щоб агенти могли націлюватися на конкретні повідомлення.
Попередній перегляд live stream
OpenClaw може транслювати чернетки відповідей, надсилаючи тимчасове повідомлення й редагуючи його в міру надходження тексту. channels.discord.streaming приймає off | partial | block | progress (типово). progress зберігає одну редаговану чернетку статусу й оновлює її прогресом інструментів до остаточної доставки; спільна початкова мітка є рухомим рядком, тому вона прокручується вгору, як і решта, коли з’являється достатньо роботи. streamMode — застарілий runtime-псевдонім. Запустіть openclaw doctor --fix, щоб переписати збережену конфігурацію на канонічний ключ.
Установіть channels.discord.streaming.mode у off, щоб вимкнути редагування попереднього перегляду Discord. Якщо block streaming Discord явно ввімкнено, OpenClaw пропускає потік попереднього перегляду, щоб уникнути подвійного streaming.
{channels: {discord: { streaming: { mode: "progress", progress: { label: "auto", maxLines: 8, toolProgress: true, }, },},},}partialредагує одне повідомлення попереднього перегляду в міру надходження токенів.blockвидає фрагменти розміру чернетки (використовуйтеdraftChunk, щоб налаштувати розмір і точки розриву, з обмеженням доtextChunkLimit).- Фінальні повідомлення з медіа, помилкою або явною відповіддю скасовують очікувані редагування попереднього перегляду.
streaming.preview.toolProgress(типовоtrue) керує тим, чи оновлення інструментів/прогресу повторно використовують повідомлення попереднього перегляду.- Рядки інструментів/прогресу відображаються як компактні emoji + заголовок + деталі, коли доступно, наприклад
🛠️ Bash: run testsабо🔎 Web Search: for "query". streaming.preview.commandText/streaming.progress.commandTextкерує деталями команди/виконання в компактних рядках прогресу:raw(типово) абоstatus(лише мітка інструмента).
Приховати необроблений текст команди/виконання, зберігаючи компактні рядки прогресу:
{ "channels": { "discord": { "streaming": { "mode": "progress", "progress": { "toolProgress": true, "commandText": "status" } } } }}Streaming попереднього перегляду працює лише з текстом; відповіді з медіа повертаються до звичайної доставки. Коли block streaming явно ввімкнено, OpenClaw пропускає потік попереднього перегляду, щоб уникнути подвійного streaming.
Історія, контекст і поведінка гілок
Контекст історії guild:
channels.discord.historyLimitтипово20- fallback:
messages.groupChat.historyLimit 0вимикає
Елементи керування історією DM:
channels.discord.dmHistoryLimitchannels.discord.dms["<user_id>"].historyLimit
Поведінка гілок:
- Гілки Discord маршрутизуються як сеанси каналу й успадковують конфігурацію батьківського каналу, якщо її не перевизначено.
- Сеанси гілок успадковують вибір
/modelрівня сеансу батьківського каналу як fallback лише для моделі; локальні для гілки вибори/modelусе ще мають пріоритет, а історія транскрипту батьківського каналу не копіюється, якщо успадкування транскрипту не ввімкнено. channels.discord.thread.inheritParent(типовоfalse) вмикає для нових автоматичних гілок початкове заповнення з батьківського транскрипту. Перевизначення для окремого акаунта розміщені вchannels.discord.accounts.<id>.thread.inheritParent.- Реакції інструмента повідомлень можуть розв’язувати DM-цілі
user:<id>. guilds.<guild>.channels.<channel>.requireMention: falseзберігається під час fallback активації на етапі відповіді.
Теми каналів додаються як ненадійний контекст. Списки дозволених користувачів обмежують, хто може запускати агента, але не є повною межею редагування додаткового контексту.
Сеанси, прив’язані до гілки, для субагентів
Discord може прив’язати гілку до цілі сеансу, щоб подальші повідомлення в цій гілці продовжували маршрутизуватися до того самого сеансу (включно із сеансами субагентів).
Команди:
/focus <target>прив’язати поточну/нову гілку до цілі субагента/сеансу/unfocusвидалити прив’язку поточної гілки/agentsпоказати активні запуски та стан прив’язки/session idle <duration|off>переглянути/оновити автоматичний unfocus через неактивність для сфокусованих прив’язок/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 Agents і Довідник конфігурації.
Постійні прив’язки каналів ACP
Для стабільних "always-on" робочих просторів 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 Agents для деталей поведінки прив’язки.
Сповіщення про реакції
Режим сповіщень про реакції для окремого guild:
offown(типово)allallowlist(використовуєguilds.<id>.users)
Події реакцій перетворюються на системні події та додаються до маршрутизованого сеансу Discord.
Ack-реакції
ackReaction надсилає emoji підтвердження, поки OpenClaw обробляє вхідне повідомлення.
Порядок розв’язання:
channels.discord.accounts.<accountId>.ackReactionchannels.discord.ackReactionmessages.ackReaction- fallback до emoji ідентичності агента (
agents.list[].identity.emoji, інакше "👀")
Примітки:
- Discord приймає unicode emoji або назви користувацьких emoji.
- Використовуйте
"", щоб вимкнути реакцію для каналу або акаунта.
Записи конфігурації
Записи конфігурації, ініційовані каналом, увімкнено за замовчуванням.
Це впливає на потоки /config set|unset (коли функції команд увімкнено).
Вимкнути:
{channels: {discord: { configWrites: false,},},}Проксі Gateway
Маршрутизуйте 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
Увімкніть розв’язання 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,},},}Приклад streaming:
{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: справний => online, погіршений або невідомий => idle, вичерпаний або недоступний => dnd. Необов'язкові перевизначення тексту:
autoPresence.healthyTextautoPresence.degradedTextautoPresence.exhaustedText(підтримує заповнювач{reason})
Підтвердження в Discord
Discord підтримує обробку підтверджень на основі кнопок у DM і може додатково публікувати запити підтвердження у вихідному каналі.
Шлях конфігурації:
channels.discord.execApprovals.enabledchannels.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 DM, коли власник, що викликає команду, має маршрут власника Discord; якщо він недоступний, використовується перший доступний маршрут власника з commands.ownerAllowFrom, наприклад Telegram.
Коли target має значення channel або both, запит підтвердження видимий у каналі. Лише визначені затверджувачі можуть використовувати кнопки; інші користувачі отримують ефемерну відмову. Запити підтвердження містять текст команди, тому вмикайте доставку в канал лише в довірених каналах. Якщо ID каналу неможливо отримати з ключа сесії, OpenClaw повертається до доставки через DM.
Discord також відтворює спільні кнопки підтвердження, які використовують інші чат-канали. Нативний адаптер Discord переважно додає маршрутизацію DM для затверджувачів і розсилання в канали.
Коли ці кнопки присутні, вони є основним UX підтвердження; OpenClaw
має додавати ручну команду /approve лише тоді, коли результат інструмента каже,
що чат-підтвердження недоступні або ручне підтвердження є єдиним шляхом.
Якщо нативний runtime підтверджень Discord не активний, OpenClaw залишає
локальний детермінований запит /approve <id> <decision> видимим. Якщо
runtime активний, але нативну картку неможливо доставити до жодної цілі,
OpenClaw надсилає резервне повідомлення в той самий чат із точною командою /approve
з очікуваного підтвердження.
Автентифікація Gateway і розв'язання підтверджень відповідають спільному контракту клієнта Gateway (plugin: ID розв'язуються через plugin.approval.resolve; інші ID через 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 | вимкнено |
UI компонентів v2
OpenClaw використовує компоненти Discord v2 для підтверджень виконання та міжконтекстних маркерів. Дії з повідомленнями Discord також можуть приймати components для власного UI (розширений режим; потребує побудови payload компонента через інструмент discord), тоді як застарілі embeds залишаються доступними, але не рекомендовані.
channels.discord.ui.components.accentColorзадає колір акценту, який використовують контейнери компонентів Discord (hex).- Установлюється для кожного облікового запису через
channels.discord.accounts.<id>.ui.components.accentColor. embedsігноруються, коли присутні компоненти v2.
Приклад:
{ channels: { discord: { ui: { components: { accentColor: "#5865F2", }, }, }, },}Голос
Discord має дві окремі голосові поверхні: realtime голосові канали (безперервні розмови) і вкладення голосових повідомлень (формат попереднього перегляду waveform). Gateway підтримує обидві.
Голосові канали
Контрольний список налаштування:
- Увімкніть Message Content Intent у Discord Developer Portal.
- Увімкніть Server Members Intent, коли використовуються allowlist ролей/користувачів.
- Запросіть бота зі scopes
botіapplications.commands. - Надайте Connect, Speak, Send Messages і Read Message History у цільовому голосовому каналі.
- Увімкніть нативні команди (
commands.nativeабоchannels.discord.commands.native). - Налаштуйте
channels.discord.voice.
Використовуйте /vc join|leave|status, щоб керувати сесіями. Команда використовує типового агента облікового запису та дотримується тих самих правил allowlist і групової політики, що й інші команди 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-codex/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", voice: "cedar", }, }, }, },}Примітки:
voice.ttsперевизначаєmessages.ttsлише для голосового відтворенняstt-tts. Режими реального часу використовуютьvoice.realtime.voice.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.agent-proxyмаршрутизує мовлення черезdiscord-voice, що зберігає звичайну авторизацію власника/інструментів для мовця й цільової сесії, але приховує інструмент агентаtts, оскільки Discord voice відповідає за відтворення. Типовоagent-proxyнадає консультації повний доступ до інструментів, еквівалентний власнику, для мовців-власників (voice.realtime.toolPolicy: "owner") і наполегливо віддає перевагу консультації з агентом OpenClaw перед змістовними відповідями (voice.realtime.consultPolicy: "always"). У цьому типовому режиміalwaysшар реального часу не промовляє автоматично заповнювальні фрази перед відповіддю консультації; він захоплює та транскрибує мовлення, а потім озвучує маршрутизовану відповідь OpenClaw. Якщо кілька примусових відповідей консультації завершуються, поки Discord ще відтворює першу відповідь, пізніші відповіді з точним мовленням ставляться в чергу, доки відтворення не стане неактивним, замість замінювати мовлення посеред речення.- У режимі
stt-ttsSTT використовуєtools.media.audio;voice.modelне впливає на транскрипцію. - У режимах реального часу
voice.realtime.provider,voice.realtime.modelіvoice.realtime.voiceналаштовують аудіосесію реального часу. Для OpenAI Realtime 2 плюс мозку Codex використовуйтеvoice.realtime.model: "gpt-realtime-2"іvoice.model: "openai-codex/gpt-5.5". - Провайдер OpenAI Realtime приймає поточні назви подій Realtime 2 і застарілі сумісні з Codex псевдоніми для подій вихідного аудіо та транскриптів, тому сумісні знімки провайдера можуть змінюватися без втрати аудіо асистента.
voice.realtime.bargeInкерує тим, чи події початку мовлення в Discord переривають активне відтворення реального часу. Якщо не задано, це значення наслідує налаштування переривання вхідного аудіо провайдера реального часу.voice.realtime.minBargeInAudioEndMsкерує мінімальною тривалістю відтворення асистента перед тим, як barge-in OpenAI Realtime обрізає аудіо. Типово:250. Установіть0для негайного переривання в кімнатах із низьким рівнем відлуння або збільште значення для конфігурацій із динаміками та сильним відлунням.- Для голосу OpenAI під час відтворення в Discord установіть
voice.tts.provider: "openai"і виберіть голос Text-to-speech уvoice.tts.openai.voiceабоvoice.tts.providers.openai.voice.cedar— вдалий вибір із чоловічим звучанням у поточній моделі OpenAI TTS. - Перевизначення
systemPromptдля окремих каналів Discord застосовуються до реплік голосового транскрипту для цього голосового каналу. - Репліки голосового транскрипту визначають статус власника з Discord
allowFrom(абоdm.allowFrom); мовці, які не є власниками, не можуть отримувати доступ до інструментів лише для власників (наприклад,gatewayіcron). - Голос Discord є opt-in для конфігурацій лише з текстом; установіть
channels.discord.voice.enabled=true(або збережіть наявний блокchannels.discord.voice), щоб увімкнути команди/vc, голосове середовище виконання та Gateway intentGuildVoiceStates. channels.discord.intents.voiceStatesможе явно перевизначити підписку на voice-state intent. Залиште це значення незаданим, щоб intent відповідав ефективному ввімкненню голосу.- Якщо
voice.autoJoinмає кілька записів для тієї самої гільдії, OpenClaw приєднується до останнього налаштованого каналу для цієї гільдії. voice.allowedChannels— необов’язковий allowlist резидентності. Залиште це значення незаданим, щоб дозволити/vc joinу будь-який авторизований голосовий канал Discord. Якщо задано,/vc join, auto-join під час запуску та переміщення голосового стану бота обмежуються переліченими записами{ guildId, channelId }. Установіть порожній масив, щоб заборонити всі голосові приєднання Discord. Якщо Discord перемістить бота за межі allowlist, OpenClaw залишить цей канал і повторно приєднається до налаштованої цілі auto-join, коли вона доступна.voice.daveEncryptionіvoice.decryptionFailureToleranceпередаються напряму до параметрів приєднання@discordjs/voice.- Типові значення
@discordjs/voice—daveEncryption=trueіdecryptionFailureTolerance=24, якщо їх не задано. - OpenClaw типово використовує чистий JS-декодер
opusscriptдля приймання голосу Discord. Необов’язковий нативний пакет@discordjs/opusігнорується політикою встановлення pnpm у репозиторії, щоб звичайні встановлення, Docker-лінії та непов’язані тести не компілювали нативний addon. Виділені хости для голосової продуктивності можуть opt-in черезOPENCLAW_DISCORD_OPUS_DECODER=nativeпісля встановлення нативного addon. voice.connectTimeoutMsкерує початковим очікуванням Ready@discordjs/voiceдля спроб/vc joinі auto-join. Типово:30000.voice.reconnectGraceMsкерує тим, як довго OpenClaw чекає, доки від’єднана голосова сесія почне повторне підключення, перш ніж знищити її. Типово:15000.- У режимі
stt-ttsголосове відтворення не зупиняється лише через те, що інший користувач починає говорити. Щоб уникнути циклів зворотного зв’язку, OpenClaw ігнорує нове захоплення голосу, поки TTS відтворюється; говоріть після завершення відтворення для наступної репліки. Режими реального часу передають початок мовлення як сигнали barge-in провайдеру реального часу. - У режимах реального часу відлуння від динаміків у відкритий мікрофон може виглядати як barge-in і переривати відтворення. Для кімнат Discord із сильним відлунням установіть
voice.realtime.providers.openai.interruptResponseOnInputAudio: false, щоб OpenAI не переривався автоматично на вхідному аудіо. Додайтеvoice.realtime.bargeIn: true, якщо ви все ще хочете, щоб події початку мовлення Discord переривали активне відтворення. Міст OpenAI Realtime ігнорує обрізання відтворення, коротші заvoice.realtime.minBargeInAudioEndMs, як імовірне відлуння/шум і логує їх як пропущені замість очищення відтворення Discord. voice.captureSilenceGraceMsкерує тим, як довго OpenClaw чекає після того, як Discord повідомляє, що мовець зупинився, перш ніж фіналізувати цей аудіосегмент для STT. Типово:2500; збільште це значення, якщо Discord розбиває звичайні паузи на уривчасті часткові транскрипти.- Коли вибраним провайдером TTS є ElevenLabs, голосове відтворення Discord використовує потоковий TTS і починається з потоку відповіді провайдера. Провайдери без підтримки потокового передавання повертаються до шляху синтезованого тимчасового файла.
- OpenClaw також відстежує помилки розшифрування приймання й автоматично відновлюється, виходячи з голосового каналу та повторно приєднуючись до нього після повторних помилок у короткому вікні.
- Якщо журнали приймання повторно показують
DecryptionFailed(UnencryptedWhenPassthroughDisabled)після оновлення, зберіть звіт про залежності та журнали. Вбудована лінія@discordjs/voiceмістить upstream-виправлення padding з PR discord.js #11449, яке закрило issue discord.js #11419. - Події приймання
The operation was abortedочікувані, коли OpenClaw фіналізує захоплений сегмент мовця; це докладні діагностичні повідомлення, а не попередження. - Докладні голосові журнали Discord містять обмежений однорядковий попередній перегляд STT-транскрипту для кожного прийнятого сегмента мовця, тож налагодження показує і сторону користувача, і сторону відповіді агента без виведення необмеженого тексту транскрипту.
- У режимі
agent-proxyпримусовий fallback консультації пропускає ймовірно неповні фрагменти транскрипту, наприклад текст, що закінчується на...або кінцевий сполучник на кшталтand, а також очевидні неакційні завершення на кшталт “be right back” або “bye”. Журнали показуютьforced agent consult skipped reason=..., коли це запобігає застарілій відповіді в черзі.
Налаштування нативного opus для source checkout:
pnpm installmise exec node@22 -- pnpm discord:opus:installВикористовуйте Node 22 для Gateway, коли потрібен upstream macOS arm64 prebuilt native addon. Якщо ви використовуєте інше середовище виконання Node, opt-in інсталятору може знадобитися локальний toolchain source-build node-gyp.
Після встановлення нативного addon запустіть Gateway з:
OPENCLAW_DISCORD_OPUS_DECODER=native pnpm gateway:watchДокладні голосові журнали мають показувати discord voice: opus decoder: @discordjs/opus. Без env opt-in або якщо нативний addon відсутній чи не може завантажитися на хості, OpenClaw логує discord voice: opus decoder: opusscript і продовжує приймати голос через чистий JS fallback.
Конвеєр STT плюс TTS:
- Захоплення Discord PCM перетворюється на тимчасовий WAV-файл.
tools.media.audioобробляє STT, наприкладopenai/gpt-4o-mini-transcribe.- Транскрипт надсилається через ingress і маршрутизацію Discord, тоді як response LLM працює з політикою голосового виводу, яка приховує інструмент агента
ttsі просить повернутий текст, оскільки Discord voice відповідає за фінальне відтворення TTS. voice.model, якщо задано, перевизначає лише response LLM для цієї репліки голосового каналу.voice.ttsоб’єднується поверхmessages.tts; провайдери з підтримкою потокового передавання подають дані безпосередньо в програвач, інакше отриманий аудіофайл відтворюється в приєднаному каналі.
Приклад типової сесії голосового каналу agent-proxy:
{ channels: { discord: { voice: { enabled: true, model: "openai-codex/gpt-5.5", realtime: { provider: "openai", model: "gpt-realtime-2", voice: "cedar", }, }, }, },}Без блока voice.agentSession кожен голосовий канал отримує власну маршрутизовану сесію OpenClaw. Наприклад, /vc join channel:234567890123456789 спілкується із сесією для цього голосового каналу Discord. Модель реального часу — це лише голосовий фронтенд; змістовні запити передаються налаштованому агенту OpenClaw. Якщо модель реального часу створює фінальний транскрипт без виклику інструмента консультації, OpenClaw примусово виконує консультацію як fallback, щоб типова поведінка все одно була схожою на розмову з агентом.
Приклад застарілого STT плюс TTS:
{ channels: { discord: { voice: { enabled: true, mode: "stt-tts", model: "openai/gpt-5.4-mini", tts: { provider: "openai", openai: { model: "gpt-4o-mini-tts", voice: "cedar", }, }, }, }, },}Приклад realtime bidi:
{ channels: { discord: { voice: { enabled: true, mode: "bidi", model: "openai-codex/gpt-5.5", realtime: { provider: "openai", model: "gpt-realtime-2", voice: "cedar", toolPolicy: "safe-read-only", consultPolicy: "always", }, }, }, },}Голос як розширення наявної сесії каналу Discord:
{ channels: { discord: { voice: { enabled: true, mode: "agent-proxy", model: "openai-codex/gpt-5.5", agentSession: { mode: "target", target: "channel:123456789012345678", }, realtime: { provider: "openai", model: "gpt-realtime-2", voice: "cedar", }, }, }, },}У режимі agent-proxy бот приєднується до налаштованого голосового каналу, але репліки агента OpenClaw використовують звичайну маршрутизовану сесію та агента цільового каналу. Голосова сесія реального часу озвучує повернутий результат назад у голосовий канал. Агент-супервізор усе ще може використовувати звичайні інструменти повідомлень відповідно до своєї політики інструментів, зокрема надсилати окреме повідомлення Discord, якщо це правильна дія.
Корисні форми цілі:
target: "channel:123456789012345678"маршрутизує через сесію текстового каналу Discord.target: "123456789012345678"обробляється як ціль каналу.target: "dm:123456789012345678"абоtarget: "user:123456789012345678"маршрутизує через цю сесію direct message.
Приклад OpenAI Realtime із сильним відлунням:
{ channels: { discord: { voice: { enabled: true, mode: "bidi", model: "openai-codex/gpt-5.5", realtime: { provider: "openai", model: "gpt-realtime-2", voice: "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
Щоб налагодити обривання аудіо, читайте голосові журнали реального часу як часову шкалу:
realtime audio playback startedозначає, що Discord почав відтворювати аудіо асистента. З цього моменту міст починає рахувати фрагменти виводу асистента, PCM-байти Discord, байти постачальника реального часу та тривалість синтезованого аудіо.realtime speaker turn openedпозначає, що мовець Discord став активним. Якщо відтворення вже активне йbargeInувімкнено, після цього може з’явитисяbarge-in detected source=speaker-start.realtime input audio startedпозначає перший фактичний аудіокадр, отриманий для цієї репліки мовця.outputActive=trueабо ненульовеoutputAudioMsтут означає, що мікрофон надсилає вхідний сигнал, поки відтворення асистента ще активне.barge-in detected source=active-speaker-audioозначає, що OpenClaw побачив живе аудіо мовця, поки відтворення асистента було активним. Це корисно, щоб відрізнити справжнє переривання від події початку мовлення в Discord без корисного аудіо.barge-in requested reason=...означає, що OpenClaw попросив постачальника реального часу скасувати або обрізати активну відповідь. Він міститьoutputAudioMs,outputActiveіplaybackChunks, щоб ви могли побачити, скільки аудіо асистента фактично відтворилося до переривання.realtime audio playback stopped reason=...— це локальна точка скидання відтворення Discord. Причина вказує, хто зупинив відтворення:barge-in,player-idle,provider-clear-audio,forced-agent-consult,stream-closeабоsession-close.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.
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і шаблони згадок
Корисні перевірки:
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 зберігають порядок у межах сесії, доки життєвий цикл сесії, інструмента або середовища виконання не завершить або не перерве роботу.
{channels: {discord: { accounts: { default: { eventQueue: { listenerTimeout: 120000, }, }, },},},}Попередження про тайм-аут пошуку метаданих Gateway
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
Перезапуски через тайм-аут READY Gateway
OpenClaw очікує подію Gateway Discord READY під час запуску та після повторних підключень середовища виконання. Налаштування з кількома обліковими записами й поетапним запуском можуть потребувати довшого стартового вікна 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 працюють лише для числових ідентифікаторів каналів.
Якщо ви використовуєте ключі-слаги, зіставлення під час виконання все одно може працювати, але проба не може повністю перевірити дозволи.
Проблеми з DM і сполученням
- DM вимкнено:
channels.discord.dm.enabled=false - політику DM вимкнено:
channels.discord.dmPolicy="disabled"(застаріле:channels.discord.dm.policy) - очікується схвалення сполучення в режимі
pairing
Цикли бот-бот
За замовчуванням повідомлення, створені ботами, ігноруються.
If you set channels.discord.allowBots=true, use strict mention and allowlist rules to avoid loop behavior.
Prefer channels.discord.allowBots="mentions" to only accept bot messages that mention the bot.
{channels: {discord: { 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 "@Mantis" and send a real Discord mention. Mantis: "MANTIS_DISCORD_USER_ID", }, }, },},},}Voice STT drops with DecryptionFailed(...)
- keep OpenClaw current (
openclaw update) so the Discord voice receive recovery logic is present - confirm
channels.discord.voice.daveEncryption=true(default) - start from
channels.discord.voice.decryptionFailureTolerance=24(upstream default) and tune only if needed - watch logs for:
discord voice: DAVE decrypt failures detecteddiscord voice: repeated decrypt failures; attempting rejoin
- if failures continue after automatic rejoin, collect logs and compare against the upstream DAVE receive history in discord.js #11419 and discord.js #11449
Configuration reference
Primary reference: Configuration reference - Discord.
High-signal Discord fields
- startup/auth:
enabled,token,accounts.*,allowBots - policy:
groupPolicy,dm.*,guilds.*,guilds.*.channels.* - command:
commands.native,commands.useAccessGroups,configWrites,slashCommand.* - event queue:
eventQueue.listenerTimeout(listener budget),eventQueue.maxQueueSize,eventQueue.maxConcurrency - gateway:
gatewayInfoTimeoutMs,gatewayReadyTimeoutMs,gatewayRuntimeReadyTimeoutMs - reply/history:
replyToMode,historyLimit,dmHistoryLimit,dms.*.historyLimit - delivery:
textChunkLimit,chunkMode,maxLinesPerMessage - streaming:
streaming(legacy alias:streamMode),streaming.preview.toolProgress,draftChunk,blockStreaming,blockStreamingCoalesce - media/retry:
mediaMaxMb(caps outbound Discord uploads, default100MB),retry - actions:
actions.* - presence:
activity,status,activityType,activityUrl - UI:
ui.components.accentColor - features:
threadBindings, top-levelbindings[](type: "acp"),pluralkit,execApprovals,intents,agentComponents,heartbeat,responsePrefix
Safety and operations
- Treat bot tokens as secrets (
DISCORD_BOT_TOKENpreferred in supervised environments). - Grant least-privilege Discord permissions.
- If command deploy/state is stale, restart gateway and re-check with
openclaw channels status --probe.