"""API 接口模块 - FastAPI 路由定义""" from fastapi import APIRouter, Request, HTTPException from pydantic import BaseModel from typing import Optional from nonebot import get_driver, logger from .config import Config from .text_parser import TextParser from .image_render import ImageRenderer from .sender import sender # 请求体模型 class PushRequest(BaseModel): """推送请求模型""" group_id: int """接收消息的 QQ 群号""" qq: int """被 @ 的 QQ 号""" text: str """通知文本(# 表示换行)""" # 响应模型 class PushResponse(BaseModel): """推送响应模型""" success: bool """是否成功""" message: str """响应消息""" data: Optional[dict] = None """返回数据(如有)""" # 创建路由器 router = APIRouter() def create_routes(token: str, config: Config): """ 创建 API 路由 Args: token: 鉴权 Token config: 配置对象 """ @router.post(f"/danding/qqpush/{token}", response_model=PushResponse) async def qqpush(request: Request, data: PushRequest): """ QQ 消息推送接口 Args: request: FastAPI 请求对象 data: 推送请求数据 Returns: 推送结果 """ try: # 1. 验证参数 if not data.group_id: raise HTTPException(status_code=400, detail="group_id 不能为空") if not data.qq: raise HTTPException(status_code=400, detail="qq 不能为空") if not data.text or not isinstance(data.text, str): raise HTTPException(status_code=400, detail="text 不能为空且必须是字符串") # 2. 检查 Bot 是否在线 bot = sender.get_bot() if not bot: logger.error("Bot 实例未设置,无法发送消息") raise HTTPException( status_code=500, detail="Bot 未连接,请检查机器人状态" ) # 3. 文本处理 text_parser = TextParser(max_length=config.MaxTextLength) if not text_parser.validate_text(data.text): raise HTTPException(status_code=400, detail="文本内容无效") parsed_text = text_parser.parse(data.text) logger.info(f"解析文本: {parsed_text[:50]}..." if len(parsed_text) > 50 else parsed_text) # 4. 生成图片 image_renderer = ImageRenderer( width=config.ImageWidth, font_size=config.ImageFontSize, padding=config.ImagePadding, line_spacing=config.ImageLineSpacing, bg_color=config.ImageBgColor, text_color=config.ImageTextColor, font_paths=config.FontPaths ) image_base64 = image_renderer.render_to_base64(parsed_text) logger.info("图片生成成功") # 5. 发送消息 send_result = await sender.send_to_group( group_id=data.group_id, qq=data.qq, image_base64=image_base64 ) if not send_result["success"]: logger.error(f"消息发送失败: {send_result['error']}") raise HTTPException( status_code=500, detail=send_result["message"] ) logger.info(f"消息发送成功 - 群: {data.group_id}, @: {data.qq}") return PushResponse( success=True, message="推送成功", data={ "group_id": data.group_id, "qq": data.qq, "message_id": send_result["data"].get("message_id") } ) except HTTPException: raise except Exception as e: logger.exception(f"推送接口异常: {str(e)}") raise HTTPException( status_code=500, detail=f"服务器内部错误: {str(e)}" ) return router