import re from discord import AuditLogAction, Member from discord.ext.commands import Bot, Cog from cdbot.constants import ( ADMIN_MENTOR_ROLE_ID, ADMIN_ROLES, CD_BOT_ROLE_ID, NICKNAME_PATTERNS, PLACEHOLDER_NICKNAME, STATIC_NICKNAME_ROLE_ID, ) def check_bad_name(nick): for i in NICKNAME_PATTERNS: if re.match(i, nick, re.IGNORECASE): return True return False class Admin(Cog): """ Admin functionality """ def __init__(self, bot: Bot): self.bot = bot @Cog.listener() # triggered on new/removed nickname async def on_member_update(self, member_before: Member, member_after: Member): # get corresponding audit log entry to find who initiated member change corresponding_audit_entry = None # get all audit log entries for Member Updated async for entry in self.bot.guilds[0].audit_logs( action=AuditLogAction.member_update ): # if this entry was to the user in question, and was this specific nickname change if entry.target == member_before and entry.after.nick == member_after.nick: corresponding_audit_entry = entry print(entry.user) print(entry.user.roles) break if ( corresponding_audit_entry is not None ): # successfully found audit log entry before # user changed their own nickname; ignore if admin/bot changed it admin_role_check = ( corresponding_audit_entry.user.top_role.name in ADMIN_ROLES ) bot_role_check = ( corresponding_audit_entry.user.top_role.id == CD_BOT_ROLE_ID ) mentor_role_check = ( corresponding_audit_entry.user.top_role.id == ADMIN_MENTOR_ROLE_ID ) if not (admin_role_check or bot_role_check or mentor_role_check): for i in member_after.roles: print(i.id) if i.id == STATIC_NICKNAME_ROLE_ID: # user has Static Name role await member_after.edit( nick=member_before.display_name ) # revert nickname return else: # check for bad words new_nickname = member_after.display_name if check_bad_name(new_nickname): # bad display name if not check_bad_name( member_after.name ): # username is okay await member_after.edit(nick=None) # reset nickname else: # assign placeholder nickname await member_after.edit(nick=PLACEHOLDER_NICKNAME) @Cog.listener() # triggered on username change async def on_user_update(self, member_before: Member, member_after: Member): new_username = member_after.name if check_bad_name(new_username): # bad username # assign placeholder nickname await member_after.edit(nick=PLACEHOLDER_NICKNAME) @Cog.listener() async def on_member_join(self, member: Member): username = member.name if check_bad_name(username): # bad username # assign placeholder nickname await member.edit(nick=PLACEHOLDER_NICKNAME) def setup(bot): bot.add_cog(Admin(bot))