From d9e6a81dac41a8b3230b6224147e07be632b891f Mon Sep 17 00:00:00 2001 From: Whyverum Date: Mon, 8 Dec 2025 16:46:58 +0700 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=BE=D0=B4=20=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D1=87=D0=B8=D0=BA=20=D1=81=D0=BE=D0=B1=D1=8B?= =?UTF-8?q?=D1=82=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot/cogs/events.py | 129 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 bot/cogs/events.py diff --git a/bot/cogs/events.py b/bot/cogs/events.py new file mode 100644 index 0000000..3d2fded --- /dev/null +++ b/bot/cogs/events.py @@ -0,0 +1,129 @@ +import datetime + +import discord +from discord.ext import commands, tasks +from discord.utils import get + +from configs import settings +from middleware import logger +from ..storage import storage, Reminder + + +class Events(commands.Cog): + """ + Cog с обработчиками событий и фоновой задачей напоминаний. + """ + + def __init__(self, bot: commands.Bot) -> None: + self.bot: commands.Bot = bot + self.check_reminders.start() + + @commands.Cog.listener() + async def on_ready(self) -> None: + """ + Событие запуска бота. + Загружает данные и создаёт необходимые роли. + """ + logger.info(text=f"Бот запущен как {self.bot.user}") + storage.load_all() + await self.ensure_roles_exist() + + @commands.Cog.listener() + async def on_member_join(self, member: discord.Member) -> None: + """ + Событие вступления нового участника на сервер. + + :param member: Новый участник. + """ + new_member_role: discord.Role | None = get(member.guild.roles, name="New Member") + if new_member_role: + await member.add_roles(new_member_role) + + channel: discord.abc.MessageableChannel | None = self.bot.get_channel( + settings.WELCOME_CHANNEL_ID + ) + if isinstance(channel, discord.TextChannel): + await channel.send(f"Приветствуем {member.mention} на сервере!") + + @commands.Cog.listener() + async def on_message(self, message: discord.Message) -> None: + """ + Событие получения сообщения. Проверяет чёрный список слов. + + :param message: Полученное сообщение. + """ + if message.author.bot or not message.content: + return + + msg_lower: str = message.content.lower() + if any(word in msg_lower for word in storage.blacklist): + try: + await message.delete() + await message.channel.send( + f"{message.author.mention}, ваше сообщение содержит запрещённые слова." + ) + except Exception: + pass + return + + await self.bot.process_commands(message) + + async def ensure_roles_exist(self) -> None: + """ + Проверяет наличие ролей Muted и New Member и создаёт их при необходимости. + """ + for guild in self.bot.guilds: + muted_role: discord.Role | None = get(guild.roles, name="Muted") + if muted_role is None: + try: + muted_role = await guild.create_role(name="Muted") + for channel in guild.channels: + await channel.set_permissions( + muted_role, send_messages=False, speak=False + ) + except Exception: + pass + + new_member_role: discord.Role | None = get(guild.roles, name="New Member") + if new_member_role is None: + try: + await guild.create_role(name="New Member") + except Exception: + pass + + @tasks.loop(seconds=30) + async def check_reminders(self) -> None: + """ + Фоновая задача, которая каждые 30 секунд проверяет напоминания + и отправляет просроченные. + """ + now: float = datetime.datetime.now().timestamp() + to_remove: list[Reminder] = [] + + for rem in storage.reminders: + if rem.time <= now: + channel = self.bot.get_channel(rem.channel_id) + if isinstance(channel, discord.TextChannel): + await channel.send(f"{rem.user_mention} Напоминание: {rem.text}") + to_remove.append(rem) + + if to_remove: + for rem in to_remove: + storage.reminders.remove(rem) + storage.save_reminders() + + @check_reminders.before_loop + async def before_check_reminders(self) -> None: + """ + Ожидание готовности бота перед стартом фоновой задачи. + """ + await self.bot.wait_until_ready() + + +async def setup(bot: commands.Bot) -> None: + """ + Функция для загрузки Cog. + + :param bot: Экземпляр бота. + """ + await bot.add_cog(Events(bot))