forked from NotFate/bot
Добавлена смена никнейма при уходе в AFK
This commit is contained in:
@@ -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", "!")
|
||||
|
||||
|
||||
@@ -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:
|
||||
"""
|
||||
Событие запуска бота.
|
||||
|
||||
@@ -41,5 +41,7 @@ class Slash(commands.Cog):
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot) -> None:
|
||||
await bot.add_cog(Slash(bot))
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user