Repository: Cog-Creators/Red-DiscordBot

Issue:
[Cleanup] let cleanup show in channel how many messages it deleted for a short while
# Feature request

#### Select the type of feature you are requesting:

- [ ] Cog
- [ ] Command
- [ ] API functionality
- [x] Cog UX improvement

#### Describe your requested feature

EDIT: I'm suggesting this feature as a toggle. 

Currently, messages deleted through cleanup commands gets deleted silently and how many messages it deleted gets logged to console/bot logs. However, in many instances it would be useful if bot displayed how many messages it actually deleted in said channel for a short while (5 seconds or less) before auto-vanishing, so as to inform the person who executed said cleanup command. Below GIF can demonstrate what I'm trying to say:

![unn2zSDxKu](https://user-images.githubusercontent.com/24418520/104428927-0cf3b980-55ab-11eb-957f-faa217436a08.gif)

This could be helpful in many instances, where, people who are managing a discord server as trial mod or helpers with just manage messages perms and don't have access to neither audit logs nor bot's console logs , OR to mods and admins who don't have to keep checking audit logs after using cleanup commands to see how many messages bot actually deleted in said channel, etc etc. It saves time, even by little amount and also makes the cleanup process transparent for them by showing deleted messages count. I also personally believe it improves user experience too in context of using cleanup cog. Just my 26 cents.



Discussion:
+1 from me.
This has already been brought up here https://canary.discord.com/channels/133049272517001216/133049878837329920/775417296277602324, but was rejected outrightly.

Would like this to be implemented as a toggle-able feature
Hmm, having it show for *few* seconds IMO wouldn't be a bad idea, I'm guessing some would still like it to be togglable though.
+0.5 from me, I want more people to share their thoughts on this
Yeah also +0.5 from me. It's not a feature I'd be desperate for, but if there could be a toggle for this then I'm down for it. 
Yeah I meant to suggest this as a toggle. Somehow I missed that part to include in OP. 
+1 from me for this. A toggle settings for it wouldn't be bad to let it show for some seconds.
+1 having feedback on what just happened is always good. If it annoys someone, they can just turn it off.
+0.4...
I am doubtful on using a togglable settings for such a tiny thing, to me, it should be either, we show how many messages were deleted and then self-destruct the message, or simply stay shut, the Org should decide of what decision to do. But otherwise, I'm good with the suggestion.
A parameter could be used in the commands, probably to True by default, I don't see any problem in making it the default option.

Resolving patch:
diff --git a/redbot/cogs/cleanup/cleanup.py b/redbot/cogs/cleanup/cleanup.py
--- a/redbot/cogs/cleanup/cleanup.py
+++ b/redbot/cogs/cleanup/cleanup.py
@@ -5,7 +5,7 @@
 import discord
 
 from redbot.cogs.mod.converters import RawUserIds
-from redbot.core import checks, commands
+from redbot.core import checks, commands, Config
 from redbot.core.bot import Red
 from redbot.core.i18n import Translator, cog_i18n
 from redbot.core.utils.chat_formatting import humanize_number
@@ -33,6 +33,8 @@ class Cleanup(commands.Cog):
     def __init__(self, bot: Red):
         super().__init__()
         self.bot = bot
+        self.config = Config.get_conf(self, 8927348724, force_registration=True)
+        self.config.register_guild(notify=True)
 
     async def red_delete_data_for_user(self, **kwargs):
         """ Nothing to delete """
@@ -72,7 +74,7 @@ async def check_100_plus(ctx: commands.Context, number: int) -> bool:
     @staticmethod
     async def get_messages_for_deletion(
         *,
-        channel: discord.TextChannel,
+        channel: Union[discord.TextChannel, discord.DMChannel],
         number: Optional[PositiveInt] = None,
         check: Callable[[discord.Message], bool] = lambda x: True,
         limit: Optional[PositiveInt] = None,
@@ -123,6 +125,27 @@ def message_filter(message):
 
         return collected
 
+    async def send_optional_notification(
+        self,
+        num: int,
+        channel: Union[discord.TextChannel, discord.DMChannel],
+        *,
+        subtract_invoking: bool = False,
+    ) -> None:
+        """
+        Sends a notification to the channel that a certain number of messages have been deleted.
+        """
+        if not hasattr(channel, "guild") or await self.config.guild(channel.guild).notify():
+            if subtract_invoking:
+                num -= 1
+            if num == 1:
+                await channel.send(_("1 message was deleted."), delete_after=5)
+            else:
+                await channel.send(
+                    _("{num} messages were deleted.").format(num=humanize_number(num)),
+                    delete_after=5,
+                )
+
     @staticmethod
     async def get_message_from_reference(
         channel: discord.TextChannel, reference: discord.MessageReference
@@ -199,6 +222,7 @@ def check(m):
         log.info(reason)
 
         await mass_purge(to_delete, channel)
+        await self.send_optional_notification(len(to_delete), channel, subtract_invoking=True)
 
     @cleanup.command()
     @commands.guild_only()
@@ -269,6 +293,7 @@ def check(m):
         log.info(reason)
 
         await mass_purge(to_delete, channel)
+        await self.send_optional_notification(len(to_delete), channel, subtract_invoking=True)
 
     @cleanup.command()
     @commands.guild_only()
@@ -321,6 +346,7 @@ async def after(
         log.info(reason)
 
         await mass_purge(to_delete, channel)
+        await self.send_optional_notification(len(to_delete), channel)
 
     @cleanup.command()
     @commands.guild_only()
@@ -376,6 +402,7 @@ async def before(
         log.info(reason)
 
         await mass_purge(to_delete, channel)
+        await self.send_optional_notification(len(to_delete), channel, subtract_invoking=True)
 
     @cleanup.command()
     @commands.guild_only()
@@ -428,6 +455,7 @@ async def between(
         log.info(reason)
 
         await mass_purge(to_delete, channel)
+        await self.send_optional_notification(len(to_delete), channel, subtract_invoking=True)
 
     @cleanup.command()
     @commands.guild_only()
@@ -466,6 +494,7 @@ async def messages(
         log.info(reason)
 
         await mass_purge(to_delete, channel)
+        await self.send_optional_notification(len(to_delete), channel, subtract_invoking=True)
 
     @cleanup.command(name="bot")
     @commands.guild_only()
@@ -552,6 +581,7 @@ def check(m):
         log.info(reason)
 
         await mass_purge(to_delete, channel)
+        await self.send_optional_notification(len(to_delete), channel, subtract_invoking=True)
 
     @cleanup.command(name="self")
     @check_self_permissions()
@@ -640,6 +670,9 @@ def check(m):
             await mass_purge(to_delete, channel)
         else:
             await slow_deletion(to_delete)
+        await self.send_optional_notification(
+            len(to_delete), channel, subtract_invoking=can_mass_purge
+        )
 
     @cleanup.command(name="duplicates", aliases=["spam"])
     @commands.guild_only()
@@ -690,3 +723,21 @@ def check(m):
 
         to_delete.append(ctx.message)
         await mass_purge(to_delete, ctx.channel)
+        await self.send_optional_notification(len(to_delete), ctx.channel, subtract_invoking=True)
+
+    @commands.group()
+    @commands.admin_or_permissions(manage_messages=True)
+    async def cleanupset(self, ctx: commands.Context):
+        """Manage the settings for the cleanup command."""
+        pass
+
+    @cleanupset.command(name="notify")
+    async def cleanupset_notify(self, ctx: commands.Context):
+        """Toggle clean up notification settings."""
+        toggle = await self.config.guild(ctx.guild).notify()
+        if toggle:
+            await self.config.guild(ctx.guild).notify.set(False)
+            await ctx.send(_("I will no longer notify of message deletions."))
+        else:
+            await self.config.guild(ctx.guild).notify.set(True)
+            await ctx.send(_("I will now notify of message deletions."))


Test patch: