Перейти к основному содержимому
Версия: 2026.2.4

Interactions API: слэш-команды

Interactions — это Discord-style слэш-команды: пользователь начинает вводить /, видит список команд бота с подсказками, выбирает нужную, заполняет параметры — и бот получает структурированный запрос вместо того, чтобы разбирать текст сообщения. Сюда же относятся клики по кнопкам/меню на сообщениях бота и заполнение модальных окон — все три сценария используют один и тот же жизненный цикл «interaction → ответ бота».

Interactions обслуживает отдельный gRPC-сервис — InteractionsApi. Он логически разбит на две части с разными правами вызова:

ЧастьКто вызываетАутентификация
Регистрация команд (RegisterCommand, UpdateCommand, DeleteCommand, GetBotCommands)Владелец бота или сам ботОба варианта: пользовательский вход (владелец) либо токен бота с intent'ом ApplicationCommands
Выполнение (ExecuteCommand, RequestAutocomplete, InvokeMessageComponent, SubmitModal)Любой участник группы (обычно — сам клиент Voice, когда пользователь вводит команду)Обычный пользовательский вход — это действие человека, не бота

Библиотеке для ботов из этого сервиса обычно нужна только регистрация команд — сам бот не «выполняет» команды, он лишь регистрирует их при старте, а затем получает уже готовый, структурированный InteractionCreated через Gateway и отвечает через BotsApi (см. ниже).

Регистрация команд​

RegisterCommand {
bot_id: "<id бота>"
name: "weather"
description: "Показать погоду в городе"
options: [
{ name: "city", description: "Город", type: STRING, required: true, autocomplete: true }
]
default_member_permissions: 0
}

Типы параметров команды (CommandOptionType): STRING, INTEGER, BOOLEAN, USER, CHANNEL, ROLE, NUMBER, SUB_COMMAND, SUB_COMMAND_GROUP. Параметр с autocomplete: true не имеет статичного списка choices — вместо этого сервер будет присылать боту запрос RequestAutocomplete по мере ввода пользователем текста в это поле, а бот должен ответить динамическим списком подсказок (см. ниже про типы ответа).

UpdateCommand/DeleteCommand работают предсказуемо — обновляют/удаляют ранее зарегистрированную команду по command_id. GetBotCommands возвращает все команды конкретного бота. Команды сейчас глобальные для бота — действуют во всех группах, где он состоит, отдельной регистрации на каждую группу не требуется.

Регистрируйте команды при каждом старте бота

Типичный паттерн — синхронизировать список команд при запуске бота: получить уже зарегистрированные (GetBotCommands), сравнить с тем, что описано в коде, создать недостающие, обновить изменившиеся, удалить лишние. Так разработчику бота достаточно объявить команды в коде — без отдельного шага «выложить команды в консоли администратора».

Жизненный цикл одного interaction​

  1. Пользователь вызывает слэш-команду / кликает кнопку / отправляет форму модального окна.
  2. Сервер создаёт короткоживущую сущность interaction'а и присылает боту событие InteractionCreated через топик interaction-events Gateway (адресно, этому конкретному боту).
  3. У бота есть ограниченное окно времени, чтобы ответить через BotsApi.RespondToInteraction:
    • 10 секунд — для слэш-команд, кликов по компонентам, сабмитов модальных окон;
    • 3 секунды — для запросов автодополнения (RequestAutocomplete). Если бот не успевает — interaction считается просроченным, попытка ответить на него позже вернёт ошибку FailedPrecondition.
  4. Если ответ требует времени (например, боту нужно сходить во внешний API), он может сначала отправить «отложенный» ответ (DEFERRED_CHANNEL_MESSAGE/DEFERRED_UPDATE_MESSAGE) в пределах тех же 10 секунд, а затем прислать содержательный ответ уже через SendInteractionFollowup — на это даётся 15 минут с момента первого ответа («followup window»).

Полезная нагрузка InteractionCreated​

{
"interactionId": "...",
"invokingUserId": "...",
"channelId": "...",
"groupId": "...",
"type": "ApplicationCommand",
"data": {
"commandName": "weather",
"options": { "city": "Berlin" },
"customId": null,
"values": null,
"focusedOption": null,
"modalFields": null
}
}

type — один из четырёх видов, определяющий, какие поля data заполнены:

typeЧто произошлоЗаполненные поля data
ApplicationCommandВызвана слэш-командаcommandName, options
MessageComponentКлик по кнопке/пункту меню на сообщении ботаcustomId, values (для меню с несколькими вариантами)
ModalSubmitОтправлена форма модального окнаcustomId (id модального окна), modalFields (значения полей по их customId)
ApplicationCommandAutocompleteПользователь печатает в поле с autocomplete: truecommandName, options (уже введённые значения других полей), focusedOption (какое поле сейчас в фокусе)

Ответ бота​

RespondToInteraction {
interaction_id: "..."
kind: CHANNEL_MESSAGE
content: "В Berlin сейчас +12°C"
components_json: null // опционально, см. "Компоненты и модальные окна"
modal_json: null
autocomplete_choices: []
ephemeral: false
}

Вид ответа (kind, он же InteractionResponseKind):

ЗначениеКогда используется
CHANNEL_MESSAGEОбычный ответ — новое сообщение в канал
DEFERRED_CHANNEL_MESSAGE«Думаю…» — подтверждает получение, реальный ответ придёт позже через SendInteractionFollowup
UPDATE_MESSAGEТолько для ответа на клик по компоненту — редактирует то самое сообщение, на котором был клик, вместо создания нового
DEFERRED_UPDATE_MESSAGEТо же, но с отложенным редактированием
MODALОткрывает у пользователя модальное окно (modal_json, см. «Компоненты и модальные окна») — доступно только в ответ на слэш-команду или клик по компоненту, не на сабмит другого модального окна
AUTOCOMPLETE_RESULTОтвет на ApplicationCommandAutocomplete — список подсказок (autocomplete_choices)

ephemeral: true означает, что ответ увидит только сам вызвавший команду пользователь (остальные участники канала — нет). Работает только для CHANNEL_MESSAGE/DEFERRED_CHANNEL_MESSAGE.

Ответ становится обычным сообщением

Если kind — CHANNEL_MESSAGE (не эфемерный), результат действительно создаёт настоящее сообщение в канале — оно попадёт в историю чата, на него распространяются UpdateMessage/ DeleteMessage из BotsApi, а рядом с ним показывается Discord-style пометка «использовал(а) /имя-команды».