diff --git a/changelog.d/mod/2990.enhance.rst b/changelog.d/mod/2990.enhance.rst new file mode 100644 index 000000000..e27d9caa3 --- /dev/null +++ b/changelog.d/mod/2990.enhance.rst @@ -0,0 +1 @@ +Added a ``[p]modset dm`` to toggle kick/bans sending an embed to the user detailing the reason for the kick/ban, the server they were kicked/banned from and if it was a kick or a ban. diff --git a/redbot/cogs/mod/kickban.py b/redbot/cogs/mod/kickban.py index 4ee1560ae..b9ce3532a 100644 --- a/redbot/cogs/mod/kickban.py +++ b/redbot/cogs/mod/kickban.py @@ -7,7 +7,7 @@ from typing import cast, Optional, Union import discord from redbot.core import commands, i18n, checks, modlog -from redbot.core.utils.chat_formatting import pagify, humanize_number +from redbot.core.utils.chat_formatting import pagify, humanize_number, bold from redbot.core.utils.mod import is_allowed_by_hierarchy, get_audit_reason from .abc import MixinMeta from .converters import RawUserIds @@ -82,6 +82,19 @@ class KickBanMixin(MixinMeta): elif not (0 <= days <= 7): return _("Invalid days. Must be between 0 and 7.") + toggle = await self.settings.guild(guild).dm_on_kickban() + if toggle: + with contextlib.suppress(discord.HTTPException): + em = discord.Embed( + title=bold(_("You have been banned from {guild}.").format(guild=guild)) + ) + em.add_field( + name=_("**Reason**"), + value=reason if reason is not None else _("No reason was given."), + inline=False, + ) + await user.send(embed=em) + audit_reason = get_audit_reason(author, reason) queue_entry = (guild.id, user.id) @@ -186,6 +199,18 @@ class KickBanMixin(MixinMeta): await ctx.send(_("I cannot do that due to discord hierarchy rules")) return audit_reason = get_audit_reason(author, reason) + toggle = await self.settings.guild(guild).dm_on_kickban() + if toggle: + with contextlib.suppress(discord.HTTPException): + em = discord.Embed( + title=bold(_("You have been kicked from {guild}.").format(guild=guild)) + ) + em.add_field( + name=_("**Reason**"), + value=reason if reason is not None else _("No reason was given."), + inline=False, + ) + await user.send(embed=em) try: await guild.kick(user, reason=audit_reason) log.info("{}({}) kicked {}({})".format(author.name, author.id, user.name, user.id)) @@ -225,10 +250,13 @@ class KickBanMixin(MixinMeta): """Ban a user from this server and optionally delete days of messages. If days is not a number, it's treated as the first word of the reason. + Minimum 0 days, maximum 7. If not specified, defaultdays setting will be used instead.""" + author = ctx.author guild = ctx.guild if days is None: days = await self.settings.guild(guild).default_days() + result = await self.ban_user( user=user, ctx=ctx, days=days, reason=reason, create_modlog_case=True ) diff --git a/redbot/cogs/mod/mod.py b/redbot/cogs/mod/mod.py index 37527d2b6..9eaa372c5 100644 --- a/redbot/cogs/mod/mod.py +++ b/redbot/cogs/mod/mod.py @@ -53,6 +53,7 @@ class Mod( "delete_delay": -1, "reinvite_on_unban": False, "current_tempbans": [], + "dm_on_kickban": False, "default_days": 0, } diff --git a/redbot/cogs/mod/settings.py b/redbot/cogs/mod/settings.py index 5de256056..3da4833db 100644 --- a/redbot/cogs/mod/settings.py +++ b/redbot/cogs/mod/settings.py @@ -27,6 +27,7 @@ class ModSettings(MixinMeta): respect_hierarchy = data["respect_hierarchy"] delete_delay = data["delete_delay"] reinvite_on_unban = data["reinvite_on_unban"] + dm_on_kickban = data["dm_on_kickban"] default_days = data["default_days"] msg = "" msg += _("Delete repeats: {num_repeats}\n").format( @@ -50,6 +51,9 @@ class ModSettings(MixinMeta): msg += _("Reinvite on unban: {yes_or_no}\n").format( yes_or_no=_("Yes") if reinvite_on_unban else _("No") ) + msg += _("Send message to users on kick/ban: {yes_or_no}\n").format( + yes_or_no=_("Yes") if dm_on_kickban else _("No") + ) if default_days: msg += _( "Default message history delete on ban: Previous {num_days} days\n" @@ -208,6 +212,30 @@ class ModSettings(MixinMeta): ) ) + @modset.command() + @commands.guild_only() + async def dm(self, ctx: commands.Context, enabled: bool = None): + """Toggle whether to send a message to a user when they are + kicked/banned. + + If this option is enabled, the bot will attempt to DM the user with the guild name + and reason as to why they were kicked/banned. + """ + guild = ctx.guild + if enabled is None: + setting = await self.settings.guild(guild).dm_on_kickban() + await ctx.send( + _("DM when kicked/banned is currently set to: {setting}").format(setting=setting) + ) + return + await self.settings.guild(guild).dm_on_kickban.set(enabled) + if enabled: + await ctx.send(_("Bot will now attempt to send a DM to user before kick and ban.")) + else: + await ctx.send( + _("Bot will no longer attempt to send a DM to user before kick and ban.") + ) + @modset.command() @commands.guild_only() async def defaultdays(self, ctx: commands.Context, days: int = 0):