Ресурсов для создания ботов Discord очень мало. Кроме того, функциональные возможности Discord постоянно изменяются или добавляются, что удерживает пользователей от создания забавных или полезных ботов для себя и своих сообществ. Как текущий разработчик бота Discord, управляющий ботом, базой данных и сотнями пользователей, я составил руководство, содержащее основы, а также несколько советов из моего собственного опыта. Это руководство поможет вам создать бота Discord с нуля с помощью discord.py.
Начало работы:
- Посетите https://discord.com/developers/applications, чтобы начать работу с ботом Discord.
ПРИМЕЧАНИЕ. для этого потребуется наличие подтвержденной учетной записи Discord, а также двухфакторная аутентификация с помощью Google Authenticator.
- Нажмите «Новое приложение» в правом верхнем углу, дайте своему боту имя и согласитесь с Условиями использования для разработчиков.
Поздравляю! Вы создали своего первого бота! Теперь давайте пригласим его в гильдию и дадим ему функциональность!
Приглашение вашего бота:
- Нажмите «OAuth2» в левом столбце и выберите «Генератор URL» из дополнительных параметров.
- Хотя это меню может показаться громоздким, настройка довольно проста! В разделе «scopes» просто отметьте «bot». В этом руководстве используется новый API взаимодействий и встроенные команды косой черты. Чтобы включить их, также проверьте «applications.commands».
- «Разрешения для ботов» зависят от вас! Я лично даю своему боту административный контроль, потому что ему нужны почти все опции для правильной работы. Однако, если вы не планируете использовать все функции Discord, проверьте только то, что, по вашему мнению, потребуется для вашей функциональности.
- Скопируйте/вставьте сгенерированный URL внизу страницы и откройте его в своем браузере! Выберите гильдию, в которую вы хотите ее пригласить, а затем разрешите ей присоединиться!
ПРИМЕЧАНИЕ. Вы также можете сохранить это для будущих приглашений.
Стратегия программирования:
Хотя в этом руководстве используется discord.py, существует множество способов кодирования ботов Discord. Вы можете кодировать все вручную с помощью вызовов API или использовать существующие простые в использовании библиотеки. Две основные библиотеки:
- discord.js — библиотека JavaScript
- discord.py — библиотека Python
Предварительные условия [discord.py]:
- Установить Питон
- Установите IDE и настройте ее для Python. Я лично использую Visual Studio Code
- Установите discord.py с помощью PIP:
#Linux/macOS: python3 -m pip install -U discord.py #Windows: py -3 -m pip install -U discord.py
АЛЬТЕРНАТИВНЫЙ ВАРИАНТ [Включает голосовую поддержку]:
#Linux/macOS: python3 -m pip install -U "discord.py[voice]" #Windows: py -3 -m pip install -U discord.py[voice]
- Создайте новый файл: yourBotName.py (или предпочитаемое вами соглашение об именах).
Теперь пришло время заняться программированием!
Прохождение кода:
Для начала вам сначала нужно импортировать необходимые библиотеки и классы:
import discord, discord.utils from discord import app_commands
Намерения:
Discord использует «намерения», которые в основном представляют собой разрешения для ботов, которые, возможно, потребуется включить в зависимости от того, что вы делаете. Вот несколько примеров наиболее распространенных:
#INTENTS intents = discord.Intents.all() #Grabs default intents intents.members = True #Changes member visibility intent (allows the bot to “see” members) intents.presences = True #Changes presence intent (allows you to set a custom bot presence)
Бот как класс
Хотя это и не обязательно, может быть полезно сделать вашего бота Discord объектом. Вы даже можете использовать иерархию объектов, но базовая реализация класса бота может выглядеть так:
#BOT CLASS class bot(discord.Client): def __init__(self): super().__init__(intents = intents) #Set the bot’s intents self.synced = False #Default synced value async def on_ready(self): #Bot on_ready function await self.wait_until_ready() #Wait until the bot is ready. if not self.synced: await tree.sync(guild = discord.Object(id = your_guild_id)) #EXPLANATION BELOW self.synced = True #Update synced variable self.change_presence(status = discord.Status.online, activity = discord.Game(your_status_message_here)) #Sets custom activity status print("your_bot_name_here is Ready.") #Prints ready message
Типы синхронизации:
Вы заметите, что я указываю одну гильдию в вызове функции tree.sync. Это очень важно для целей тестирования. Discord позволяет запускать либо глобальную синхронизацию, либо отдельную синхронизацию (синхронизируется с одной гильдией). Запуск глобальной синхронизации может занять час или два, прежде чем ее можно будет использовать. При кодировании/тестировании используйте одну гильдию, а при развертывании просто используйте:
await tree.sync()
CommandTree:
Далее вам нужно создать объект бота, а также CommandTree для него:
bot = bot() #Initialize a bot object tree = app_commands.CommandTree(bot) #Initialize a CommandTree
Токен и выполнение.
Наконец, получите свой токен и используйте его для запуска бота.
ПРИМЕЧАНИЕ. Вам нужно перейти в раздел «Бот » в левой колонке веб-портала и нажмите «Сбросить токен». Это токен, который свяжет ваш код с ботом Discord. Не делитесь этим ни с кем!
#RUN YOUR BOT bot.run(your_token_here)
Поздравляем! У вас есть работающий бот! Теперь я объясню, как реализовать некоторые базовые функции!
Важная информация:
Прежде чем я перейду к особенностям «забавного» кода, важно понять, как работают боты Discord. Вот некоторые вещи, которые вы должны знать и/или учитывать, прежде чем добавлять функции в своего бота.
События:
серверы Discord (которые будут перенаправлять на ваш код) прослушивают «события». События — это триггеры, которые заставляют бота каким-то образом реагировать. Хотя их много, наиболее распространенными триггерами, на которые реагируют боты, являются следующие:
- Участник, отправляющий сообщение
- Член, вызывающий команду косой черты
- Ваш бот вступает в новую гильдию
Каждый из этих триггеров запрограммирован по-разному. Для каждого из вышеперечисленных случаев используются следующие декораторы функций и сигнатуры:
#ON MESSAGE EVENTS @bot.event async def on_message(message: discord.Message): ...your functionality here #SLASH COMMAND EVENTS @tree.command(description = "This is a command description!") async def command_name(interaction: discord.Interaction): ...your functionality here #BOT JOINING NEW GUILD EVENTS @bot.event async def on_guild_join(guild: discord.Guild): ...your functionality here
Структура кода:
Имейте в виду, есть только по одной функции on_message и on_guild_join. Команды косой черты будут иметь одну функцию для каждой команды или подкоманды. Это будет зависеть от вас, чтобы реализовать так, как вы хотите.
Хранение данных.
Важно учитывать необходимость хранения данных пользователя или бота и то, как вы можете это сделать. Чтение и запись в текстовые файлы являются опцией, словари облегчат эту задачу. Но проблемы возникнут с требованиями к параллелизму и скорости, если вы масштабируете бота для обработки большего количества пользователей и гильдий.
Самое простое решение — использовать постоянно работающую базу данных. Это может быть размещено с помощью стороннего сервиса или вы можете разместить его самостоятельно на энергоэффективном устройстве, таком как Raspberry Pi или ноутбуке. Существует множество типов баз данных и разновидностей SQL, которые используются в каждой из них. Для собственного производства я использовал Raspberry Pi с MariaDB (облегченный форк MySQL). Это, опять же, зависит от вас, если вам нужно хранить большие объемы данных для вашего бота.
Слеш-команды:
Теперь, когда вы обдумали, как вы хотите вызывать свою функциональность и где хранить потенциальные результаты, позвольте мне объяснить, как работают слеш-команды.
Команды косой черты используют декоратор your_tree_name.command() над декораторами необязательных разрешений, а затем имеют подпись в формате:
#BASIC SIGNATURE async def command_name(interaction: discord.Interaction, parameters...):
Параметры:
при необходимости вы можете включить дополнительные параметры, которые необходимо указать, когда пользователь вызывает команду. Примитивные типы данных говорят сами за себя, но одной из основных функций, по которой я изо всех сил пытался найти документацию, были списки параметров, из которых можно выбирать. Вот несколько примеров распространенных реализаций, которые могут вам понадобиться:
#SIGNATURE WITH SPECIFIC EXAMPLES async def command_name(interaction: discord.Interaction, role: Optional[discord.Role], member: Optional[discord.Member], mode: Literal["Hello", "World"]):
В приведенном выше примере я включил синтаксис для использования опций, выбора ролей и участников и литеральных списков. Существуют и другие классы разногласий, которые вы можете использовать в панелях выбора. Я надеюсь, что этот фрагмент кода будет полезен!
Разрешения [Необязательно]:
Дополнительные декораторы разрешений позволяют вам ограничить, кто может запускать команду. Аргумент должен принимать значение True, чтобы проверка app_command продолжила выполнение. Пример, который я взял с официального сайта discord.py, приведен ниже:
#LAMBDA EVALUATION FUNCTION def check_if_it_is_me(interaction: discord.Interaction) -> bool: return interaction.user.id == 85309593344815104 #Checks user id of invoker against a constant user id #SLASH COMMAND @tree.command() @app_commands.check(check_if_it_is_me) #Variable or called function must be true for command to execute async def only_for_me(interaction: discord.Interaction): await interaction.response.send_message('I know you!', ephemeral = True) #Sends ephemeral response
Ответы:
Важно, чтобы вы всегда включали discord.Interaction в качестве первого параметра, а также понимали, как работают Discord Interactions. Взаимодействия требуют «ответа». Поэтому в какой-то момент в команде вам нужно будет включить ответ на сообщение. Ответ может быть отправлен либо сразу, если ваша команда быстрая, либо, если требуется время на обработку, вам может потребоваться отложить ответ и отреагировать на него позже:
#STANDARD RESPONSE await interaction.response.send_message("I'm a response") #DELAYED RESPONSE await interaction.response.defer() #Defers response await interaction.followup.send("I'm a response") #Follows up with a deferred response
В любом случае бот ответит сообщением после выполнения команды. Ответы обычно должны быть эфемерными (отправляться в виде синего сообщения, которое может видеть только исполнитель). Вы можете просто добавить эфемерный аргумент после вашей строки в функциях send или send_message.
Заканчивать:
Теперь вы добавили команду и готовы запустить/протестировать своего бота! Поздравляю! Если у вас есть дополнительные вопросы, лучше всего начать с Справочника Interactions API; затем онлайн-форумы. Если у вас есть какие-либо дополнительные предложения для будущих статей или правок, дайте мне знать!
Вот несколько общих советов по разработке ботов, основанных на моем опыте разработки:
- Создание второго приложения на портале разработчиков Discord может позволить вам запускать производственный код в одном приложении и одновременно запускать частную сборку в другом. Это необходимо, если вы не хотите, чтобы приложение простояло при разработке.
- Может быть полезно использовать инструмент разработки для переключения между рабочими и тестовыми экземплярами вашего бота.
- Базы данных MySQL проще использовать с помощью MySQL Python Connector, хотя вам все равно может понадобиться собственный контроллер SQL или множество служебных функций.
- Рефакторинг и переработка кода, а также создание дополнительных файлов чрезвычайно важны, поскольку проекты могут быстро расти! Бот, который я все еще разрабатываю, приближается к 2000 строк кода!
Завершенный код:
import discord, discord.utils from discord import app_commands #INTENTS intents = discord.Intents.all() #Grabs default intents intents.members = True #Changes member visibility intent (allows the bot to "see" members) intents.presences = True #Changes presence intent (allows you to set a custom bot presence) #BOT CLASS class bot(discord.Client): #Bot class def __init__(self): super().__init__(intents = intents) #Set the bot's intents self.synced = False #Default synced value async def on_ready(self): #Bot on_ready function await self.wait_until_ready() #Wait until the bot is ready. if not self.synced: await tree.sync(guild = discord.Object(id = your_guild_id)) #EXPLANATION BELOW self.synced = True #Update synced variable self.change_presence(status = discord.Status.online, activity = discord.Game(your_status_message_here)) #Sets custom activity status print("your_bot_name_here is Ready.") #Prints ready message #ON MESSAGE EVENTS @bot.event async def on_message(message: discord.Message): ...your functionality here #SLASH COMMAND EVENTS @tree.command(description = "This is a command description!") async def command_name(interaction: discord.Interaction): await interaction.response.send_message("I'm a response") #SLASH COMMAND EVENTS @tree.command(description = "This is second command's description!") @app_commands.check(check_if_it_is_me) #Variable or called function must be true for command to execute async def second_command_name(interaction: discord.Interaction): await interaction.response.send_message('I know you!', ephemeral = True) #Sends ephemeral response #BOT JOINING NEW GUILD EVENTS @bot.event async def on_guild_join(guild: discord.Guild): ...your functionality here #LAMBDA EVALUATION FUNCTION def check_if_it_is_me(interaction: discord.Interaction) -> bool: return interaction.user.id == 85309593344815104 #Checks user id of invoker against a constant user id #INITIALIZATION bot = bot() #Initialize a bot object tree = app_commands.CommandTree(bot) #Initialize a CommandTree #RUN YOUR BOT bot.run(your_token_here)
Я надеюсь, что вы нашли эту статью краткой и информативной! Спасибо за чтение и удачи в развитии!