1
1
"""Discord Cog to close support threads."""
2
2
3
3
import asyncio
4
+ import datetime
4
5
import logging
5
6
6
7
import discord
7
8
import prometheus_client # type: ignore
8
9
from discord .ext import commands
10
+ from discord .ext import tasks
9
11
10
12
from cogs import base_cog
11
13
@@ -28,6 +30,8 @@ def __init__(
28
30
self .resolved_reaction = resolved_reaction
29
31
self .support_channel = support_channel
30
32
33
+ self .task_close_old_support .start () # pylint: disable=E1101
34
+
31
35
@commands .Cog .listener ()
32
36
async def on_thread_update (self , before , after ) -> None :
33
37
"""On thread archive, lock a thread."""
@@ -72,3 +76,43 @@ async def on_raw_reaction_add(self, payload) -> None:
72
76
logger .debug ("Locking thread %d due to owner resolving it." , payload .channel_id )
73
77
await thread .edit (locked = True , archived = True )
74
78
PROM_CLOSED .inc ()
79
+
80
+ @tasks .loop (minutes = 60 * 11 )
81
+ async def task_close_old_support (self ) -> None :
82
+ """Close old support threads."""
83
+ guild = self .bot .get_guild (self .exercism_guild_id )
84
+ if not guild :
85
+ logger .error ("Failed to find the guild." )
86
+ return
87
+ channel = guild .get_channel (self .support_channel )
88
+ if not channel or not isinstance (channel , discord .ForumChannel ):
89
+ logger .error ("Failed to find the guild." )
90
+ return
91
+ count = 0
92
+ cutoff = datetime .datetime .now (datetime .timezone .utc ) - datetime .timedelta (days = 21 )
93
+ oldest = None
94
+ for thread in channel .threads :
95
+ if thread .archived or thread .locked :
96
+ continue
97
+ message_id = thread .last_message_id
98
+ if not isinstance (message_id , int ):
99
+ continue
100
+ try :
101
+ last = await thread .fetch_message (message_id )
102
+ except discord .errors .NotFound :
103
+ continue
104
+ if not last :
105
+ continue
106
+ oldest = min (last .created_at , oldest ) if oldest else last .created_at # type: ignore
107
+ if last .created_at > cutoff :
108
+ continue
109
+ count += 1
110
+ await thread .edit (locked = True , archived = True )
111
+ PROM_CLOSED .inc ()
112
+ logger .warning ("Locking thread: %s" , last .content )
113
+ await asyncio .sleep (1 )
114
+
115
+ @task_close_old_support .before_loop
116
+ async def before_close_old_support (self ):
117
+ """Before starting the task, wait for bot ready."""
118
+ await self .bot .wait_until_ready ()
0 commit comments