Discord (Bot API)
Статус: готов для личных сообщений и текстовых каналов гильдий через официальный Discord bot gateway.
Быстрая настройка (для начинающих)
- Создайте Discord бота и скопируйте токен бота.
- В настройках приложения Discord включите Message Content Intent (и Server Members Intent, если планируете использовать белые списки или поиск по именам).
- Установите токен для OpenClaw:
- Env: DISCORD_BOT_TOKEN=...
- Или config: channels.discord.token: "...".
- Если установлены оба, приоритет имеет config (env fallback только для аккаунта по умолчанию).
- Пригласите бота на ваш сервер с правами на сообщения (создайте приватный сервер, если хотите только личные сообщения).
- Запустите gateway.
- Доступ к личным сообщениям по умолчанию требует сопряжения; утвердите код сопряжения при первом контакте.
Минимальная конфигурация:
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN"
}
}
}
Цели
- Общайтесь с OpenClaw через личные сообщения Discord или каналы гильдий.
- Прямые чаты объединяются в основную сессию агента (по умолчанию agent:main:main); каналы гильдий остаются изолированными как agent:<agentId>:discord:channel:<channelId> (отображаемые имена используют discord:<guildSlug>#<channelSlug>).
- Групповые личные сообщения игнорируются по умолчанию; включите через channels.discord.dm.groupEnabled и опционально ограничьте через channels.discord.dm.groupChannels.
- Сохраняйте маршрутизацию детерминированной: ответы всегда возвращаются в канал, откуда они пришли.
Как это работает
- Создайте приложение Discord → Bot, включите необходимые intents (личные сообщения + сообщения гильдий + содержимое сообщений) и получите токен бота.
- Пригласите бота на ваш сервер с правами, необходимыми для чтения/отправки сообщений там, где вы хотите его использовать.
- Настройте OpenClaw с channels.discord.token (или DISCORD_BOT_TOKEN в качестве fallback).
- Запустите gateway; он автоматически запустит канал Discord, когда доступен токен (сначала config, затем env fallback) и channels.discord.enabled не установлен в false.
- Если вы предпочитаете переменные окружения, установите DISCORD_BOT_TOKEN (блок config опционален).
- Прямые чаты: используйте user:<id> (или упоминание <@id>) при доставке; все обращения попадают в общую сессию main. Голые числовые ID неоднозначны и отклоняются.
- Каналы гильдий: используйте channel:<channelId> для доставки. Упоминания требуются по умолчанию и могут быть установлены для каждой гильдии или канала.
- Прямые чаты: безопасны по умолчанию через channels.discord.dm.policy (по умолчанию: "pairing"). Неизвестные отправители получают код сопряжения (истекает через 1 час); утвердите через openclaw pairing approve discord <code>.
- Чтобы сохранить старое поведение "открыто для всех": установите channels.discord.dm.policy="open" и channels.discord.dm.allowFrom=["*"].
- Для жесткого белого списка: установите channels.discord.dm.policy="allowlist" и перечислите отправителей в channels.discord.dm.allowFrom.
- Чтобы игнорировать все личные сообщения: установите channels.discord.dm.enabled=false или channels.discord.dm.policy="disabled".
- Групповые личные сообщения игнорируются по умолчанию; включите через channels.discord.dm.groupEnabled и опционально ограничьте через channels.discord.dm.groupChannels.
- Опциональные правила гильдий: установите channels.discord.guilds с ключами по guild id (предпочтительно) или slug, с правилами для каждого канала.
- Опциональные нативные команды: commands.native по умолчанию "auto" (включено для Discord/Telegram, выключено для Slack). Переопределите с channels.discord.commands.native: true|false|"auto"; false очищает ранее зарегистрированные команды. Текстовые команды контролируются commands.text и должны отправляться как отдельные /... сообщения. Используйте commands.useAccessGroups: false для обхода проверок access-group для команд.
- Полный список команд + конфигурация: Slash-команды
- Опциональная история контекста гильдии: установите channels.discord.historyLimit (по умолчанию 20, fallback на messages.groupChat.historyLimit) для включения последних N сообщений гильдии в качестве контекста при ответе на упоминание. Установите 0 для отключения.
- Реакции: агент может вызывать реакции через инструмент discord (контролируется channels.discord.actions.*).
- Семантика удаления реакций: см. /tools/reactions.
- Инструмент discord доступен только когда текущий канал — Discord.
- Нативные команды используют изолированные ключи сессий (agent:<agentId>:discord:slash:<userId>) вместо общей сессии main.
Примечание: Разрешение имя → id использует поиск участников гильдии и требует Server Members Intent; если бот не может искать участников, используйте id или упоминания <@id>. Примечание: Slugs в нижнем регистре с пробелами, замененными на -. Имена каналов преобразуются в slug без ведущего #. Примечание: Строки контекста гильдии [from:] включают author.tag + id для упрощения ответов с пингом.
Запись конфигурации
По умолчанию Discord разрешено записывать обновления конфигурации, вызванные /config set|unset (требует commands.config: true).
Отключите с помощью:
{
channels: { discord: { configWrites: false } }
}
Как создать своего бота
Это настройка "Discord Developer Portal" для запуска OpenClaw в канале сервера (гильдии) типа #help.
1) Создайте приложение Discord + пользователя бота
- Discord Developer Portal → Applications → New Application
- В вашем приложении:
- Bot → Add Bot
- Скопируйте Bot Token (это то, что вы поместите в DISCORD_BOT_TOKEN)
2) Включите gateway intents, необходимые OpenClaw
Discord блокирует "привилегированные intents", если вы явно их не включите.
В Bot → Privileged Gateway Intents, включите:
- Message Content Intent (требуется для чтения текста сообщений в большинстве гильдий; без него вы увидите "Used disallowed intents" или бот подключится, но не будет реагировать на сообщения)
- Server Members Intent (рекомендуется; требуется для некоторых поисков участников/пользователей и сопоставления белых списков в гильдиях)
Обычно вам не нужен Presence Intent.
3) Сгенерируйте URL приглашения (OAuth2 URL Generator)
В вашем приложении: OAuth2 → URL Generator
Scopes
- ✅ bot
- ✅ applications.commands (требуется для нативных команд)
Bot Permissions (минимальная базовая линия)
- ✅ View Channels
- ✅ Send Messages
- ✅ Read Message History
- ✅ Embed Links
- ✅ Attach Files
- ✅ Add Reactions (опционально, но рекомендуется)
- ✅ Use External Emojis / Stickers (опционально; только если вы их хотите)
Избегайте Administrator, если только не отлаживаете и полностью доверяете боту.
Скопируйте сгенерированный URL, откройте его, выберите ваш сервер и установите бота.
4) Получите id (guild/user/channel)
Discord использует числовые id везде; конфигурация OpenClaw предпочитает id.
- Discord (desktop/web) → User Settings → Advanced → включите Developer Mode
- Правый клик:
- Имя сервера → Copy Server ID (guild id)
- Канал (например, #help) → Copy Channel ID
- Ваш пользователь → Copy User ID
5) Настройте OpenClaw
Токен
Установите токен бота через переменную окружения (рекомендуется на серверах):
- DISCORD_BOT_TOKEN=...
Или через конфигурацию:
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN"
}
}
}
Поддержка нескольких аккаунтов: используйте channels.discord.accounts с токенами для каждого аккаунта и опциональным name. См. gateway/configuration для общего паттерна.
Белый список + маршрутизация каналов
Пример "один сервер, разрешить только меня, разрешить только #help":
{
channels: {
discord: {
enabled: true,
dm: { enabled: false },
guilds: {
"YOUR_GUILD_ID": {
users: ["YOUR_USER_ID"],
requireMention: true,
channels: {
help: { allow: true, requireMention: true }
}
}
},
retry: {
attempts: 3,
minDelayMs: 500,
maxDelayMs: 30000,
jitter: 0.1
}
}
}
}
Примечания:
- requireMention: true означает, что бот отвечает только при упоминании (рекомендуется для общих каналов).
- agents.list[].groupChat.mentionPatterns (или messages.groupChat.mentionPatterns) также считаются упоминаниями для сообщений гильдий.
- Переопределение нескольких агентов: установите паттерны для каждого агента на agents.list[].groupChat.mentionPatterns.
- Если присутствует channels, любой канал, не указанный в списке, по умолчанию запрещен.
- Используйте запись канала "*" для применения значений по умолчанию ко всем каналам; явные записи каналов переопределяют подстановочный знак.
- Треды наследуют конфигурацию родительского канала (белый список, requireMention, skills, prompts и т.д.), если вы не добавите id канала треда явно.
- Сообщения, созданные ботом, игнорируются по умолчанию; установите channels.discord.allowBots=true, чтобы разрешить их (собственные сообщения остаются отфильтрованными).
- Предупреждение: Если вы разрешаете ответы другим ботам (channels.discord.allowBots=true), предотвратите петли ответов бот-бот с помощью requireMention, белых списков channels.discord.guilds.*.channels.<id>.users и/или четких ограждений в AGENTS.md и SOUL.md.
6) Убедитесь, что это работает
- Запустите gateway.
- В канале вашего сервера отправьте: @Krill hello (или как там зовут вашего бота).
- Если ничего не происходит: проверьте Устранение неполадок ниже.
Устранение неполадок
- Сначала: запустите openclaw doctor и openclaw channels status --probe (предупреждения с действиями + быстрые аудиты).
- "Used disallowed intents": включите Message Content Intent (и, вероятно, Server Members Intent) в Developer Portal, затем перезапустите gateway.
- Бот подключается, но никогда не отвечает в канале гильдии:
- Отсутствует Message Content Intent, или
- У бота нет прав на канал (View/Send/Read History), или
- Ваша конфигурация требует упоминаний, а вы не упомянули бота, или
- Ваш белый список гильдии/канала запрещает канал/пользователя.
- requireMention: false, но все равно нет ответов:
- channels.discord.groupPolicy по умолчанию allowlist; установите его в "open" или добавьте запись гильдии в channels.discord.guilds (опционально перечислите каналы в channels.discord.guilds.<id>.channels для ограничения).
- Если вы установили только DISCORD_BOT_TOKEN и никогда не создавали секцию channels.discord, runtime по умолчанию устанавливает groupPolicy в open. Добавьте channels.discord.groupPolicy, channels.defaults.groupPolicy или белый список гильдии/канала для блокировки.
- requireMention должен находиться в channels.discord.guilds (или конкретном канале). channels.discord.requireMention на верхнем уровне игнорируется.
- Аудиты прав (channels status --probe) проверяют только числовые ID каналов. Если вы используете slugs/имена как ключи channels.discord.guilds.*.channels, аудит не может проверить права.
- Личные сообщения не работают: channels.discord.dm.enabled=false, channels.discord.dm.policy="disabled" или вы еще не утверждены (channels.discord.dm.policy="pairing").
Возможности и ограничения
- Личные сообщения и текстовые каналы гильдий (треды обрабатываются как отдельные каналы; голос не поддерживается).
- Индикаторы набора текста отправляются по мере возможности; разбиение сообщений использует channels.discord.textChunkLimit (по умолчанию 2000) и разделяет длинные ответы по количеству строк (channels.discord.maxLinesPerMessage, по умолчанию 17).
- Опциональное разбиение по новым строкам: установите channels.discord.chunkMode="newline" для разделения на пустых строках (границы параграфов) перед разбиением по длине.
- Загрузка файлов поддерживается до настроенного channels.discord.mediaMaxMb (по умолчанию 8 МБ).
- Ответы в гильдиях по умолчанию требуют упоминаний для избежания шумных ботов.
- Контекст ответа внедряется, когда сообщение ссылается на другое сообщение (цитируемое содержимое + id).
- Нативная цепочка ответов выключена по умолчанию; включите с помощью channels.discord.replyToMode и тегов ответов.
Политика повторных попыток
Исходящие вызовы Discord API повторяются при ограничении скорости (429), используя Discord retry_after, когда доступно, с экспоненциальным backoff и jitter. Настройте через channels.discord.retry. См. Политика повторных попыток.
Конфигурация
{
channels: {
discord: {
enabled: true,
token: "abc.123",
groupPolicy: "allowlist",
guilds: {
"*": {
channels: {
general: { allow: true }
}
}
},
mediaMaxMb: 8,
actions: {
reactions: true,
stickers: true,
emojiUploads: true,
stickerUploads: true,
polls: true,
permissions: true,
messages: true,
threads: true,
pins: true,
search: true,
memberInfo: true,
roleInfo: true,
roles: false,
channelInfo: true,
channels: true,
voiceStatus: true,
events: true,
moderation: false
},
replyToMode: "off",
dm: {
enabled: true,
policy: "pairing", // pairing | allowlist | open | disabled
allowFrom: ["123456789012345678", "steipete"],
groupEnabled: false,
groupChannels: ["openclaw-dm"]
},
guilds: {
"*": { requireMention: true },
"123456789012345678": {
slug: "friends-of-openclaw",
requireMention: false,
reactionNotifications: "own",
users: ["987654321098765432", "steipete"],
channels: {
general: { allow: true },
help: {
allow: true,
requireMention: true,
users: ["987654321098765432"],
skills: ["search", "docs"],
systemPrompt: "Keep answers short."
}
}
}
}
}
}
}
Ack-реакции контролируются глобально через messages.ackReaction + messages.ackReactionScope. Используйте messages.removeAckAfterReply для очистки ack-реакции после ответа бота.
- dm.enabled: установите false для игнорирования всех личных сообщений (по умолчанию true).
- dm.policy: контроль доступа к личным сообщениям (pairing рекомендуется). "open" требует dm.allowFrom=["*"].
- dm.allowFrom: белый список личных сообщений (id пользователей или имена). Используется dm.policy="allowlist" и для проверки dm.policy="open". Мастер принимает имена пользователей и разрешает их в id, когда бот может искать участников.
- dm.groupEnabled: включить групповые личные сообщения (по умолчанию false).
- dm.groupChannels: опциональный белый список для id каналов групповых личных сообщений или slugs.
- groupPolicy: контролирует обработку каналов гильдий (open|disabled|allowlist); allowlist требует белые списки каналов.
- guilds: правила для каждой гильдии с ключами по guild id (предпочтительно) или slug.
- guilds."*": настройки по умолчанию для каждой гильдии, применяемые при отсутствии явной записи.
- guilds.<id>.slug: опциональный дружественный slug, используемый для отображаемых имен.
- guilds.<id>.users: опциональный белый список пользователей для каждой гильдии (id или имена).
- guilds.<id>.tools: опциональные переопределения политики инструментов для каждой гильдии (allow/deny/alsoAllow), используемые при отсутствии переопределения канала.
- guilds.<id>.toolsBySender: опциональные переопределения политики инструментов для каждого отправителя на уровне гильдии (применяется при отсутствии переопределения канала; поддерживается подстановочный знак "*").
- guilds.<id>.channels.<channel>.allow: разрешить/запретить канал при groupPolicy="allowlist".
- guilds.<id>.channels.<channel>.requireMention: требование упоминания для канала.
- guilds.<id>.channels.<channel>.tools: опциональные переопределения политики инструментов для каждого канала (allow/deny/alsoAllow).
- guilds.<id>.channels.<channel>.toolsBySender: опциональные переопределения политики инструментов для каждого отправителя внутри канала (поддерживается подстановочный знак "*").
- guilds.<id>.channels.<channel>.users: опциональный белый список пользователей для каждого канала.
- guilds.<id>.channels.<channel>.skills: фильтр skills (пропустить = все skills, пусто = none).
- guilds.<id>.channels.<channel>.systemPrompt: дополнительный системный промпт для канала (объединяется с темой канала).
- guilds.<id>.channels.<channel>.enabled: установите false для отключения канала.
- guilds.<id>.channels: правила каналов (ключи — slugs каналов или id).
- guilds.<id>.requireMention: требование упоминания для каждой гильдии (переопределяемо для каждого канала).
- guilds.<id>.reactionNotifications: режим событий реакций (off, own, all, allowlist).
- textChunkLimit: размер исходящего фрагмента текста (символы). По умолчанию: 2000.
- chunkMode: length (по умолчанию) разбивает только при превышении textChunkLimit; newline разбивает на пустых строках (границы параграфов) перед разбиением по длине.
- maxLinesPerMessage: мягкий макс количество строк на сообщение. По умолчанию: 17.
- mediaMaxMb: ограничить входящие медиа, сохраненные на диск.
- historyLimit: количество последних сообщений гильдии для включения в качестве контекста при ответе на упоминание (по умолчанию 20; fallback на messages.groupChat.historyLimit; 0 отключает).
- dmHistoryLimit: лимит истории личных сообщений в пользовательских обращениях. Переопределения для конкретного пользователя: dms["<user_id>"].historyLimit.
- retry: политика повторных попыток для исходящих вызовов Discord API (attempts, minDelayMs, maxDelayMs, jitter).
- actions: ограничения инструментов для каждого действия; пропустить для разрешения всех (установите false для отключения).
- reactions (покрывает react + read reactions)
- stickers, emojiUploads, stickerUploads, polls, permissions, messages, threads, pins, search
- memberInfo, roleInfo, channelInfo, voiceStatus, events
- channels (создание/редактирование/удаление каналов + категорий + прав)
- roles (добавление/удаление ролей, по умолчанию false)
- moderation (таймаут/кик/бан, по умолчанию false)
Уведомления о реакциях используют guilds.<id>.reactionNotifications:
- off: нет событий реакций.
- own: реакции на собственные сообщения бота (по умолчанию).
- all: все реакции на все сообщения.
- allowlist: реакции от guilds.<id>.users на все сообщения (пустой список отключает).
Действия инструментов по умолчанию
| Группа действий | По умолчанию | Примечания |
|---|---|---|
| reactions | включено | React + list reactions + emojiList |
| stickers | включено | Отправка стикеров |
| emojiUploads | включено | Загрузка эмодзи |
| stickerUploads | включено | Загрузка стикеров |
| polls | включено | Создание опросов |
| permissions | включено | Снимок прав канала |
| messages | включено | Read/send/edit/delete |
| threads | включено | Create/list/reply |
| pins | включено | Pin/unpin/list |
| search | включено | Поиск сообщений (preview feature) |
| memberInfo | включено | Информация об участнике |
| roleInfo | включено | Список ролей |
| channelInfo | включено | Информация о канале + список |
| channels | включено | Управление каналами/категориями |
| voiceStatus | включено | Поиск голосового состояния |
| events | включено | List/create scheduled events |
| roles | отключено | Добавление/удаление ролей |
| moderation | отключено | Таймаут/кик/бан |
- replyToMode: off (по умолчанию), first или all. Применяется только когда модель включает тег ответа.
Теги ответов
Чтобы запросить цепочку ответов, модель может включить один тег в свой вывод:
- [[reply_to_current]] — ответить на вызывающее сообщение Discord.
- [[reply_to:<id>]] — ответить на конкретное сообщение по id из контекста/истории. ID текущих сообщений добавляются к промптам как [message_id: …]; записи истории уже включают id.
Поведение контролируется channels.discord.replyToMode:
- off: игнорировать теги.
- first: только первый исходящий фрагмент/вложение является ответом.
- all: каждый исходящий фрагмент/вложение является ответом.
Примечания по сопоставлению белых списков:
- allowFrom/users/groupChannels принимают id, имена, теги или упоминания типа <@id>.
- Поддерживаются префиксы типа discord:/user: (пользователи) и channel: (групповые личные сообщения).
- Используйте * для разрешения любого отправителя/канала.
- Когда присутствует guilds.<id>.channels, каналы, не указанные в списке, по умолчанию запрещены.
- Когда guilds.<id>.channels отсутствует, разрешены все каналы в гильдии из белого списка.
- Чтобы не разрешить никакие каналы, установите channels.discord.groupPolicy: "disabled" (или сохраните пустой белый список).
- Мастер настройки принимает имена Guild/Channel (публичные + приватные) и разрешает их в ID, когда это возможно.
- При запуске OpenClaw разрешает имена каналов/пользователей в белых списках в ID (когда бот может искать участников) и логирует сопоставление; неразрешенные записи сохраняются как введенные.
Примечания по нативным командам:
- Зарегистрированные команды отражают чат-команды OpenClaw.
- Нативные команды соблюдают те же белые списки, что и личные сообщения/сообщения гильдий (channels.discord.dm.allowFrom, channels.discord.guilds, правила для каждого канала).
- Slash-команды все еще могут быть видны в интерфейсе Discord пользователям, которые не в белом списке; OpenClaw применяет белые списки при выполнении и отвечает "not authorized".
Действия инструментов
Агент может вызывать discord с действиями типа:
- react / reactions (добавить или перечислить реакции)
- sticker, poll, permissions
- readMessages, sendMessage, editMessage, deleteMessage
- Payload инструментов Read/search/pin включают нормализованные timestampMs (UTC epoch ms) и timestampUtc наряду с сырым Discord timestamp.
- threadCreate, threadList, threadReply
- pinMessage, unpinMessage, listPins
- searchMessages, memberInfo, roleInfo, roleAdd, roleRemove, emojiList
- channelInfo, channelList, voiceStatus, eventList, eventCreate
- timeout, kick, ban
ID сообщений Discord передаются во внедренном контексте ([discord message id: …] и строки истории), чтобы агент мог нацеливаться на них. Эмодзи могут быть unicode (например, ✅) или синтаксисом пользовательских эмодзи типа <:party_blob:1234567890>.
Безопасность и операции
- Обращайтесь с токеном бота как с паролем; предпочитайте переменную окружения DISCORD_BOT_TOKEN на контролируемых хостах или блокируйте права на файл конфигурации.
- Предоставляйте боту только необходимые права (обычно Read/Send Messages).
- Если бот застрял или ограничен по скорости, перезапустите gateway (openclaw gateway --force) после подтверждения, что никакие другие процессы не владеют сессией Discord.