"""Messaging utilities for Superviseur bot.""" import discord import logging from typing import Optional, List, Dict logger = logging.getLogger('Superviseur') class MessagingManager: """Manages message sending with rate limiting and chunking.""" def __init__(self, bot): self.bot = bot async def send_message_with_limit( self, channel: discord.abc.Messageable, content: str ) -> None: """Send a message, splitting into multiple if it exceeds 2000 chars.""" while len(content) > 2000: split_index = content.rfind(' ', 0, 2000) if split_index == -1: split_index = 2000 chunk = content[:split_index] await channel.send(chunk) content = content[split_index:].lstrip() if content: await channel.send(content) async def reply_with_limit( self, message: discord.Message, content: str ) -> None: """Reply to a message, splitting if it exceeds 2000 chars.""" if not message.channel: logger.warning(f"Cannot send message: no channel") return if hasattr(message.channel, 'permissions_for'): perms = message.channel.permissions_for( message.guild.me if message.guild else message.author ) if not perms.send_messages: logger.warning(f"Cannot send message in channel {message.channel}") return first_chunk = True while len(content) > 2000: split_index = content.rfind(' ', 0, 2000) if split_index == -1: split_index = 2000 chunk = content[:split_index] if first_chunk: try: await message.reply(chunk) except (discord.errors.HTTPException, discord.errors.NotFound): try: await message.channel.send(chunk) except discord.errors.Forbidden: logger.error(f"Forbidden to send in channel {message.channel}") first_chunk = False else: try: await message.channel.send(chunk) except discord.errors.Forbidden: logger.error(f"Forbidden to send in channel {message.channel}") return content = content[split_index:].lstrip() if content: if first_chunk: try: await message.reply(content) except (discord.errors.HTTPException, discord.errors.NotFound): try: await message.channel.send(content) except discord.errors.Forbidden: logger.error(f"Forbidden to send in channel {message.channel}") else: try: await message.channel.send(content) except discord.errors.Forbidden: logger.error(f"Forbidden to send in channel {message.channel}") async def send_embed( self, target: discord.abc.Messageable, title: str, description: str, color: discord.Color = discord.Color.light_grey(), thumbnail_url: Optional[str] = None, is_asset: bool = False, fields: Optional[List[Dict[str, str]]] = None ) -> None: """Send a clinical Samaritan-style embed with support for fields and clickable links.""" # Clinical formatting - we avoid the global ``` to allow markdown (links, mentions) display_title = f"◈ {title} ◈" embed = discord.Embed( title=display_title, description=description, color=color ) if fields: for field in fields: embed.add_field( name=field.get("name", "---"), value=field.get("value", "---"), inline=field.get("inline", True) ) if is_asset: embed.set_author( name="SYSTEM: BÊTA | PRIMARY ASSET LINK", icon_url="https://i.imgur.com/xH3X5rR.png" ) if thumbnail_url: embed.set_thumbnail(url=thumbnail_url) embed.set_footer(text=f"HEURISTIC ANALYSIS COMPLETE | {self.bot.system_name} v2.0") try: await target.send(embed=embed) except discord.errors.Forbidden: logger.error(f"Cannot send DM/Message to {target}")