Гайд по Discord Components V2: кнопки, меню, контейнеры и секции в вебхуках
Полное руководство по Discord Components V2: Container, Section, TextDisplay, MediaGallery, Separator, а также кнопки и select-меню в webhook-сообщениях. Примеры кода и лимиты API.
Что такое Discord Components?
Discord Components — это интерактивные элементы, которые можно добавлять в сообщения: кнопки, выпадающие меню (select), текстовые поля. Они позволяют пользователям взаимодействовать с сообщениями без необходимости писать команды.
Components V2 — это обновлённая версия API, которая добавила:
- Модальные формы (text input modals)
- Улучшенные select-меню с поддержкой пользователей, ролей, каналов
- Более гибкие кнопки с эмодзи и стилями
Важно: Webhook могут отправлять сообщения с компонентами, но не могут обрабатывать взаимодействия. Для обработки нажатий нужен полноценный Discord бот с обработчиком
INTERACTION_CREATE.
Типы компонентов
Discord поддерживает следующие типы компонентов:
| Тип | Описание | Использование |
|---|---|---|
| Button | Кликабельная кнопка | Действия, ссылки, подтверждения |
| Select Menu | Выпадающий список | Выбор из нескольких опций |
| Text Input | Текстовое поле | Модальные формы (только в ботах) |
Структура компонентов
Компоненты добавляются в массив components сообщения. Каждый элемент массива — это Action Row (строка действий), которая может содержать до 5 кнопок или 1 select-меню:
{
"content": "Выберите действие:",
"components": [
{
"type": 1,
"components": [
{
"type": 2,
"style": 1,
"label": "Кнопка 1",
"custom_id": "button_1"
}
]
}
]
}
type: 1— Action Row (контейнер для компонентов)type: 2— Buttontype: 3— Select Menu
Кнопки (Buttons)
Кнопки — самый популярный тип компонентов. Они бывают двух видов:
1. Интерактивные кнопки (с custom_id)
Требуют обработки ботом:
{
"content": "Подтвердите действие:",
"components": [
{
"type": 1,
"components": [
{
"type": 2,
"style": 3,
"label": "Подтвердить",
"custom_id": "confirm_action"
},
{
"type": 2,
"style": 4,
"label": "Отменить",
"custom_id": "cancel_action"
}
]
}
]
}
2. Кнопки-ссылки (с url)
Открывают URL в браузере (не требуют бота):
{
"content": "Полезные ссылки:",
"components": [
{
"type": 1,
"components": [
{
"type": 2,
"style": 5,
"label": "Документация",
"url": "https://discord.com/developers/docs"
},
{
"type": 2,
"style": 5,
"label": "GitHub",
"url": "https://github.com"
}
]
}
]
}
Важно: Кнопки-ссылки всегда имеют
style: 5и не имеютcustom_id.
Стили кнопок
Discord поддерживает 5 стилей кнопок:
const buttonStyles = {
PRIMARY: 1, // Синяя (blurple)
SECONDARY: 2, // Серая
SUCCESS: 3, // Зелёная
DANGER: 4, // Красная
LINK: 5 // Серая с иконкой ссылки (только для url)
};
Пример всех стилей:
{
"content": "Все стили кнопок:",
"components": [
{
"type": 1,
"components": [
{
"type": 2,
"style": 1,
"label": "Primary",
"custom_id": "btn_primary"
},
{
"type": 2,
"style": 2,
"label": "Secondary",
"custom_id": "btn_secondary"
},
{
"type": 2,
"style": 3,
"label": "Success",
"custom_id": "btn_success"
},
{
"type": 2,
"style": 4,
"label": "Danger",
"custom_id": "btn_danger"
},
{
"type": 2,
"style": 5,
"label": "Link",
"url": "https://example.com"
}
]
}
]
}
Кнопки с эмодзи
Добавьте эмодзи в кнопки для визуального выделения:
{
"content": "Выберите реакцию:",
"components": [
{
"type": 1,
"components": [
{
"type": 2,
"style": 3,
"label": "Нравится",
"custom_id": "like",
"emoji": {
"name": "👍"
}
},
{
"type": 2,
"style": 4,
"label": "Не нравится",
"custom_id": "dislike",
"emoji": {
"name": "👎"
}
}
]
}
]
}
Для кастомных эмодзи сервера:
{
"emoji": {
"name": "custom_emoji",
"id": "1234567890"
}
}
Отключённые кнопки
Кнопки можно отключить (они станут серыми и некликабельными):
{
"type": 2,
"style": 2,
"label": "Недоступно",
"custom_id": "disabled_button",
"disabled": true
}
Это полезно для обновления сообщений после взаимодействия.
Select Menu (выпадающие списки)
Select-меню позволяют выбрать одну или несколько опций из списка:
{
"content": "Выберите язык программирования:",
"components": [
{
"type": 1,
"components": [
{
"type": 3,
"custom_id": "language_select",
"placeholder": "Выберите язык...",
"min_values": 1,
"max_values": 1,
"options": [
{
"label": "JavaScript",
"value": "js",
"description": "Язык веб-разработки",
"emoji": {
"name": "🟨"
}
},
{
"label": "Python",
"value": "py",
"description": "Универсальный язык",
"emoji": {
"name": "🐍"
}
},
{
"label": "Rust",
"value": "rs",
"description": "Системный язык",
"emoji": {
"name": "🦀"
}
}
]
}
]
}
]
}
Параметры Select Menu
custom_id— уникальный ID для обработки (обязательно)placeholder— текст-подсказка (опционально)min_values— минимум выбранных опций (по умолчанию 1)max_values— максимум выбранных опций (по умолчанию 1)options— массив опций (макс. 25)
Параметры опций
label— отображаемый текст (обязательно, макс. 100 символов)value— значение для обработки (обязательно, макс. 100 символов)description— описание опции (опционально, макс. 100 символов)emoji— эмодзи рядом с опцией (опционально)default— выбрана по умолчанию (опционально)
Множественный выбор в Select Menu
Разрешите выбрать несколько опций:
{
"content": "Выберите ваши навыки (до 3):",
"components": [
{
"type": 1,
"components": [
{
"type": 3,
"custom_id": "skills_select",
"placeholder": "Выберите навыки...",
"min_values": 1,
"max_values": 3,
"options": [
{
"label": "Frontend",
"value": "frontend"
},
{
"label": "Backend",
"value": "backend"
},
{
"label": "DevOps",
"value": "devops"
},
{
"label": "Design",
"value": "design"
},
{
"label": "Mobile",
"value": "mobile"
}
]
}
]
}
]
}
Специальные типы Select Menu
Discord поддерживает select-меню для выбора пользователей, ролей и каналов:
User Select (выбор пользователей)
{
"type": 1,
"components": [
{
"type": 5,
"custom_id": "user_select",
"placeholder": "Выберите пользователя"
}
]
}
Role Select (выбор ролей)
{
"type": 1,
"components": [
{
"type": 6,
"custom_id": "role_select",
"placeholder": "Выберите роль"
}
]
}
Channel Select (выбор каналов)
{
"type": 1,
"components": [
{
"type": 8,
"custom_id": "channel_select",
"placeholder": "Выберите канал"
}
]
}
Важно: Эти типы select-меню работают только в ботах, webhook не может их обрабатывать.
Комбинирование компонентов
Можно комбинировать кнопки и select-меню в одном сообщении:
{
"content": "Настройте уведомления:",
"components": [
{
"type": 1,
"components": [
{
"type": 3,
"custom_id": "notification_type",
"placeholder": "Тип уведомлений",
"options": [
{
"label": "Все уведомления",
"value": "all"
},
{
"label": "Только упоминания",
"value": "mentions"
},
{
"label": "Отключить",
"value": "none"
}
]
}
]
},
{
"type": 1,
"components": [
{
"type": 2,
"style": 3,
"label": "Сохранить",
"custom_id": "save_settings"
},
{
"type": 2,
"style": 2,
"label": "Отменить",
"custom_id": "cancel_settings"
}
]
}
]
}
Отправка через webhook (JavaScript)
const webhookUrl = "https://discord.com/api/webhooks/YOUR_WEBHOOK_URL";
const payload = {
content: "Интерактивное сообщение:",
embeds: [{
title: "Выберите действие",
description: "Нажмите на кнопку ниже",
color: 5793266
}],
components: [
{
type: 1,
components: [
{
type: 2,
style: 5,
label: "Открыть документацию",
url: "https://discord.com/developers/docs"
},
{
type: 2,
style: 5,
label: "Открыть GitHub",
url: "https://github.com"
}
]
}
]
};
fetch(webhookUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
});
Отправка через curl
curl -H "Content-Type: application/json" \
-d '{
"content": "Выберите действие:",
"components": [
{
"type": 1,
"components": [
{
"type": 2,
"style": 5,
"label": "Документация",
"url": "https://discord.com/developers/docs"
}
]
}
]
}' \
https://discord.com/api/webhooks/YOUR_WEBHOOK_URL
Настоящие Components V2: компоненты разметки
Разделы выше описывают кнопки и select-меню — они существуют в Discord уже давно. Настоящее обновление “Components V2” добавило совершенно другой набор компонентов для разметки: Container, Section, TextDisplay, Separator, MediaGallery и File. С их помощью можно строить богатые структурированные сообщения без использования embed.
Формат сообщения Components V2
Чтобы использовать новые компоненты разметки, нужно установить flags: 32768 в сообщении. Этот флаг называется IS_COMPONENTS_V2 и указывает Discord рендерить сообщение в новой системе компонентов.
В режиме V2 массив components верхнего уровня может содержать:
- Container (type 17) — стилизованный блок-обёртка
- TextDisplay (type 10) — текст с markdown
- Separator (type 14) — визуальный разделитель
- MediaGallery (type 12) — сетка изображений или видео
- File (type 13) — отображение прикреплённого файла
- ActionRow (type 1) — кнопки и select-меню, как раньше
{
"flags": 32768,
"components": [
{
"type": 10,
"content": "**Привет!** Это сообщение использует Components V2."
}
]
}
Важно: При установке
flags: 32768нельзя использоватьcontentилиembedsна верхнем уровне. Весь контент размещается внутри компонентов.
Компонент Container (type 17)
Container — это визуальный блок, который группирует другие компоненты. Поддерживает опциональный цвет акцента (тот же целочисленный формат, что и у embed) и переключатель спойлера.
Свойства:
type:17accent_color: целочисленное значение цвета (опционально)spoiler: boolean, скрывает содержимое за спойлером (опционально)components: массив дочерних компонентов
Допустимые дочерние элементы: TextDisplay, Separator, Section, MediaGallery, ActionRow, File
{
"flags": 32768,
"components": [
{
"type": 17,
"accent_color": 5793266,
"spoiler": false,
"components": [
{ "type": 10, "content": "Привет **мир**!" },
{ "type": 14, "spacing": 1, "divider": true },
{ "type": 10, "content": "Второй абзац" }
]
}
]
}
accent_color отображается как цветная левая граница, аналогично цветам embed. Используйте наш справочник цветов для подбора нужного целочисленного значения.
Компонент TextDisplay (type 10)
Самый простой V2-компонент. Отображает блок текста с полной поддержкой Discord markdown.
Свойства:
type:10content: строка с markdown
{ "type": 10, "content": "**Жирный**, *курсив*, `код` и [ссылки](https://discord-webhook.com)" }
TextDisplay поддерживает весь стандартный Discord markdown: жирный, курсив, подчёркивание, зачёркивание, блоки кода, цитаты и ссылки.
Компонент Section (type 9)
Section размещает текст слева с аксессуаром (изображение Thumbnail или кнопка Button) справа. Подходит для карточек профиля, списков элементов или любого макета, где текст сочетается с визуальным элементом.
Свойства:
type:9components: массив компонентов TextDisplay (левая сторона)accessory: один объект Thumbnail (type 11) или Button (type 2)
{
"type": 9,
"components": [
{ "type": 10, "content": "**Статистика сервера**" },
{ "type": 10, "content": "Участников: 1 204\nОнлайн: 87" }
],
"accessory": {
"type": 11,
"media": {
"url": "https://cdn.discordapp.com/icons/SERVER_ID/icon.png"
}
}
}
Компонент Separator (type 14)
Separator добавляет визуальный разрыв между компонентами. Можно настроить размер отступа и наличие видимой линии-разделителя.
Свойства:
type:14spacing:1(маленький) или2(большой)divider: boolean — показывает горизонтальную линию при значенииtrue
{ "type": 14, "spacing": 1, "divider": true }
Используйте Separator для разбивки длинных Container на читаемые секции без создания нескольких Container.
Компонент MediaGallery (type 12)
MediaGallery отображает сетку изображений или видео. Каждый элемент галереи имеет собственный URL, описание и опциональный спойлер.
Свойства:
type:12items: массив медиа-объектов
Каждый медиа-элемент:
media: объект сurl(строка)description: альтернативный текст / подпись (опционально)spoiler: boolean (опционально)
{
"type": 12,
"items": [
{
"media": { "url": "https://example.com/screenshot1.png" },
"description": "Обзор дашборда"
},
{
"media": { "url": "https://example.com/screenshot2.png" },
"description": "Панель настроек",
"spoiler": false
}
]
}
Компонент File (type 13)
File отображает загруженное вложение прямо в макете сообщения.
Свойства:
type:13file: объект сurl(URL вложения)spoiler: boolean (опционально)
{
"type": 13,
"file": { "url": "attachment://report.pdf" },
"spoiler": false
}
url должен ссылаться на вложение, загруженное вместе с сообщением через multipart form data.
Полный пример V2-сообщения
Полное сообщение с несколькими V2-компонентами:
{
"flags": 32768,
"components": [
{
"type": 17,
"accent_color": 5763719,
"components": [
{
"type": 9,
"components": [
{ "type": 10, "content": "## Деплой завершён" },
{ "type": 10, "content": "**Сервис**: api-gateway\n**Версия**: v2.4.1\n**Окружение**: Production" }
],
"accessory": {
"type": 11,
"media": { "url": "https://example.com/success-icon.png" }
}
},
{ "type": 14, "spacing": 1, "divider": true },
{
"type": 12,
"items": [
{
"media": { "url": "https://example.com/deploy-graph.png" },
"description": "Время ответа после деплоя"
}
]
},
{ "type": 14, "spacing": 1, "divider": false },
{
"type": 1,
"components": [
{
"type": 2,
"style": 5,
"label": "Посмотреть логи",
"url": "https://logs.example.com"
},
{
"type": 2,
"style": 5,
"label": "Откатить",
"url": "https://deploy.example.com/rollback"
}
]
}
]
}
]
}
Результат — один стилизованный блок с заголовком секции, медиа-изображением, разделителем и кнопками-ссылками, без использования embed.
Лимиты Components V2
| Лимит | Значение |
|---|---|
| Компонентов верхнего уровня в сообщении | 40 |
| Компонентов в Container | 10 |
| ActionRow в Container | 5 (макс.) |
| Элементов в MediaGallery | 10 |
| Длина контента TextDisplay | 4000 символов |
Визуальное создание V2-сообщений
Составлять вложенный JSON вручную быстро надоедает. Наш конструктор Discord Webhook поддерживает все типы Components V2 — Container, Section, TextDisplay, Separator, MediaGallery и другие. Создавайте макет визуально, смотрите предпросмотр в реальном времени, затем копируйте JSON прямо в свой код.
Лимиты компонентов
Discord устанавливает следующие лимиты:
| Элемент | Лимит |
|---|---|
| Action Rows в сообщении | 5 |
| Кнопок в Action Row | 5 |
| Select Menu в Action Row | 1 |
| Опций в Select Menu | 25 |
| Длина label кнопки | 80 символов |
| Длина custom_id | 100 символов |
| Длина label опции | 100 символов |
| Длина value опции | 100 символов |
Важно: Нельзя смешивать кнопки и select-меню в одном Action Row.
Обработка взаимодействий (только для ботов)
Webhook не могут обрабатывать нажатия на кнопки. Для этого нужен бот:
// Пример обработки в Discord.js
client.on("interactionCreate", async (interaction) => {
if (!interaction.isButton()) return;
if (interaction.customId === "confirm_action") {
await interaction.reply({
content: "Действие подтверждено!",
ephemeral: true
});
}
});
Если вы отправляете компоненты через webhook, убедитесь, что у вас есть бот для обработки взаимодействий.
Практический пример: Сообщение с ссылками
Webhook может отправлять кнопки-ссылки без необходимости в боте:
const sendLinksMessage = async () => {
const payload = {
embeds: [{
title: "Полезные ресурсы",
description: "Документация и инструменты для разработки",
color: 5793266
}],
components: [
{
type: 1,
components: [
{
type: 2,
style: 5,
label: "Discord API",
url: "https://discord.com/developers/docs",
emoji: { name: "📚" }
},
{
type: 2,
style: 5,
label: "Webhook Builder",
url: "https://discord-webhook.com/app",
emoji: { name: "🛠️" }
}
]
},
{
type: 1,
components: [
{
type: 2,
style: 5,
label: "GitHub",
url: "https://github.com",
emoji: { name: "💻" }
},
{
type: 2,
style: 5,
label: "Stack Overflow",
url: "https://stackoverflow.com",
emoji: { name: "❓" }
}
]
}
]
};
await fetch(webhookUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
});
};
Частые ошибки
1. Смешивание кнопок и select-меню в одном Action Row
// Неправильно
{
type: 1,
components: [
{ type: 2, style: 1, label: "Кнопка", custom_id: "btn" },
{ type: 3, custom_id: "select", options: [...] }
]
}
// Правильно — разные Action Rows
{
components: [
{
type: 1,
components: [{ type: 2, style: 1, label: "Кнопка", custom_id: "btn" }]
},
{
type: 1,
components: [{ type: 3, custom_id: "select", options: [...] }]
}
]
}
2. Использование custom_id с кнопками-ссылками
// Неправильно
{
type: 2,
style: 5,
label: "Ссылка",
url: "https://example.com",
custom_id: "link_btn" // Не нужен для ссылок
}
// Правильно
{
type: 2,
style: 5,
label: "Ссылка",
url: "https://example.com"
}
3. Превышение лимита кнопок
// Неправильно — 6 кнопок в одном Action Row
{
type: 1,
components: [
{ type: 2, style: 1, label: "1", custom_id: "1" },
{ type: 2, style: 1, label: "2", custom_id: "2" },
{ type: 2, style: 1, label: "3", custom_id: "3" },
{ type: 2, style: 1, label: "4", custom_id: "4" },
{ type: 2, style: 1, label: "5", custom_id: "5" },
{ type: 2, style: 1, label: "6", custom_id: "6" } // Превышен лимит
]
}
// Правильно — разделить на два Action Rows
Что дальше
Discord Components делают сообщения интерактивными и удобными. Webhook могут отправлять кнопки-ссылки без необходимости в боте, что идеально для документации, навигации и внешних интеграций.
Если вам нужны кнопки, которые выполняют реальные действия при нажатии — выдача ролей, открытие форм, отправка личных сообщений — ознакомьтесь с нашим руководством по интерактивным кнопкам и системе действий. Это работает без написания кода через визуальный конструктор.
Попробуйте визуально в нашем бесплатном конструкторе Discord Webhook — создавайте сообщения с кнопками и select-меню с предпросмотром в реальном времени, а затем экспортируйте JSON для вашего кода.
Похожие статьи
- Полное руководство по Discord Embed: поля, цвета, изображения, лимиты — Основы создания embed-сообщений для использования с компонентами
- Цвета Discord Embed — Полный справочник цветовых кодов — Выбор правильных цветов для кнопок и embed
- Автоматические уведомления через Discord Webhook — Полное руководство — Использование компонентов в автоматических уведомлениях
- Лучшая альтернатива Discohook — Сравнение инструментов для создания Discord вебхуков
- Интерактивные кнопки и действия — без кода — Кнопки с ролями, формами и цепочками действий
Попробуйте в нашем инструменте
Открыть конструктор Discord Webhook