diff --git a/bot.py b/bot.py index a2ba2f7..fa6109f 100644 --- a/bot.py +++ b/bot.py @@ -195,7 +195,7 @@ class GravityBot(commands.Bot): async def _ensure_channel( self, conversation_id: str, project_name: str ) -> discord.TextChannel: - """Get or create a channel. Uses GLOBAL lock and NAME-based lookup.""" + """Get or create a channel. Uses GLOBAL lock + OWN dict lookup (no cache issues).""" # Fast path: already mapped if conversation_id in self.session_channels: return self.session_channels[conversation_id] @@ -208,24 +208,16 @@ class GravityBot(commands.Bot): channel_name = f"{Config.CHANNEL_PREFIX}-{project_name}" target_name = channel_name.lower().replace(" ", "-") - # Fetch FRESH channel list from Discord API (not cached) - if self.session_category: - category = await self.guild.fetch_channel(self.session_category.id) - for ch in category.text_channels: - # Match by NAME (handles different conv IDs → same project) - if ch.name == target_name or (ch.topic and conversation_id in ch.topic): - self.session_channels[conversation_id] = ch - self.session_names[conversation_id] = project_name - # Rename from closed- if needed - if ch.name.startswith("closed-"): - try: - await ch.edit(name=channel_name) - except discord.errors.Forbidden: - pass - logger.info(f"Reusing existing channel #{ch.name}") - return ch + # Check OWN dict for a channel with the same NAME + # (different conv IDs can share one channel) + for cid, ch in self.session_channels.items(): + if ch.name == target_name: + self.session_channels[conversation_id] = ch + self.session_names[conversation_id] = project_name + logger.info(f"Reusing channel #{ch.name} for {conversation_id[:8]}") + return ch - # Create new channel (only if truly no match found) + # Create new channel (truly first time) try: channel = await self.guild.create_text_channel( name=channel_name, @@ -280,10 +272,16 @@ class GravityBot(commands.Bot): if not channel: return - if event.file_name == "task.md": - await self._send_task_update(channel, event) - else: - await self._send_artifact_update(channel, event) + try: + if event.file_name == "task.md": + await self._send_task_update(channel, event) + else: + await self._send_artifact_update(channel, event) + except discord.NotFound: + # Channel was deleted while we held a reference + self.session_channels.pop(event.conversation_id, None) + self.session_status_messages.pop(event.conversation_id, None) + logger.warning(f"Channel deleted, cleared: {event.conversation_id[:8]}") # ─── Message Senders ─────────────────────────────────────────────