Repository: Cog-Creators/Red-DiscordBot

Issue:
[V3] Cleanup bot does not clean aliases
# Command bugs

<!-- 
Did you find a bug with a command? Fill out the following:
-->

#### Command name

`[p]cleanup bot`

#### What cog is this command from?

Cleanup

#### What were you expecting to happen?

Cleans command messages (including aliases) and messages from the bot.

#### What actually happened?

It does not delete the alias commands.

#### How can we reproduce this issue?

Create an alias:
`[p]alias add rickroll play https://www.youtube.com/watch?v=dQw4w9WgXcQ`

Call alias:
`[p]rickroll`

Call cleanup:
`[p]cleanup bot 10`

`[p]rickroll` command never gets deleted.


Discussion:
Can confirm that this is a bug.
Note: If the `[p]cleanup bot 10` is called with an alias like `[p]cleanbot`, this alias command is deleted. 
I saw that this issue had no assignees. Just to double check, do you guys want someone to work on this?
@rguan72 Sure, no one is working on it yet as far as I know :)

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
@@ -1,6 +1,6 @@
 import re
 from datetime import datetime, timedelta
-from typing import Union, List, Callable
+from typing import Union, List, Callable, Set
 
 import discord
 
@@ -323,15 +323,35 @@ async def cleanup_bot(self, ctx: commands.Context, number: int, delete_pinned: b
         if "" in prefixes:
             prefixes.remove("")
 
+        cc_cog = self.bot.get_cog("CustomCommands")
+        if cc_cog is not None:
+            command_names: Set[str] = await cc_cog.get_command_names(ctx.guild)
+            is_cc = lambda name: name in command_names
+        else:
+            is_cc = lambda name: False
+        alias_cog = self.bot.get_cog("Alias")
+        if alias_cog is not None:
+            alias_names: Set[str] = (
+                set((a.name for a in await alias_cog.unloaded_global_aliases()))
+                | set(a.name for a in await alias_cog.unloaded_aliases(ctx.guild))
+            )
+            is_alias = lambda name: name in alias_names
+        else:
+            is_alias = lambda name: False
+
+        bot_id = self.bot.user.id
+
         def check(m):
-            if m.author.id == self.bot.user.id:
+            if m.author.id == bot_id:
                 return True
             elif m == ctx.message:
                 return True
             p = discord.utils.find(m.content.startswith, prefixes)
             if p and len(p) > 0:
                 cmd_name = m.content[len(p) :].split(" ")[0]
-                return bool(self.bot.get_command(cmd_name))
+                return (
+                    bool(self.bot.get_command(cmd_name)) or is_alias(cmd_name) or is_cc(cmd_name)
+                )
             return False
 
         to_delete = await self.get_messages_for_deletion(
diff --git a/redbot/cogs/customcom/customcom.py b/redbot/cogs/customcom/customcom.py
--- a/redbot/cogs/customcom/customcom.py
+++ b/redbot/cogs/customcom/customcom.py
@@ -3,7 +3,7 @@
 from datetime import datetime, timedelta
 from inspect import Parameter
 from collections import OrderedDict
-from typing import Mapping, Tuple, Dict
+from typing import Mapping, Tuple, Dict, Set
 
 import discord
 
@@ -553,3 +553,14 @@ def transform_parameter(result, message) -> str:
         else:
             return raw_result
         return str(getattr(first, second, raw_result))
+
+    async def get_command_names(self, guild: discord.Guild) -> Set[str]:
+        """Get all custom command names in a guild.
+
+        Returns
+        --------
+        Set[str]
+            A set of all custom command names.
+
+        """
+        return set(await CommandObj.get_commands(self.config.guild(guild)))


Test patch: