Перейти к содержимому
Все статьи
· Обновлено 17 февраля 2026 г.

Гайд по Discord Components V2: кнопки, меню, контейнеры и секции в вебхуках

Полное руководство по Discord Components V2: Container, Section, TextDisplay, MediaGallery, Separator, а также кнопки и select-меню в webhook-сообщениях. Примеры кода и лимиты API.

componentsdiscord apiwebhookинтерактивностьdiscord components 2026контейнерысекции
Гайд по Discord Components V2: кнопки, меню, контейнеры и секции в вебхуках

Что такое 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 — Button
  • type: 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: 17
  • accent_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: 10
  • content: строка с markdown
{ "type": 10, "content": "**Жирный**, *курсив*, `код` и [ссылки](https://discord-webhook.com)" }

TextDisplay поддерживает весь стандартный Discord markdown: жирный, курсив, подчёркивание, зачёркивание, блоки кода, цитаты и ссылки.

Компонент Section (type 9)

Section размещает текст слева с аксессуаром (изображение Thumbnail или кнопка Button) справа. Подходит для карточек профиля, списков элементов или любого макета, где текст сочетается с визуальным элементом.

Свойства:

  • type: 9
  • components: массив компонентов 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: 14
  • spacing: 1 (маленький) или 2 (большой)
  • divider: boolean — показывает горизонтальную линию при значении true
{ "type": 14, "spacing": 1, "divider": true }

Используйте Separator для разбивки длинных Container на читаемые секции без создания нескольких Container.

Компонент MediaGallery (type 12)

MediaGallery отображает сетку изображений или видео. Каждый элемент галереи имеет собственный URL, описание и опциональный спойлер.

Свойства:

  • type: 12
  • items: массив медиа-объектов

Каждый медиа-элемент:

  • 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: 13
  • file: объект с 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
Компонентов в Container10
ActionRow в Container5 (макс.)
Элементов в MediaGallery10
Длина контента TextDisplay4000 символов

Визуальное создание V2-сообщений

Составлять вложенный JSON вручную быстро надоедает. Наш конструктор Discord Webhook поддерживает все типы Components V2 — Container, Section, TextDisplay, Separator, MediaGallery и другие. Создавайте макет визуально, смотрите предпросмотр в реальном времени, затем копируйте JSON прямо в свой код.

Лимиты компонентов

Discord устанавливает следующие лимиты:

ЭлементЛимит
Action Rows в сообщении5
Кнопок в Action Row5
Select Menu в Action Row1
Опций в Select Menu25
Длина label кнопки80 символов
Длина custom_id100 символов
Длина 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 Webhook