From 9b94280e8b79e8a63b3f8e572b32403d1a7d3d8b Mon Sep 17 00:00:00 2001 From: Franz Rolfsvaag Date: Mon, 25 Aug 2025 23:57:39 +0200 Subject: [PATCH] 0.5.1.2.a3 - Small patch to repair orphaned fedaykin requests --- bot.py | 2 +- modules/reaction_role/reaction_role.py | 41 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 1104c86..84e3801 100644 --- a/bot.py +++ b/bot.py @@ -9,7 +9,7 @@ from modules.common.boot_notice import post_boot_notice # Version consists of: # Major.Enhancement.Minor.Patch.Test (Test is alphanumeric; doesn’t trigger auto update) -VERSION = "0.5.1.2.a2" +VERSION = "0.5.1.2.a3" # ---------- Env loading ---------- load_dotenv() diff --git a/modules/reaction_role/reaction_role.py b/modules/reaction_role/reaction_role.py index 0cdffc3..08c0e20 100644 --- a/modules/reaction_role/reaction_role.py +++ b/modules/reaction_role/reaction_role.py @@ -212,6 +212,12 @@ class ReactionRoleCog(commands.Cog): hg = cfg(self.bot).int('home_guild_id', 0) guild = self.bot.get_guild(hg) if hg else (self.bot.guilds[0] if self.bot.guilds else None) await self._maybe_transition_head_state(guild) + except Exception: + pass + + try: + if guild: + await self._repair_orphaned_pending_cards(guild) except Exception: pass @@ -576,6 +582,7 @@ class ReactionRoleCog(commands.Cog): # Head appeared — flush queued to cards self._fedaykin_headless = False posted = await self._flush_pending_to_cards(guild) + await self._repair_orphaned_pending_cards(guild) await self._modlog_head_summary(guild, head_present=True, posted=posted) elif not has_head_now and not self._fedaykin_headless: # Became headless — revoke all fedaykins and queue pendings @@ -583,6 +590,40 @@ class ReactionRoleCog(commands.Cog): revoked, queued = await self._headless_revoke_and_queue(guild) await self._modlog_head_summary(guild, head_present=False, revoked=revoked, queued=queued) + # inside ReactionRoleCog class + async def _repair_orphaned_pending_cards(self, guild: discord.Guild) -> int: + """Detect pending requests whose review message was deleted; reset them so they can be re-posted.""" + dm = self.bot.data_manager + repaired = 0 + for req in list(_as_list(dm.get('fedaykin_requests'))): + if int(req.get("guild_id", 0)) != guild.id or req.get("status") != "pending": + continue + mid = int(req.get("review_message_id", 0) or 0) + cid = int(req.get("review_channel_id", 0) or 0) + if not mid or not cid: + continue # already queued (no card) + ch = self.bot.get_channel(cid) + exists = False + if isinstance(ch, (discord.TextChannel, discord.Thread)): + try: + await ch.fetch_message(mid) + exists = True + except (discord.NotFound, discord.Forbidden): + exists = False + except Exception: + exists = False + if not exists: + # reset to "queued" so normal flow can re-post + req["review_message_id"] = 0 + req["review_channel_id"] = 0 + await self._save_fedaykin_request(req) + repaired += 1 + + # If we repaired and a head exists, immediately flush to new cards + if repaired and not self._fedaykin_headless and self._has_fedaykin_head(guild): + await self._flush_pending_to_cards(guild) + return repaired + # ------------------ listeners ------------------ @commands.Cog.listener()