Discord (Bot API)

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

Быстрая настройка (для начинающих)

  1. Создайте Discord бота и скопируйте токен бота.
  2. В настройках приложения Discord включите Message Content IntentServer Members Intent, если планируете использовать белые списки или поиск по именам).
  3. Установите токен для OpenClaw:
    • Env: DISCORD_BOT_TOKEN=...
    • Или config: channels.discord.token: "...".
    • Если установлены оба, приоритет имеет config (env fallback только для аккаунта по умолчанию).
  4. Пригласите бота на ваш сервер с правами на сообщения (создайте приватный сервер, если хотите только личные сообщения).
  5. Запустите gateway.
  6. Доступ к личным сообщениям по умолчанию требует сопряжения; утвердите код сопряжения при первом контакте.

Минимальная конфигурация:

{
  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.
  • Сохраняйте маршрутизацию детерминированной: ответы всегда возвращаются в канал, откуда они пришли.

Как это работает

  1. Создайте приложение Discord → Bot, включите необходимые intents (личные сообщения + сообщения гильдий + содержимое сообщений) и получите токен бота.
  2. Пригласите бота на ваш сервер с правами, необходимыми для чтения/отправки сообщений там, где вы хотите его использовать.
  3. Настройте OpenClaw с channels.discord.token (или DISCORD_BOT_TOKEN в качестве fallback).
  4. Запустите gateway; он автоматически запустит канал Discord, когда доступен токен (сначала config, затем env fallback) и channels.discord.enabled не установлен в false.
    • Если вы предпочитаете переменные окружения, установите DISCORD_BOT_TOKEN (блок config опционален).
  5. Прямые чаты: используйте user:<id> (или упоминание <@id>) при доставке; все обращения попадают в общую сессию main. Голые числовые ID неоднозначны и отклоняются.
  6. Каналы гильдий: используйте channel:<channelId> для доставки. Упоминания требуются по умолчанию и могут быть установлены для каждой гильдии или канала.
  7. Прямые чаты: безопасны по умолчанию через 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".
  8. Групповые личные сообщения игнорируются по умолчанию; включите через channels.discord.dm.groupEnabled и опционально ограничьте через channels.discord.dm.groupChannels.
  9. Опциональные правила гильдий: установите channels.discord.guilds с ключами по guild id (предпочтительно) или slug, с правилами для каждого канала.
  10. Опциональные нативные команды: commands.native по умолчанию "auto" (включено для Discord/Telegram, выключено для Slack). Переопределите с channels.discord.commands.native: true|false|"auto"; false очищает ранее зарегистрированные команды. Текстовые команды контролируются commands.text и должны отправляться как отдельные /... сообщения. Используйте commands.useAccessGroups: false для обхода проверок access-group для команд.
  11. Опциональная история контекста гильдии: установите channels.discord.historyLimit (по умолчанию 20, fallback на messages.groupChat.historyLimit) для включения последних N сообщений гильдии в качестве контекста при ответе на упоминание. Установите 0 для отключения.
  12. Реакции: агент может вызывать реакции через инструмент discord (контролируется channels.discord.actions.*).
    • Семантика удаления реакций: см. /tools/reactions.
    • Инструмент discord доступен только когда текущий канал — Discord.
  13. Нативные команды используют изолированные ключи сессий (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 + пользователя бота

  1. Discord Developer Portal → ApplicationsNew Application
  2. В вашем приложении:
    • BotAdd Bot
    • Скопируйте Bot Token (это то, что вы поместите в DISCORD_BOT_TOKEN)

2) Включите gateway intents, необходимые OpenClaw

Discord блокирует "привилегированные intents", если вы явно их не включите.

В BotPrivileged Gateway Intents, включите:

  • Message Content Intent (требуется для чтения текста сообщений в большинстве гильдий; без него вы увидите "Used disallowed intents" или бот подключится, но не будет реагировать на сообщения)
  • Server Members Intent (рекомендуется; требуется для некоторых поисков участников/пользователей и сопоставления белых списков в гильдиях)

Обычно вам не нужен Presence Intent.

3) Сгенерируйте URL приглашения (OAuth2 URL Generator)

В вашем приложении: OAuth2URL 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.

  1. Discord (desktop/web) → User SettingsAdvanced → включите Developer Mode
  2. Правый клик:
    • Имя сервера → 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) Убедитесь, что это работает

  1. Запустите gateway.
  2. В канале вашего сервера отправьте: @Krill hello (или как там зовут вашего бота).
  3. Если ничего не происходит: проверьте Устранение неполадок ниже.

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

  • Сначала: запустите 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.