diff --git a/redbot/cogs/cleanup/cleanup.py b/redbot/cogs/cleanup/cleanup.py index 74ff35790..a406e7e9e 100644 --- a/redbot/cogs/cleanup/cleanup.py +++ b/redbot/cogs/cleanup/cleanup.py @@ -63,6 +63,7 @@ class Cleanup(commands.Cog): channel: discord.TextChannel, number: int = None, check: Callable[[discord.Message], bool] = lambda x: True, + limit: int = None, before: Union[discord.Message, datetime] = None, after: Union[discord.Message, datetime] = None, delete_pinned: bool = False, @@ -99,7 +100,7 @@ class Cleanup(commands.Cog): collected = [] async for message in channel.history( - limit=None, before=before, after=after, oldest_first=False + limit=limit, before=before, after=after, oldest_first=False ): if message.created_at < two_weeks_ago: break @@ -541,3 +542,46 @@ class Cleanup(commands.Cog): await mass_purge(to_delete, channel) else: await slow_deletion(to_delete) + + @cleanup.command(name="spam") + @commands.guild_only() + @commands.bot_has_permissions(manage_messages=True) + async def cleanup_spam(self, ctx: commands.Context, number: int = 50): + """Deletes duplicate messages in the channel from the last X messages and keeps only one copy. + + Defaults to 50. + """ + msgs = [] + spam = [] + + def check(m): + if m.attachments: + return False + c = (m.author.id, m.content, [e.to_dict() for e in m.embeds]) + if c in msgs: + spam.append(m) + return True + else: + msgs.append(c) + return False + + to_delete = await self.get_messages_for_deletion( + channel=ctx.channel, limit=number, check=check, before=ctx.message, + ) + + if len(to_delete) > 100: + cont = await self.check_100_plus(ctx, len(to_delete)) + if not cont: + return + + log.info( + "%s (%s) deleted %s spam messages in channel %s (%s).", + ctx.author, + ctx.author.id, + len(to_delete), + ctx.channel, + ctx.channel.id, + ) + + to_delete.append(ctx.message) + await mass_purge(to_delete, ctx.channel)