Слэш команды дискорд бот

Обновлено: 07.07.2024

Before we begin getting started on everything else, it is recommended to check out the quickstart page first to get a basic grip on making slash commands for your bot.

Making a slash command.¶

The basics.¶

First, let’s explain by how commands are parsed through the Discord Bot API.

Field

Type

Description

1-32 character name matching ^[\w-]$ .

1-100 character description.

if the option is a subcommand or subcommand group type, this nested options will be the parameters.

This table shows us the way that Discord handles the structure of commands for slash commands through their Bot API. For visualization purposes, we’ll quickly make a JSON example (although we won’t be using it) in order to explain how this works:

Now that we have a basic understanding of how the JSON table works, we can take this knowledge and convert it into a decorator method for the Python code as shown below:

Now that we’ve gone over how Discord handles the declaration of slash commands through their Bot API, let’s go over what some of the other things mean within the logical part of our code, the command function:

Giving some options for variety.¶

The next thing that we will begin to talk about is the implementation of options, otherwise well-known as “arguments” in discord.py commands.

The JSON structure of options are designed up to be similar to the same premise of how a slash command is declared. Below is the given table of how an option JSON would appear as:

Field

Type

Description

1-32 character name matching ^[\w-]$ .

1-100 character description.

the first required option for the user to complete–only one option can be default.

if the parameter is required or optional–default false .

choices for string and int types for the user to pick from.

if the option is a subcommand or subcommand group type, this nested options will be the parameters.

Now we have an idea of how options are declared. With this in mind, let’s quickly make a JSON example in order to visualize this concept even further:

While the table in the basics mentions an array in particular called ApplicationCommandOptionType , there isn’t that much of an explanation on how this works. Let’s put this into better laymen terms on what this means with a table below showing all of these values:

Name

Value

The purpose of having the ApplicationCommandOptionType value passed into our option JSON structure is so that we can help the Discord UI understand what kind of value we’re inputting here. For instance, if we’re wanting to put in a string response, we’ll pass the ID 3 so that the UI of Discord chat bar knows to format it visually this way. If we’re looking for a user, then we’ll pass ID 6 so that it presents us with a list of users in our server instead, making it easier on our lives.

This is not to be confused, however, with formatting the response type itself. This is merely a method so that the API wrapper can help us with passing the correct type or instance variable with the arguments of the command function’s code.

Now, we can finally visualize this by coding an example of this being used in the Python code shown below.

More in the option? Give them a choice.¶

Alas, there is also a way to give even more information to options with Discord’s Slash Commands: a choice. Not like something that you’re given at birth of when you become of legal age as an adult, we’re not here to give you that kind of life advice, but the choice of what value you want your option to rather pass. Below is a table that shows the JSON structure of how choices are represented for an option:

Field

Type

Description

1-32 character choice name.

value of the choice, up to 100 characters if string.

This time, only 2 fields are able to be passed for this. Below is a JSON example of how this would be designed:

To make it really simple, the name field is only to be used for how you want the choice to be presented through Discord’s UI. It’s the “appearance” of how you want your choice shown, not the actual returned value of it. Hence, this is why value is the second field passed for that, which can be either in the form of a string or integer. Below is an implementation of this design in the Python code:

Want to restrict access? Setup permissions!¶

Slash commands also support the ability to set permissions to allow only certain roles and/or users to run a slash command. Permissions can be applied to both global and guild based commands. They are defined per guild, per top-level command (the base command for subcommands), and each guild can have multiple permissions. Here is the table that shows the JSON structure of how permissions are represented:

Field

Type

Description

Snowflake value of type specified. Represents the target to apply permissions on.

True to allow, False to disallow.

How the type parameter works is very simple. Discord has many ids to represent different things. As you can set permissions to apply for User or Role, ApplicationCommandPermissionType is used. It’s a number and following table shows the supported id types for permissions:

Name

Value

This is an example of how a single permission will look when represented as a json object:

Now, let take a look at an example. The slash command decorator has a permissions parameter where it takes in a dictionary. The key being the guild id to apply permissions on, and value being the list of permissions to apply. For each permission, we can use the handy create_permission method to build the permission json explained above.

In this case, we are setting 2 permissions for a guild with an id of 12345678 . Firstly, we are allowing role with id 99999999 and disallowing user with id 88888888 from running the slash command.

But what about buttons?¶

Making a message/menu command.¶

Lucky for you, this library has recently added support for context menus! Let’s take a look into how they’re designed.

Please note that the current limit for context menus with the Discord API is 5.

A menu command (context menu) is an easy way for bot developers to program optionless and choiceless commands into their bot which can be easily accessible by right clicking on a user and/or message present. Below is a table of the supported keys and values:

Field

Type

Description

The name of the context menu command.

The following table below represents how it would be shown as a JSON object:

The following table explains more about the type parameter being passed, which there are three of: CHAT_INPUT , USER and MESSAGE . By default, the type will always be the first. This is because it is a registered type that is used to process slash commands, and should not be used for when you are declaring context menu commands in your bot’s code at all:

Name

Value

Unlike manage_commands and manage_components , you will have to use a decorator for now to register them:

Can I use components with context menus?¶

Of course! However, you will need to add in some additional code in order for both of the separate contexts to work seamlessly. Below is the given code of what will need to be changed:

Hey, what about component/[X] listening?¶

The decision has been made that this will not be implemented because of two reasons: context menus currently have no ability to hold any options or choices, so listening for any responses would be currently pointless. Additionally, component listening is already a built-in feature that does not require further customized and new decorators for explicitly context menus, as they’re more universal.

Nested commands as subcommands.¶

Before you get into learning how to create a subcommand, please be sure to read up on the documentation above given for how slash commands are made.

Subcommands are way to “nest” your slash commands under one (or more) given names, as either a “base” name or a “grouping” of an existing base. When this is said, it will initially appear very confusing. Let’s use the table shown below as a way to introduce the new fields/properties that can be applied for a slash command to become a subcommand:


"The API for interacting with Gateways is complex and fairly unforgiving, therefore it's highly recommended you read all of the following documentation before writing a custom implementation." - Discord API Docs

Добрый день. Многие знают, что программисту приходится следить за развитием технологий, даже тех, которые не касаются его текущего стека. Ну, или ему это доставляет удовольствие, которое он оправдывает необходимостью держать руку на пульсе. Так обычно зарождаются разнообразные домашние проекты. Я решил свести в один пост свои наработки по написанию Node.js-бота для Discord Slash API с Serverless подходом в Yandex Cloud. Использование готовых библиотек сведено к минимуму.

Discord?

Discord — это многим известный мессенджер, бесплатный до определённых пределов. Он позволяет без особых технических навыков построить коммьюнити по какой-то теме. В основном, конечно, это геймерские сообщества, именно так себя Discord и позиционирует — встроенная функциональность для трансляции игр и прочие навороты. Ими, впрочем, дело не ограничивается — на Хабре пробегали статьи про жизнь небольших контор в этом мессенджере, также там заседают алготрейдеры с «Реддита» и много кто ещё. В определённой степени эта популярность вызвана открытым API для написания ботов. Как правило, в любом сообществе администраторы создают 1–2 канала для совместного прослушивания музыки, игр в простые текстовые развлечения — атмосфера IRC начала нулевых.

В настоящий момент существует два API для ботов на этой платформе. Одно, ставшее классическим, основано на вебсокетах. Второе Discord открыл в конце 2020 года — и им можно пользоваться на чистом REST.

Изначально я наткнулся на статью про Python и AWS, но просто скопировать её было бы слишком скучно для понимания и погружения, поэтому пришлось читать документацию самостоятельно.

Discord Slash API?

Базовый сценарий:


Начнём с простого — заставим эту связку минимально работать. Нужно отвечать на команду
/дай с параметром фотку:<тип> соответствующей картинкой. Варианта будет три — котик, собакен или случайная из двух.

У Discord (в отличие от Telegram) довольно разухабистая система авторизаций, проверок и перекрёстных страниц, по которым надо пройти, чтобы все участники взаимодействия получили свои права в нужном объёме. Общением с @Botfather дело не ограничивается.

Сначала идём на портал разработчика и создаём новое приложение. На этой странице нам пригодятся поля APPLICATION ID и PUBLIC KEY. На вкладке Oauth2 нужно скопировать CLIENT SECRET, он тоже пригодится.

С помощью этих данных можно получить временный Bearer token, который позволяет авторизовываться на некоторых служебных эндпоинтах. Получим его:

CLIENT SECRET вводим весто пароля в интерактивном режиме.
Ответом будет примерно такой JSON:

Из ответа надо запомнить уже поле access_token. Обратите внимание, что scope — тоже значащее поле. Оно определяет, какие права будут у выданного нам токена. Перечисленных в примере хватит для дальнейшей работы.

Работать она, конечно же, ещё не будет.


Знания, необходимые для этой, казалось бы, простой подготовительной части, щедро рассыпаны по документации, так что написание первой простейшей версии бота заняло у меня несколько вечеров. Кроме того — таких извращенцев просто мало, в основном эту функциональность используют вместе с основным ботом, висящим на WebSocket с помощью библиотеки discord.js (что, конечно, получается гораздо быстрее), и готовых сниппетов в интернете практически нет.

Пришла пора писать Serverless-функцию, которая будет отвечать на запросы.

Yandex Cloud Functions

Я не буду подробно останавливаться на описании интерфейса консоли Yandex Cloud. Типичный жизненный цикл Serverless-функций — это обрабатывать входящие обращения, иногда уже отсортированные Gateway API, и отдавать результат. Биллинг потом спишет копеечку за время работы функции.

Итак, в консоли Yandex Cloud создаём новую функцию, среда выполнения — Node.js 14, время выполнения — 3 секунды (про него объясню позднее), доступная память — минимальная — 128 МБ.

Начинаем писать мало-мальски работающий код:

Мы объявили функцию, которая будет вызываться при получении REST-запроса по своему случайно сгенерированному постоянному адресу. В параметр event прилетает всё описание запроса — заголовки и тело. Переменная, которую мы возвращаем, описывает, как должен выглядеть ответ, его статус, заголовки и тело.

Бот обязан проверять подпись входящих запросов. Discord при первом сохранении endpoint проверяет, как она реагирует на запрос с некорректной подписью. И если бот не сможет распознать его и ответить 401-й ошибкой — откажется с ней работать. Проверку было решено отдать на откуп готовой библиотеке, помня о первой заповеди самостоятельной реализации аутентификации — «не делай этого».

Рядом с этим файлом нужно создать package.json, положив в него описание проекта, а главное — зависимостей:

После сохранения этого файла на вкладке «Операции» появится запись о том, что все зависимости установлены. Конечно, никто не мешает писать код в любимой IDE, а затем положить его в ZIP и закинуть на сервер со всеми зависимостями — но мне было интересно, как работает этот функционал.

У проверки подписи есть побочный эффект — вы не сможете потыкать свою функцию тестовыми данными, чтобы проверить её работу. Так что при более-менее серьёзной разработке поднимайте отдельную версию функции, которая не столь радикально относится к подписи. А заниматься такой отладкой придётся, потому что Discord не расскажет вам, что пошло не так при общении с ботом. Именно ручная отладка помогла мне понять, что по умолчанию функция отдаёт заголовок text/plain вместо нужного application/json.

Итак, после сохранения можно взять URL функции, зайти в личный кабинет приложения на сайте Discord, вбить его в поле INTERACTIONS ENDPOINT URL и сохранить. Ура. Теперь начнём, наконец, что-то отвечать на саму команду:


Первая итерация закончена, бот работает, выдает одну, вторую или случайную картинку. Конечно, это абсолютно синхронная и лёгкая операция, и отдавать таким образом статику суперпросто. Теперь пойдём дальше — и сделаем нашу функцию асинхронной.

Все, перед кем вставала задача радовать неугомонных пользователей фотографиями животных, наверное, знают про сервисы The Cat API и The Dog API. Это API, отдающее ссылки на фотографии, доступные для использования в проектах, похожих на наш. Большинство подобных сервисов реализуют функцию random и сами следят за актуальностью фотографий в своей базе, что снимает с разработчика множество проблем. Такие сервисы есть почти по любой тематике, и многие из них бесплатны до какого-то количества обращений. Мне вполне хватало этого лимита, так что я приступил к их использованию, всего лишь один fetch-запрос до сервиса. и сразу наступил на грабли того самого ограничения в 3 секунды, про которое говорил ранее. И проблема тут совсем не во времени исполнения функции — хотя, учитывая, что тарифицируют нас за время работы, необдуманно забивать это поле девятками — безусловно, не лучшая идея.

Я не планировал скачивать изображения и считал что «трёх секунд хватит всем»​, но нет. Во-первых, запросы в нашем несовершенном мире иногда падают по сетевым причинам. Во-вторых, сервисы эти монетизируются крайне условно и геокешинг с CDN в разных странах, как правило, не используют. Запросы отрабатывали, но за 3 секунды можно вылететь.

Кроме того, однажды я попал в ситуацию, когда изображения перестали открываться в чате. Виноват оказался Роскомнадзор: CDN сервиса с котиками попал под блокировку. Сам сервис отдавал ссылку на картинку, я передавал её в чат, а Discord не мог открыть её, так как из России адрес был недоступен. Дополнительная проверка ссылки на доступность (напомню, мы всего лишь пытаемся показывать милые фото котиков) делала перспективы уложиться в 3 секунды более призрачными, особенно в случае повторного запроса.

Решение? Очевидно — создадим ещё одну функцию.

Новый план!


Изменения в быстрой функции:

Работа с точки зрения пользователя:


Итоги

Главный вопрос, который может возникнуть при прочтении: «Зачем?».

Иногда нужен контроль, иногда страшно, что функция слишком бодро масштабируется, иногда есть виртуалка, на которой вполне хватит места на ещё-один-докер-с-js-процессом-внутри. Но рано или поздно за этим придётся следить — переносить процесс, данные, добавлять мониторинг, обновлять систему, наконец. Serverless-подход несложен в использовании, не требует ухода после деплоя и очень дёшев при небольших/нечастых нагрузках для домашних проектов.

Кстати, про «дёшево» — это, как правило, второй возникающий вопрос. Посчитаем по прайсу.

При тарификации вычислительных ресурсов (ГБ × час) учитывается объём памяти, выделенный для функции, и время выполнения функции.

На июль 2021 г. 1 миллион вызовов стоит 10 ₽, ГБ*час стоит 3,42 ₽, а исходящий трафик — 0,96 ₽ за гигабайт.

Среднее оплачиваемое время выполнения этих функций (из отчёта Yandex Cloud):

Медленная функция: 1200 мс
Быстрая: 200 мс

Итого: 1,4 с на обработку одного запроса.

Прикинем стоимость миллиона котиков:

3,42 × (128 / 1024) × (1200 / 3600 / 1000) × 1 000 000 + 10 × (1 000 000 / 1 000 000) = 152,5 ₽

Но — приятный подарок — первый миллион запросов, первые 10 ГБ × час в месяц и первые 10 ГБ исходящего трафика не тарифицируются.

Из моей личной практики (на канале в 400 человек, где у бота есть клуб преданных фанатов): он ни разу не вышел в платный режим. Даже с учётом вакханалии на 1 апреля, когда он показывал, а затем оперативно удалял чуть-чуть NSFW-шные картинки, которые «случайно» попали в его базу.

Для меня это уже не первый раз, когда Serverless-решение оказалось дешевле, но главное — гораздо проще в поддержке , чем стандартный подход.

Неважно, что вы делаете — планировщик задач, торгового бота или такой проект на коленке, — прежде чем писать ещё_один_демон_за_которым_надо_следить, подумайте, возможно Serverless подойдёт вам больше.

This page assumes you use the same file structure as our command handling section. The scripts provided are made to function with that setup.

If you already have slash commands set up for your application and want to learn how to respond to them, refer to the following page.

First off, install the @discordjs/rest

open in new window by running the following command in your terminal:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

Running this script will register all your commands to the guild of which the id was passed in above.

To deploy global commands, you can use the same script from the guild commands section and adjust the route in the script to .applicationCommands(clientId) .

Application commands can have options . Think of these options as arguments to a function. You can specify them as shown below:

Notice how .setRequired(true) is specified within the options builder. Setting this will prevent the user from sending the command without specifying a value for this option!

As shown in the options example above, you can specify the type of an ApplicationCommandOption . Listed below are all the possible values you can pass as ApplicationCommandOptionType :

The slash command builder has a method for each of these types respectively. Refer to the Discord API documentation for detailed explanations on the SUB_COMMAND and SUB_COMMAND_GROUP option types

  • SUB_COMMAND sets the option to be a subcommand
  • SUB_COMMAND_GROUP sets the option to be a subcommand group
  • STRING sets the option to require a string value
  • INTEGER sets the option to require an integer value
  • NUMBER sets the option to require a decimal (also known as a floating point) value
  • BOOLEAN sets the option to require a boolean value
  • USER sets the option to require a user or snowflake as value
  • CHANNEL sets the option to require a channel or snowflake as value
  • ROLE sets the option to require a role or snowflake as value
  • MENTIONABLE sets the option to require a user, role or snowflake as value

The STRING and INTEGER option types both can have choices . choices are a set of predetermined values users can pick from when selecting the option that contains them.

Specify them by using the addChoice() method from the slash command builder:

Your ultimate Discord interactions library for discord.py.

What is discord-interactions?

discord-interactions is, in the simplest terms, a library extension that builds off of the currently existing discord.py API wrapper. While we do use our own basic class code for our own library, a large majority of this library uses discord.py base events in order to make contextualization of interactions relatively easy for us.

When did this begin?

In mid-December of 2020, Discord released the very first type of components, slash commands. These were relatively primitive at the time of their debut, however, over time they slowly came to grew more complex and mutable. This library was created 2 days after the release of slash commands to Discord, and ever since has been actively growing.

What do we currently support?

At this time, we are able to provide you an non-exhaustive list (because Discord are actively creating more interactions at this time) of all components integrated as interactions:

  • Slash Commands
  • Buttons
  • Selects (also known as dropdowns or menus)

We recommend using pip in order to install our library. You are able to do this by typing the following line below:

pip install -U discord-py-slash-command

Slash Commands

This example shows a very quick and simplistic solution to implementing a slash command.

This example serves as an alternative method for using slash commands in a cog instead.

Buttons

This basic example shows how to easily integrate buttons into your commands. Buttons are not limited to slash commands and may be used in regular discord.py commands as well.

Advanced

For more advanced use, please refer to our official documentation on buttons here.

Selects

This basic example shows how to add selects into our bot. Selects offer the same accessibility as buttons do in premise of limitations.

Advanced

For more advanced use, please refer to our official documentation on selects here.


Одним из главных помощников для пользователей Discord являются команды для чатов и ботов, а также горячие клавиши для общения или игры. Ниже рассмотрим разные виды команд, приведем их расшифровку и особенности применения.

Команды для бота

Боты — специальные коды, созданные на базе API и используемые на серверах Дискорд. Они устанавливаются в программе и используются для расширения ее функционала. Сегодня существует много полезных Discord-ботов. Наиболее популярные — Mee6, Red, Dyno и другие. Все они отличаются по особенностям работы и функциональной начинке. При этом команды для ботов в Дискорде также отличаются. Эти данные необходимо изучать перед добавлением на официальной странице софта.

К примеру, Mee6 — универсальный бот, позволяющий создавать свои собственные команды и настраивать поздравление для участников.


Выделим несколько основных Дискорд-команд:

Команды чата

Многие пользователи не знают, что существуют так называемые команды Дискорда для чата. Выделим основные варианты:


Как видно, Дискорд-команды чата больше направлены на оформление текста и исправление ошибок. Но их применение во многих случаях может оказаться полезным.

Горячие клавиши

Не менее полезная опция — горячие клавиши Discord, которые можно использовать в обычном режиме или во время игры. При желании их легко задать вручную Для этого сделайте следующие шаги:

  1. Войдите в программу Дискорд.
  2. Жмите на шестеренку внизу.
  3. Найдите слева пункт Горячие клавиши.
  4. Выберите необходимое действие в любом из полей.
  5. Введите в поле рядом нужную комбинацию.


При желании можно забить комбинацию на рацию (обычный и приоритетный) режим, обратную рацию, включение и отключение микрофона, режима стримера, звука в динамиках, оверлея и т. д.

При этом есть ряд клавиш, которые работают по умолчанию. К примеру, комбинация shift+` используется прямо в игре. В этом случае появляется список голосовых Дискорд-каналов и настройка оверлея. Комбинацию можно поменять в разделе настроек. После появления списка каналов жмите на левую кнопку мышки по участнику и поменяйте громкость.

Дополнительно можно использовать и другие комбинации:


Если вдруг не работают горячие клавиши Дискорд, попробуйте из заново запрограммировать через настройки или убедитесь в работоспособности клавиатуры.

Итоги

Теперь вы знаете, какие команды бывают в Discord, для чего их можно использовать, и чем они помогают пользователям. Главное — не упускать такую возможность и пользоваться ей во время общения или игры.

Читайте также: