aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/cogs/moderation/incidents.py32
1 files changed, 32 insertions, 0 deletions
diff --git a/bot/cogs/moderation/incidents.py b/bot/cogs/moderation/incidents.py
index 91b949173..e773636e7 100644
--- a/bot/cogs/moderation/incidents.py
+++ b/bot/cogs/moderation/incidents.py
@@ -1,3 +1,4 @@
+import asyncio
import logging
import typing as t
from enum import Enum
@@ -27,7 +28,38 @@ class Incidents(Cog):
"""Automation for the #incidents channel."""
def __init__(self, bot: Bot) -> None:
+ """Schedule `crawl_task` on start-up."""
self.bot = bot
+ self.crawl_task = self.bot.loop.create_task(self.crawl_incidents())
+
+ async def crawl_incidents(self) -> None:
+ """
+ Crawl #incidents and add missing emoji where necessary.
+
+ This is to catch-up should an incident be reported while the bot wasn't listening.
+ Internally, we simply walk the channel history and pass each message to `on_message`.
+
+ In order to avoid drowning in ratelimits, we take breaks after each message.
+
+ Once this task is scheduled, listeners should await it. The crawl assumes that
+ the channel history doesn't change as we go over it.
+ """
+ await self.bot.wait_until_guild_available()
+ incidents: discord.TextChannel = self.bot.get_channel(Channels.incidents)
+
+ # Limit the query at 50 as in practice, there should never be this many messages,
+ # and if there are, something has likely gone very wrong
+ limit = 50
+
+ # Seconds to sleep after each message
+ sleep = 2
+
+ log.debug(f"Crawling messages in #incidents: {limit=}, {sleep=}")
+ async for message in incidents.history(limit=limit):
+ await self.on_message(message)
+ await asyncio.sleep(sleep)
+
+ log.debug("Crawl task finished!")
@staticmethod
async def add_signals(incident: discord.Message) -> None: