# /// # messages.py # 描述:消息发送API路由 # 作者:AI Generated # 创建日期:2026-04-05 # /// from fastapi import APIRouter, HTTPException, Depends from typing import List, Dict, Any from pydantic import BaseModel from services.node_manager import node_manager from utils import require_api_key, check_node_health router = APIRouter(prefix="/messages", tags=["消息管理"]) class SendMessageRequest(BaseModel): node_id: str who: str msg: str msg_type: str = "text" class SendGroupMessageRequest(BaseModel): node_id: str group_name: str msg: str msg_type: str = "text" class BatchMessageRequest(BaseModel): messages: List[Dict[str, Any]] async def sync_node_from_db(node_id: str) -> bool: from database_service import get_db_service db_service = get_db_service() if not db_service: return False node = db_service.get_node(node_id) if not node: return False existing = node_manager.nodes.get(node_id) if existing: existing.api_url = node.api_url existing.api_key = node.api_key else: await node_manager.add_node( node_id=node.node_id, name=node.name, api_url=node.api_url, api_key=node.api_key, description=node.description or "", group=node.group or "default" ) return True @router.post("/send", summary="发送消息") async def send_message(request: SendMessageRequest, _=Depends(require_api_key)) -> Dict[str, Any]: await sync_node_from_db(request.node_id) await check_node_health(request.node_id) result = await node_manager.send_message( node_id=request.node_id, who=request.who, msg=request.msg, msg_type=request.msg_type ) return result @router.post("/send_group", summary="发送群消息") async def send_group_message(request: SendGroupMessageRequest, _=Depends(require_api_key)) -> Dict[str, Any]: await sync_node_from_db(request.node_id) await check_node_health(request.node_id) result = await node_manager.send_message_to_group( node_id=request.node_id, group_name=request.group_name, msg=request.msg, msg_type=request.msg_type ) return result @router.post("/batch", summary="批量发送消息") async def batch_send(request: BatchMessageRequest, _=Depends(require_api_key)) -> Dict[str, Any]: results = [] for msg_item in request.messages: node_id = msg_item.get("node_id") who = msg_item.get("who") msg = msg_item.get("msg") msg_type = msg_item.get("msg_type", "text") if not all([node_id, who, msg]): results.append({ "success": False, "error": "Missing required fields", "item": msg_item }) continue is_healthy, reason = await node_manager.is_node_healthy(node_id) if not is_healthy: results.append({ "success": False, "error": f"Node not healthy: {reason}", "node_id": node_id, "who": who }) continue result = await node_manager.send_message(node_id, who, msg, msg_type) results.append({"node_id": node_id, "who": who, "result": result}) return {"success": True, "results": results, "total": len(results)} @router.post("/template/{node_id}/{who}", summary="发送模板消息") async def send_template_message(node_id: str, who: str, template: str, params: Dict[str, str], _=Depends(require_api_key)) -> Dict[str, Any]: await check_node_health(node_id) try: msg = template.format(**params) except KeyError as e: raise HTTPException(status_code=400, detail=f"Missing template parameter: {e}") result = await node_manager.send_message(node_id, who, msg) return result @router.get("/history/{node_id}/{chat_name}", summary="获取消息历史") async def get_message_history(node_id: str, chat_name: str, limit: int = 50, _=Depends(require_api_key)) -> Dict[str, Any]: await check_node_health(node_id) result = await node_manager.get_messages(node_id, chat_name, limit) return result