Добавлена смена никнейма при уходе в AFK
All checks were successful
CI / basic-checks (push) Successful in 51s

This commit is contained in:
2026-03-06 14:25:57 +07:00
parent cc821bc6e8
commit 2c6629f7f9
4 changed files with 74 additions and 0 deletions

View File

@@ -29,6 +29,7 @@ class Bot(commands.Bot):
intents.guilds = True
intents.message_content = True
intents.members = True
intents.presences = True
command_prefix: str = prefix or getattr(settings, "PREFIX", "!")

View File

@@ -20,6 +20,69 @@ class Events(Cog):
self.check_reminders.start()
@Cog.listener()
async def on_presence_update(self, before: discord.Member, after: discord.Member) -> None:
"""
Следим за конкретным пользователем и меняем ник на '[AFK] Ник' при уходе в Idle,
а при возвращении восстанавливаем оригинальный ник.
"""
afk_nickname = getattr(settings, "AFK_NICKNAME", "AFK")
# если статус не изменился — выходим
if before.status == after.status:
return
# словарь для хранения оригинального ника
if not hasattr(self, 'original_nick'):
self.original_nick = {}
# пользователь ушёл в AFK/Idle
if after.status == discord.Status.idle:
# если уже AFK, ничего не делаем
if after.nick and after.nick.startswith(afk_nickname):
return
# сохраняем оригинальный ник
self.original_nick[after.id] = after.nick or after.name
try:
await after.edit(nick=afk_nickname)
logger.info(
text=f"{after} ушёл в AFK, ник изменён",
log_type="PRESENCE",
user=str(after),
)
except discord.Forbidden:
logger.warning(
text=f"Нет прав изменить ник {after}",
log_type="PRESENCE",
)
except discord.HTTPException as e:
logger.error(
text=f"Ошибка смены ника {after}: {e!r}",
log_type="PRESENCE",
)
# пользователь вернулся из AFK
elif before.status == discord.Status.idle and after.status != discord.Status.idle:
original = self.original_nick.get(after.id)
if original:
try:
await after.edit(nick=original)
logger.info(
text=f"{after} вернулся из AFK, ник восстановлен",
log_type="PRESENCE",
user=str(after),
)
del self.original_nick[after.id] # убираем из словаря
except discord.Forbidden:
logger.warning(
text=f"Нет прав вернуть ник {after}",
log_type="PRESENCE",
)
except discord.HTTPException as e:
logger.error(
text=f"Ошибка возврата ника {after}: {e!r}",
log_type="PRESENCE",
)
@Cog.listener()
async def on_ready(self) -> None:
"""
Событие запуска бота.

View File

@@ -41,5 +41,7 @@ class Slash(commands.Cog):
)
async def setup(bot: commands.Bot) -> None:
await bot.add_cog(Slash(bot))

View File

@@ -20,6 +20,7 @@ class _Settings(BaseSettings):
WELCOME_CHANNEL_ID: int = 0
ADMIN_ROLE_NAME: str = "Администратор"
AFK_NICKNAME:str ="AFK"
WARNINGS_FILE: Path = Path("data/warnings.json")
REMINDERS_FILE: Path = Path("data/reminders.json")
@@ -53,6 +54,13 @@ class _Settings(BaseSettings):
raise ValueError(f"LOG_LEVEL должен быть одним из: {', '.join(allowed)}")
return v.lower()
@field_validator("AFK_NICKNAME")
def validate_afk_nickname(cls, v: str) -> str:
# если пустая строка или None, используем дефолт "AFK"
if not v or not v.strip():
return "AFK"
return v.strip()
@field_validator("WARNINGS_FILE", "REMINDERS_FILE", "BLACKLIST_FILE", "LOG_FILE_NAME", mode="before")
def validate_paths(cls, v) -> Optional[Path]:
return Path(v) if isinstance(v, str) else v