import asyncio import logging import time import uuid from yuxi.channel.extensions.irc.client import ( connect_irc_client, graceful_disconnect, send_privmsg, ) from yuxi.channel.extensions.irc.normalize import normalize_irc_target from yuxi.channel.extensions.irc.protocol import sanitize_irc_text, split_irc_text from yuxi.channel.extensions.irc.types import ResolvedIrcAccount, SendIrcResult logger = logging.getLogger(__name__) IRC_SEND_DELAY = 0.3 async def send_irc_message( to: str, text: str, account: ResolvedIrcAccount, reply_to_id: str | None = None, client=None, ) -> SendIrcResult: target = normalize_irc_target(to) text = sanitize_irc_text(text) if reply_to_id: text = f"{text}\n\n[reply:{reply_to_id}]" chunk_limit = 350 if account.config is not None: chunk_limit = account.config.text_chunk_limit or 350 chunks = split_irc_text(text, chunk_limit) writer = None own_client = None try: if client is not None and client.writer is not None: writer = client.writer else: own_client = await connect_irc_client(account, timeout=12.0) await asyncio.sleep(1.5) writer = own_client.writer for i, chunk in enumerate(chunks): if i > 0: await asyncio.sleep(IRC_SEND_DELAY) await send_privmsg(writer, target, chunk) except Exception as e: logger.error("Failed to send IRC message to %s: %s", target, e) return SendIrcResult(ok=False, error=str(e), chunk_count=0) finally: if own_client is not None: await graceful_disconnect(own_client) return SendIrcResult( ok=True, message_id=str(uuid.uuid4()), chunk_count=len(chunks), ) async def send_irc_media( to: str, media_url: str, media_type: str, account: ResolvedIrcAccount, reply_to_id: str | None = None, client=None, ) -> SendIrcResult: caption = f"[{media_type}]" if media_type else "[Attachment]" text = f"{caption}\n{media_url}" return await send_irc_message(to, text, account, reply_to_id=reply_to_id, client=client)