Allow enforcing reason to be filled in Mod cog commands (#6477)

Co-authored-by: Jakub Kuczys <me@jacken.men>
This commit is contained in:
Kevin Wang 2024-12-23 19:58:57 -05:00 committed by GitHub
parent f0a29e9815
commit 9419f2642a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 81 additions and 0 deletions

View File

@ -266,6 +266,28 @@ and reason as to why they were kicked/banned.
* ``[enabled]``: Whether a message should be sent to a user when they are kicked/banned. |bool-input| * ``[enabled]``: Whether a message should be sent to a user when they are kicked/banned. |bool-input|
.. _mod-command-modset-requirereason:
""""""""""""""""""""
modset requirereason
""""""""""""""""""""
**Syntax**
.. code-block:: none
[p]modset requirereason [enabled]
**Description**
Toggle whether a reason is required for mod actions.
If this is enabled, the bot will require a reason to be provided for all mod actions.
**Arguments**
* ``[enabled]``: Whether a reason should be required when performing mod actions. |bool-input|
.. _mod-command-modset-hierarchy: .. _mod-command-modset-hierarchy:
"""""""""""""""" """"""""""""""""

View File

@ -117,6 +117,9 @@ class KickBanMixin(MixinMeta):
removed_temp = False removed_temp = False
if reason is None and await self.config.guild(guild).require_reason():
return False, _("You must provide a reason for the ban.")
if not (0 <= days <= 7): if not (0 <= days <= 7):
return False, _("Invalid days. Must be between 0 and 7.") return False, _("Invalid days. Must be between 0 and 7.")
@ -303,6 +306,10 @@ class KickBanMixin(MixinMeta):
author = ctx.author author = ctx.author
guild = ctx.guild guild = ctx.guild
if reason is None and await self.config.guild(guild).require_reason():
await ctx.send(_("You must provide a reason for the kick."))
return
if author == member: if author == member:
await ctx.send( await ctx.send(
_("I cannot let you do that. Self-harm is bad {emoji}").format( _("I cannot let you do that. Self-harm is bad {emoji}").format(
@ -428,6 +435,10 @@ class KickBanMixin(MixinMeta):
errors = {} errors = {}
upgrades = [] upgrades = []
if reason is None and await self.config.guild(ctx.guild).require_reason():
await ctx.send(_("You must provide a reason for the massban."))
return
async def show_results(): async def show_results():
text = _("Banned {num} users from the server.").format( text = _("Banned {num} users from the server.").format(
num=humanize_number(len(banned)) num=humanize_number(len(banned))
@ -605,6 +616,10 @@ class KickBanMixin(MixinMeta):
guild = ctx.guild guild = ctx.guild
author = ctx.author author = ctx.author
if reason is None and await self.config.guild(guild).require_reason():
await ctx.send(_("You must provide a reason for the temporary ban."))
return
if author == member: if author == member:
await ctx.send( await ctx.send(
_("I cannot let you do that. Self-harm is bad {}").format("\N{PENSIVE FACE}") _("I cannot let you do that. Self-harm is bad {}").format("\N{PENSIVE FACE}")
@ -684,6 +699,10 @@ class KickBanMixin(MixinMeta):
guild = ctx.guild guild = ctx.guild
author = ctx.author author = ctx.author
if reason is None and await self.config.guild(guild).require_reason():
await ctx.send(_("You must provide a reason for the softban."))
return
if author == member: if author == member:
await ctx.send( await ctx.send(
_("I cannot let you do that. Self-harm is bad {emoji}").format( _("I cannot let you do that. Self-harm is bad {emoji}").format(
@ -771,6 +790,10 @@ class KickBanMixin(MixinMeta):
self, ctx: commands.Context, member: discord.Member, *, reason: str = None self, ctx: commands.Context, member: discord.Member, *, reason: str = None
): ):
"""Kick a member from a voice channel.""" """Kick a member from a voice channel."""
if reason is None and await self.config.guild(ctx.guild).require_reason():
await ctx.send(_("You must provide a reason for the voice kick."))
return
author = ctx.author author = ctx.author
guild = ctx.guild guild = ctx.guild
user_voice_state: discord.VoiceState = member.voice user_voice_state: discord.VoiceState = member.voice
@ -818,6 +841,10 @@ class KickBanMixin(MixinMeta):
self, ctx: commands.Context, member: discord.Member, *, reason: str = None self, ctx: commands.Context, member: discord.Member, *, reason: str = None
): ):
"""Unban a user from speaking and listening in the server's voice channels.""" """Unban a user from speaking and listening in the server's voice channels."""
if reason is None and await self.config.guild(ctx.guild).require_reason():
await ctx.send(_("You must provide a reason for the voice unban."))
return
user_voice_state = member.voice user_voice_state = member.voice
if ( if (
await self._voice_perm_check( await self._voice_perm_check(
@ -859,6 +886,10 @@ class KickBanMixin(MixinMeta):
@commands.admin_or_permissions(mute_members=True, deafen_members=True) @commands.admin_or_permissions(mute_members=True, deafen_members=True)
async def voiceban(self, ctx: commands.Context, member: discord.Member, *, reason: str = None): async def voiceban(self, ctx: commands.Context, member: discord.Member, *, reason: str = None):
"""Ban a user from speaking and listening in the server's voice channels.""" """Ban a user from speaking and listening in the server's voice channels."""
if reason is None and await self.config.guild(ctx.guild).require_reason():
await ctx.send(_("You must provide a reason for the voice ban."))
return
user_voice_state: discord.VoiceState = member.voice user_voice_state: discord.VoiceState = member.voice
if ( if (
await self._voice_perm_check( await self._voice_perm_check(
@ -908,6 +939,10 @@ class KickBanMixin(MixinMeta):
1. Copy it from the mod log case (if one was created), or 1. Copy it from the mod log case (if one was created), or
2. Enable Developer Mode, go to Bans in this server's settings, right-click the user and select 'Copy ID'. 2. Enable Developer Mode, go to Bans in this server's settings, right-click the user and select 'Copy ID'.
""" """
if reason is None and await self.config.guild(ctx.guild).require_reason():
await ctx.send(_("You must provide a reason for the unban."))
return
guild = ctx.guild guild = ctx.guild
author = ctx.author author = ctx.author
audit_reason = get_audit_reason(ctx.author, reason, shorten=True) audit_reason = get_audit_reason(ctx.author, reason, shorten=True)

View File

@ -57,6 +57,7 @@ class Mod(
"reinvite_on_unban": False, "reinvite_on_unban": False,
"current_tempbans": [], "current_tempbans": [],
"dm_on_kickban": False, "dm_on_kickban": False,
"require_reason": False,
"default_days": 0, "default_days": 0,
"default_tempban_duration": 60 * 60 * 24, "default_tempban_duration": 60 * 60 * 24,
"track_nicknames": True, "track_nicknames": True,

View File

@ -370,6 +370,29 @@ class ModSettings(MixinMeta):
_("Bot will no longer attempt to send a DM to user before kick and ban.") _("Bot will no longer attempt to send a DM to user before kick and ban.")
) )
@modset.command()
@commands.guild_only()
async def requirereason(self, ctx: commands.Context, enabled: bool = None):
"""
Toggle whether a reason is required for mod actions.
If this is enabled, the bot will require a reason to be provided for all mod actions.
"""
guild = ctx.guild
if enabled is None:
setting = await self.config.guild(guild).require_reason()
await ctx.send(
_("Mod action reason requirement is currently set to: {setting}").format(
setting=setting
)
)
return
await self.config.guild(guild).require_reason.set(enabled)
if enabled:
await ctx.send(_("Bot will now require a reason for all mod actions."))
else:
await ctx.send(_("Bot will no longer require a reason for all mod actions."))
@modset.command() @modset.command()
@commands.guild_only() @commands.guild_only()
async def defaultdays(self, ctx: commands.Context, days: int = 0): async def defaultdays(self, ctx: commands.Context, days: int = 0):