From ceef217b099c593c991ca2e8367bf62566b0f2d0 Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Fri, 22 Nov 2024 21:54:34 -0800 Subject: [PATCH] Close Support: add a task to close out old threads periodically (#111) --- cogs/close_support.py | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/cogs/close_support.py b/cogs/close_support.py index ea96378..3dba7a3 100755 --- a/cogs/close_support.py +++ b/cogs/close_support.py @@ -1,11 +1,13 @@ """Discord Cog to close support threads.""" import asyncio +import datetime import logging import discord import prometheus_client # type: ignore from discord.ext import commands +from discord.ext import tasks from cogs import base_cog @@ -28,6 +30,8 @@ def __init__( self.resolved_reaction = resolved_reaction self.support_channel = support_channel + self.task_close_old_support.start() # pylint: disable=E1101 + @commands.Cog.listener() async def on_thread_update(self, before, after) -> None: """On thread archive, lock a thread.""" @@ -72,3 +76,43 @@ async def on_raw_reaction_add(self, payload) -> None: logger.debug("Locking thread %d due to owner resolving it.", payload.channel_id) await thread.edit(locked=True, archived=True) PROM_CLOSED.inc() + + @tasks.loop(minutes=60 * 11) + async def task_close_old_support(self) -> None: + """Close old support threads.""" + guild = self.bot.get_guild(self.exercism_guild_id) + if not guild: + logger.error("Failed to find the guild.") + return + channel = guild.get_channel(self.support_channel) + if not channel or not isinstance(channel, discord.ForumChannel): + logger.error("Failed to find the guild.") + return + count = 0 + cutoff = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=21) + oldest = None + for thread in channel.threads: + if thread.archived or thread.locked: + continue + message_id = thread.last_message_id + if not isinstance(message_id, int): + continue + try: + last = await thread.fetch_message(message_id) + except discord.errors.NotFound: + continue + if not last: + continue + oldest = min(last.created_at, oldest) if oldest else last.created_at # type: ignore + if last.created_at > cutoff: + continue + count += 1 + await thread.edit(locked=True, archived=True) + PROM_CLOSED.inc() + logger.warning("Locking thread: %s", last.content) + await asyncio.sleep(1) + + @task_close_old_support.before_loop + async def before_close_old_support(self): + """Before starting the task, wait for bot ready.""" + await self.bot.wait_until_ready()