Skip to main content

A lightweight Discord bot library built on the raw Discord API.

Project description

suneord

suneord - библиотека для Discord-ботов на Python, которая работает через сырой Discord API без discord.py, disnake, nextcord и других готовых Discord-обёрток.

Возможности

  • Прямой Discord Gateway + REST.
  • Prefix-команды.
  • Slash-команды.
  • cogs.
  • Embed, Color.
  • MessageContext, SlashContext, ModalContext.
  • Модальные окна.
  • Отдельный Intents API.
  • Moderation-хелперы.

Установка

pip install suneord

Требования:

  • Python 3.12+
  • aiohttp

Быстрый старт

from suneord import Bot

bot = Bot(
    prefix="!",
    status="dnd",
    activity="слежу за сервером",
    case_insensitive=True,
)


@bot.event
async def on_ready():
    print(f"{bot.username} успешно запущен и работает")


@bot.command("p", "пинг", description="Показывает пинг")
async def ping(ctx):
    await ctx.send("Понг!")


@bot.slash_command(name="ping", description="Показывает задержку бота")
async def ping_slash(ctx):
    await ctx.respond(f"Понг! {ctx.latency} мс")


bot.run("TOKEN")

Bot

Создание:

from suneord import Bot

bot = Bot(
    prefix="!",
    status="online",
    activity="работаю",
    case_insensitive=True,
    strip_after_prefix=True,
)

Параметры:

  • prefix - префикс для обычных команд.
  • status - Discord-статус бота.
  • activity - текст активности.
  • case_insensitive - команды без учёта регистра.
  • strip_after_prefix - убирать лишние пробелы после префикса.
  • intents - Intents или int.

Свойства:

  • bot.user
  • bot.username
  • bot.avatar_url
  • bot.mention
  • bot.latency
  • bot.latency_ms
  • bot.commands
  • bot.slash_commands
  • bot.modals
  • bot.intents

Методы:

  • bot.run(token)
  • bot.start(token)
  • bot.close()
  • bot.wait_until_ready()
  • bot.sync_commands()
  • bot.fetch_user(user_id)
  • bot.fetch_member(guild_id, user_id)
  • bot.get_command(name)
  • bot.has_command(name)
  • bot.remove_command(name)
  • bot.add_cog(cog)
  • await bot.add_cog_async(cog)
  • bot.get_cog(name)
  • bot.remove_cog(name)
  • await bot.remove_cog_async(name)
  • bot.add_modal(modal)
  • bot.get_modal(custom_id)
  • bot.remove_modal(custom_id)

Intents

Теперь интенты вынесены в отдельный файл suneord/intents.py.

Использование:

from suneord import Bot, Intents

bot = Bot(
    prefix="!",
    status="dnd",
    activity="слежу за сервером",
    case_insensitive=True,
    intents=Intents.default().add(Intents.GUILD_MEMBERS),
)

Если intents не передать, библиотека сама возьмёт Intents.default(). Поэтому такой код тоже корректен:

bot = Bot(
    prefix="!",
    status="dnd",
    activity="слежу за сервером",
    case_insensitive=True,
)

Полезные методы:

  • Intents.default()
  • Intents.all()
  • Intents.none()
  • Intents.from_names(...)
  • intents.add(...)
  • intents.remove(...)
  • intents.has(...)

События

@bot.event
async def on_ready():
    print(bot.username)

Примеры:

@bot.event
async def on_message(ctx):
    print(ctx.content)


@bot.event
async def on_command(ctx):
    print(ctx.command.name)


@bot.event
async def on_command_error(ctx, error):
    await ctx.send_error(str(error))


@bot.event
async def on_slash_command_error(ctx, error):
    await ctx.send_error(str(error))


@bot.event
async def on_modal_error(ctx, error):
    await ctx.send_error(str(error))

Дополнительные lifecycle-события:

  • on_command_completion
  • on_slash_command_completion
  • on_modal_submit
  • on_modal_completion

Prefix-команды

@bot.command(description="Пинг")
async def ping(ctx):
    await ctx.send("Понг!")

С алиасами:

@bot.command("p", "пинг", description="Пинг")
async def ping(ctx):
    await ctx.send("Понг!")

Или:

@bot.command(aliases=("p", "пинг"))
async def ping(ctx):
    await ctx.send("Понг!")

Поддерживаемые параметры:

  • name
  • description
  • aliases
  • usage
  • cooldown
  • checks
  • hidden
  • enabled

Аргументы prefix-команд парсятся через shlex, поэтому строки в кавычках работают нормально:

!say "привет мир"

Slash-команды

from suneord import OptionType, SlashOption


@bot.slash_command(
    name="avatar",
    description="Показывает аватар",
    options=[
        SlashOption(
            name="user",
            description="Пользователь",
            type=OptionType.USER,
            required=True,
        )
    ],
)
async def avatar(ctx):
    user = ctx.option("user")
    await ctx.respond(f"ID: {user['id']}")

Типы OptionType:

  • STRING
  • INTEGER
  • BOOLEAN
  • USER
  • CHANNEL
  • ROLE
  • MENTIONABLE
  • NUMBER
  • ATTACHMENT

Context API

MessageContext

Свойства:

  • ctx.bot
  • ctx.message
  • ctx.guild_id
  • ctx.channel_id
  • ctx.message_id
  • ctx.author
  • ctx.author_id
  • ctx.author_name
  • ctx.author_mention
  • ctx.content
  • ctx.args
  • ctx.args_text
  • ctx.command
  • ctx.invoked_with
  • ctx.latency
  • ctx.jump_url
  • ctx.channel_mention

Методы:

  • ctx.send(...)
  • ctx.reply(...)
  • ctx.typing()
  • ctx.react("🔥")
  • ctx.pin()
  • ctx.unpin()
  • ctx.edit(...)
  • ctx.delete()
  • ctx.send_success(...)
  • ctx.send_error(...)

SlashContext

Свойства:

  • ctx.bot
  • ctx.interaction
  • ctx.guild_id
  • ctx.channel_id
  • ctx.user
  • ctx.author
  • ctx.author_id
  • ctx.author_name
  • ctx.author_mention
  • ctx.command
  • ctx.command_name
  • ctx.options
  • ctx.latency
  • ctx.channel_mention
  • ctx.responded
  • ctx.deferred

Методы:

  • ctx.option("name")
  • ctx.respond(...)
  • ctx.send(...)
  • ctx.defer(...)
  • ctx.followup(...)
  • ctx.edit_original_response(...)
  • ctx.delete_original_response()
  • ctx.send_success(...)
  • ctx.send_error(...)
  • ctx.show_modal(modal)

ModalContext

Свойства:

  • ctx.bot
  • ctx.interaction
  • ctx.custom_id
  • ctx.options
  • ctx.user
  • ctx.author
  • ctx.author_id
  • ctx.responded
  • ctx.deferred

Методы:

  • ctx.value("field_id")
  • ctx.respond(...)
  • ctx.send(...)
  • ctx.defer(...)
  • ctx.followup(...)
  • ctx.edit_original_response(...)
  • ctx.delete_original_response()
  • ctx.send_success(...)
  • ctx.send_error(...)

Embed

from suneord import Color, Embed

embed = Embed(
    title="Заголовок",
    description="Описание",
    color=Color.BLURPLE,
)
embed.set_author(name="Suneord")
embed.add_field(name="Поле", value="Значение", inline=False)
embed.set_thumbnail(url="https://example.com/avatar.png")
embed.set_image(url="https://example.com/banner.png")
embed.set_footer(text="Footer")
embed.set_timestamp()

Модальные окна

Библиотека поддерживает Discord modals.

Пример:

from suneord import Bot, Modal, TextInput, TextInputStyle

bot = Bot(prefix="!")


@bot.modal(
    custom_id="feedback_modal",
    title="Обратная связь",
    components=[
        TextInput(
            custom_id="feedback_text",
            label="Твой отзыв",
            style=TextInputStyle.PARAGRAPH,
            min_length=5,
            max_length=400,
        )
    ],
)
async def feedback_submit(ctx):
    text = ctx.value("feedback_text")
    await ctx.send_success(f"Спасибо за отзыв:\n{text}")


@bot.slash_command(name="feedback", description="Открыть форму отзыва")
async def feedback(ctx):
    modal = Modal(
        custom_id="feedback_modal",
        title="Обратная связь",
        components=(
            TextInput(
                custom_id="feedback_text",
                label="Твой отзыв",
                style=TextInputStyle.PARAGRAPH,
            ),
        ),
    )
    await ctx.show_modal(modal)

Для cogs доступен отдельный декоратор:

from suneord import Cog, modal, TextInput


class FeedbackCog(Cog):
    @modal(
        custom_id="report_modal",
        title="Жалоба",
        components=[TextInput(custom_id="reason", label="Причина")],
    )
    async def report_submit(self, ctx):
        await ctx.respond(ctx.value("reason"), ephemeral=True)

Moderation API

В библиотеке есть готовые методы:

await bot.kick(guild_id, user_id, reason="Причина")
await bot.ban(guild_id, user_id, reason="Причина", delete_message_seconds=86400)
await bot.unban(guild_id, user_id, reason="Причина")
await bot.mute(guild_id, user_id, minutes=10, reason="Причина")
await bot.unmute(guild_id, user_id, reason="Причина")
await bot.set_nickname(guild_id, user_id, "Новый ник", reason="Причина")
await bot.set_slowmode(channel_id, 10)
deleted = await bot.purge_messages(channel_id, limit=25)

Проверка unmute:

  • bot.unmute(...) теперь сначала проверяет, есть ли у пользователя активный timeout.
  • Если тайм-аута нет, выбрасывается MemberNotMuted.

Пример обработки:

from suneord import MemberNotMuted


@bot.event
async def on_slash_command_error(ctx, error):
    if isinstance(error, MemberNotMuted):
        await ctx.send_error("У этого пользователя нет активного мута.")
        return
    await ctx.send_error(str(error))

Checks и hooks

@bot.check
async def only_guild(ctx):
    return ctx.guild_id is not None


@bot.before_invoke
async def before_any_command(ctx):
    print("before", ctx.command.name)


@bot.after_invoke
async def after_any_command(ctx):
    print("after", ctx.command.name)

Cogs

from suneord import Bot, Cog, command, slash_command

bot = Bot(prefix="!")


class Utility(Cog):
    @Cog.listener()
    async def on_ready(self):
        print(f"{self.bot.username} готов")

    @command("p", "пинг", description="Пинг")
    async def ping(self, ctx):
        await ctx.send("Понг!")

    @slash_command(name="hello", description="Приветствие")
    async def hello(self, ctx):
        await ctx.respond("Привет из cog!")


bot.add_cog(Utility(bot))
bot.run("TOKEN")

Для cog lifecycle доступны:

  • cog_load
  • cog_unload

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

suneord-1.0.1.tar.gz (21.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

suneord-1.0.1-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

File details

Details for the file suneord-1.0.1.tar.gz.

File metadata

  • Download URL: suneord-1.0.1.tar.gz
  • Upload date:
  • Size: 21.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for suneord-1.0.1.tar.gz
Algorithm Hash digest
SHA256 9e7eb65c725793620e207228afb8659c40b6529b3a6ba1b2fe60fd04b147aab8
MD5 ec0c9f0daadbaf7a5801083bd0c016fc
BLAKE2b-256 7d572d87858e3964a0316e6d7ae03f468dd30dc182372bb3611e0f1faf28b6df

See more details on using hashes here.

File details

Details for the file suneord-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: suneord-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 20.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for suneord-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 068e34d4fb32e623c75504d15c954b5fea063bc87a6d5d2dce31d3db11b23e6a
MD5 5c53976aee983e376a049c412eeb7e03
BLAKE2b-256 b26f0419dbf5f645b2e2398b23c17762575550d310ed97101642bbbd8254e366

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page