async def on_member_ban(self, guild, user): if not await self.guild_has_modlog_config(guild): return logger.debug("ban detected") moderator = reason = note = duration = None await asyncio.sleep(2) entry = await self.fetch_audit_log_entry(BAN, guild, user) if entry: moderator = entry.user duration, reason = self.maybe_duration_from_audit_reason( entry.reason) reason, note = self.maybe_note_from_audit_reason(reason) if moderator == self.bot.user: # action was done by me return elif moderator and moderator.id == 515067662028636170: # Beemo (special support coming soontm) await SmallLogEvent('beemo-ban', guild, user, None).dispatch() return # disable currently-active ban(s) for this user in this guild, if there are any await self.bot.run_in_background( modlog.deactivate_infractions(guild.id, user.id, 'ban')) await LogEvent('ban', guild, user, moderator, reason, note, duration).dispatch()
async def _do_auto_unban(self, guild, user_id, infraction): """Removes a ban from a user without dispatching the modlog event. Used for handling expired bans without creating an infraction. """ infraction_id = infraction.infraction_id # make sure we can actually do this can_unban = guild.me.guild_permissions.ban_members if can_unban: # remove the role try: ban = await guild.fetch_ban(discord.Object(user_id)) user = ban.user await guild.unban(user, reason=f'Ban expired (#{infraction_id})') except discord.NotFound: user = None else: user = None # dispatch the modlog event await SmallLogEvent('ban-expire', guild, user or user_id, infraction_id).dispatch() # even if we don't have any permissions, mark any bans for this user as inactive # so we don't keep trying to unban. await self.bot.run_in_background( modlog.deactivate_infractions(guild.id, user_id, 'ban')) return can_unban
async def _do_auto_unmute(self, guild, user_id, infraction): """Removes a mute from a user without dispatching the modlog event. Used for handling expired mutes without creating an infraction. """ config = await db.get_config(guild) member = await self.bot.get_or_fetch_member(guild, user_id) role = guild.get_role(config.mute_role_id if config else 0) infraction_id = infraction.infraction_id # make sure we can actually do this can_unmute = bool(member) \ and bool(role) \ and guild.me.guild_permissions.manage_roles \ and guild.me.top_role > role if can_unmute: # remove the role await member.remove_roles( role, reason=f'Mute expired (#{infraction_id})') # dispatch the modlog event await SmallLogEvent('mute-expire', guild, member or user_id, infraction_id).dispatch() # even if we don't have any permissions, mark any mutes for this user as inactive # so we don't keep trying to unmute. await self.bot.run_in_background( modlog.deactivate_infractions(guild.id, user_id, 'mute')) return can_unmute
async def _do_unban(self, guild, user, mod, reason, note, audit_reason): """Removes a ban from a user and dispatches the event to the modlog.""" # check to make sure we can actually do this if not guild.me.guild_permissions.ban_members: raise BotMissingPermission('Ban Members') # unban the user await guild.unban(user, reason=audit_reason) # mark any bans for this user as inactive await self.bot.run_in_background( modlog.deactivate_infractions(guild.id, user.id, 'ban')) # dispatch the modlog event and return to the command await LogEvent('unban', guild, user, mod, reason, note, None).dispatch()
async def on_member_unban(self, guild, user): if not await self.guild_has_modlog_config(guild): return logger.debug("unban detected") await asyncio.sleep(2) entry = await self.fetch_audit_log_entry(UNBAN, guild, user) moderator = entry.user reason, note = self.maybe_note_from_audit_reason(entry.reason) if moderator == self.bot.user: # action was done by me return # disable currently-active ban(s) for this user in this guild, if there are any await self.bot.run_in_background( modlog.deactivate_infractions(guild.id, user.id, 'ban')) # dispatch the event await LogEvent('unban', guild, user, moderator, reason, note, None).dispatch()
async def _do_unmute(self, guild, user, mod, reason, note, audit_reason): """Lifts a user's mute and dispatches the event to the modlog.""" config = await db.get_config(guild) member = await self.bot.get_or_fetch_member(guild, user.id) role = guild.get_role(config.mute_role_id if config else 0) # some checks to make sure we can actually do this if not member: raise UserNotInGuild(user) if not role: raise NotConfigured('mute_role') if not guild.me.guild_permissions.manage_roles: raise BotMissingPermission('Manage Roles') if not guild.me.top_role > role: raise BotRoleHierarchyError if await is_server_mod(member): raise ModActionOnMod # remove the role await member.remove_roles(role, reason=audit_reason) # notify the user if the setting is enabled if not config or config.dm_on_infraction: message = format_alert_dm(guild, user, 'unmute', reason=reason) delivered = await try_send(user, message) else: delivered = None # mark any mutes for this user as inactive await self.bot.run_in_background( modlog.deactivate_infractions(guild.id, user.id, 'mute')) # dispatch the modlog event and return to the command await LogEvent('unmute', guild, user, mod, reason, note, None).dispatch() return delivered
async def on_member_update(self, before, after): guild = before.guild if not await self.guild_has_modlog_config(guild): return config = await db.get_config(guild) if not (config and config.mute_role_id): return member = before mute_role = guild.get_role(config.mute_role_id) await asyncio.sleep(2) if mute_role in before.roles and mute_role not in after.roles: # unmute logger.debug("detected unmute") entry = await self.fetch_audit_log_entry( UNMUTE, guild, member, check=lambda e: mute_role in e.before.roles and mute_role not in e.after.roles) if entry.id == self._last_audit_id_cache.get(guild.id): return self._last_audit_id_cache[guild.id] = entry.id moderator = entry.user reason, note = self.maybe_note_from_audit_reason(entry.reason) if moderator == self.bot.user: # action was done by me return # disable currently-active mute(s) for this user in this guild, if there are any await self.bot.run_in_background( modlog.deactivate_infractions(guild.id, member.id, 'mute')) await LogEvent('unmute', guild, member, moderator, reason, note, None).dispatch() elif mute_role in after.roles and mute_role not in before.roles: # mute logger.debug("detected mute") entry = await self.fetch_audit_log_entry( MUTE, guild, member, check=lambda e: mute_role in e.after.roles and mute_role not in e.before.roles) if entry.id == self._last_audit_id_cache.get(guild.id): return self._last_audit_id_cache[guild.id] = entry.id moderator = entry.user duration, reason = self.maybe_duration_from_audit_reason( entry.reason) reason, note = self.maybe_note_from_audit_reason(reason) if moderator == self.bot.user: # action was done by me return # disable currently-active mute(s) for this user in this guild, if there are any await self.bot.run_in_background( modlog.deactivate_infractions(guild.id, member.id, 'mute')) await LogEvent('mute', guild, member, moderator, reason, note, duration).dispatch()