ForcePilot/backend/package/yuxi/channel/extensions/irc/send.py
Kris 061cc7076b feat(channel): 添加 IRC 渠道扩展插件
新增 IRC 渠道的完整扩展实现,包括客户端连接管理、消息收发与流式处理、安全策略与配对验证、消息去重与规范化、状态监控与健康探测、配置模型与账户管理、错误处理等模块。
2026-05-21 10:59:12 +08:00

78 lines
2.1 KiB
Python

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)