Создаём бота для Discord на Python: от основ до продвинутых приёмов

Раздел: Веб-разработка -> Создание ботов

Создание Discord бота на Python: обзор библиотек и решений

Как создать базового Discord бота на Python, который отвечает на сообщения?

Наиболее эффективный способ - использование библиотеки discord.py. Эта асинхронная библиотека предоставляет всю необходимую функциональность для взаимодействия с API Discord, включая обработку команд, событий, управление голосовыми каналами и слеш-командами. Рассмотрим минимальный пример.

import discord
from discord.ext import commands

intents = discord.Intents.default()
intents.message_content = True

bot = commands.Bot(command_prefix='!', intents=intents)

@bot.event
async def on_ready():
    print(f'Бот {bot.user} готов!')

@bot.command()
async def привет(ctx):
    await ctx.send('Привет, {ctx.author.mention}!')

bot.run('YOUR_BOT_TOKEN')

библиотека бота python (библиотека для создания ботов на python)

Пояснения:

  • Импортируются необходимые классы: discord и commands.
  • Настраиваются интенты (intents) - обязательное требование с версии 2.0. В данном случае включён message_content для чтения содержимого сообщений.
  • Создаётся экземпляр commands.Bot с префиксом команд (!) и указанными интентами.
  • Декоратор @bot.event позволяет слушать события, например on_ready - вызывается после успешного подключения бота.
  • Декоратор @bot.command() регистрирует текстовую команду !привет.
  • В конце вызывается bot.run() с токеном бота, полученным на Discord Developer Portal.

Как использовать слеш-команды (slash commands) вместо текстовых?

Слеш-команды - современный стандарт. Для их реализации в discord.py используется discord.app_commands. Пример:

import discord
from discord import app_commands

class MyClient(discord.Client):
    def __init__(self):
        intents = discord.Intents.default()
        super().__init__(intents=intents)
        self.tree = app_commands.CommandTree(self)

    async def on_ready(self):
        await self.tree.sync()
        print(f'Бот {self.user} готов!')

client = MyClient()

@client.tree.command()
async def тест(interaction: discord.Interaction):
    await interaction.response.send_message('Это слеш-команда!')

client.run('TOKEN')

Python discord py (создание discord бота на python)

Ключевое отличие: команда регистрируется через @client.tree.command(), а ответ отправляется через interaction.response. После запуска бот синхронизирует команды с Discord.

Как структурировать бота с помощью когов (Cogs)?

Коги позволяют разбить код на логические модули. Пример кога:

# cog_example.py
import discord
from discord.ext import commands

class Пример(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.command()
    async def ping(self, ctx):
        await ctx.send('Понг!')

async def setup(bot):
    await bot.add_cog(Пример(bot))

Python vk py (использование vk api с python)

Загрузка в основном файле:

bot = commands.Bot(command_prefix='!', intents=...)
await bot.load_extension('cog_example')
bot.run('TOKEN')

Какие альтернативы discord.py существуют?

Основные альтернативы:

  • py-cord - форк discord.py с улучшенной поддержкой слеш-команд, кнопок и модальных окон. Пример почти идентичен, но команды регистрируются через @bot.slash_command() или @bot.command().
  • disnake - ещё один форк, активно поддерживается, включает полный набор современных фич.
  • discum - библиотека для работы с пропущенными событиями и без асинхронности, но она менее популярна.

Выбор зависит от потребностей: если нужна стабильность и поддержка старых методов - discord.py; для самых свежих возможностей (кнопки, модалки, селект-меню) лучше py-cord или disnake.

Типичные ошибки и их решения:

  • Missing Access - бот не имеет прав на просмотр или отправку сообщений. Решение: выдайте боту роль с нужными разрешениями или используйте OAuth2 URL с правильными scope.
  • 401: Unauthorized - неверный токен. Проверьте, что токен скопирован без пробелов.
  • prerequisites not satisfied - не установлена библиотека. Установите: pip install discord.py.
  • on_ready не срабатывает - убедитесь, что интенты включены на портале разработчика и в коде.
  • Rate limit (429) - слишком много запросов. Добавьте задержки между командами или используйте Bucket в когах.

Расширенные примеры использования Discord бота

Ниже приведены более сложные сценарии с подробными пояснениями и ожидаемым результатом.

Пример
# Пример: эмбед с информацией о пользователе
import discord
from discord.ext import commands

bot = commands.Bot(command_prefix='!', intents=discord.Intents.all())

@bot.command()
async def userinfo(ctx, member: discord.Member = None):
    member = member or ctx.author
    embed = discord.Embed(
        title=f'Информация о {member.display_name}',
        colour=discord.Colour.blue()
    )
    embed.set_thumbnail(url=member.avatar.url)
    embed.add_field(name='ID', value=member.id, inline=True)
    embed.add_field(name='Присоединился', value=member.joined_at.strftime('%d.%m.%Y %H:%M'), inline=True)
    embed.add_field(name='Зарегистрировался', value=member.created_at.strftime('%d.%m.%Y %H:%M'), inline=True)
    await ctx.send(embed=embed)

bot.run('TOKEN')
# Ожидаемый вывод: бот отправляет Embed с информацией о пользователе.

Пояснение: discord.Embed создаёт встроенное сообщение с полями. Конвертер типа discord.Member автоматически получает объект участника по упоминанию или ID.

Пример
# Пример: реакция на добавление реакции
@bot.event
async def on_raw_reaction_add(payload):
    channel = bot.get_channel(payload.channel_id)
    message = await channel.fetch_message(payload.message_id)
    user = payload.member
    if str(payload.emoji) == '✅':
        await message.channel.send(f'{user.mention} подтвердил!')
    elif str(payload.emoji) == '❌':
        await message.delete()
        await user.send('Сообщение удалено из-за реакции.')

Используется событие on_raw_reaction_add, которое работает даже для сообщений, не находящихся в кэше.

Пример
# Пример: голосовой канал - подключение и отключение
@bot.command()
async def join(ctx):
    if ctx.author.voice:
        channel = ctx.author.voice.channel
        await channel.connect()
        await ctx.send(f'Подключился к {channel.name}')
    else:
        await ctx.send('Вы не находитесь в голосовом канале.')

@bot.command()
async def leave(ctx):
    if ctx.voice_client:
        await ctx.voice_client.disconnect()
        await ctx.send('Отключился от голосового канала.')
    else:
        await ctx.send('Бот не в голосовом канале.')

Для работы с голосом требуется установить ffmpeg (если планируется воспроизведение аудио).

Пример
# Пример: слеш-команда с option (аргументом) через py-cord
import discord
from discord.ext import commands

bot = commands.Bot(command_prefix='!', intents=discord.Intents.default())

@bot.slash_command(name='say', description='Повторяет введённый текст')
async def say(ctx: discord.ApplicationContext, text: discord.Option(str, 'Текст для повтора')):
    await ctx.respond(f'{text}')

bot.run('TOKEN')
# Результат: при вводе /say Привет! бот отвечает 'Привет!'

py-cord упрощает создание слеш-команд с использованием декоратора @bot.slash_command.

Создание Discord бота на Python - comments

En
Python discord py (python)