177 lines
5.6 KiB
Python
177 lines
5.6 KiB
Python
# ///
|
|
# external.py
|
|
# 描述:外部扩展接口,供其他程序调用中控系统
|
|
# 作者:AI Generated
|
|
# 创建日期:2026-04-05
|
|
# ///
|
|
|
|
from fastapi import APIRouter, HTTPException, Depends
|
|
from typing import List, Optional, Dict, Any
|
|
from pydantic import BaseModel
|
|
|
|
from services.node_manager import node_manager
|
|
from plugins.base import PluginRegistry
|
|
from utils import require_external_key
|
|
|
|
|
|
router = APIRouter(prefix="/external", tags=["外部扩展接口"])
|
|
|
|
|
|
class ExternalMessageRequest(BaseModel):
|
|
node_id: str
|
|
who: str
|
|
msg: str
|
|
msg_type: str = "text"
|
|
|
|
|
|
class DataTriggerRequest(BaseModel):
|
|
node_id: str
|
|
source: str
|
|
event: str
|
|
data: Dict[str, Any]
|
|
auto_send: bool = True
|
|
target: Optional[str] = None
|
|
|
|
|
|
class PluginExecuteRequest(BaseModel):
|
|
plugin_name: str
|
|
action: str
|
|
params: 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 external_send_message(request: ExternalMessageRequest,
|
|
_=Depends(require_external_key)) -> Dict[str, Any]:
|
|
await sync_node_from_db(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("/trigger", summary="外部接口-触发数据处理")
|
|
async def external_trigger(request: DataTriggerRequest,
|
|
_=Depends(require_external_key)) -> Dict[str, Any]:
|
|
plugin = PluginRegistry.get(request.source)
|
|
if not plugin:
|
|
raise HTTPException(status_code=404, detail=f"Plugin '{request.source}' not found")
|
|
|
|
if not plugin.enabled:
|
|
raise HTTPException(status_code=400, detail=f"Plugin '{request.source}' is disabled")
|
|
|
|
execute_result = plugin.execute({
|
|
"event": request.event,
|
|
"data": request.data
|
|
})
|
|
|
|
if request.auto_send and request.target:
|
|
await sync_node_from_db(request.node_id)
|
|
msg = request.data.get("message", str(request.data))
|
|
send_result = await node_manager.send_message(
|
|
node_id=request.node_id,
|
|
who=request.target,
|
|
msg=msg
|
|
)
|
|
execute_result["send_result"] = send_result
|
|
|
|
return {
|
|
"success": True,
|
|
"plugin_result": execute_result,
|
|
"data_triggered": True
|
|
}
|
|
|
|
|
|
@router.post("/plugin/execute", summary="外部接口-执行插件")
|
|
async def execute_plugin(request: PluginExecuteRequest,
|
|
_=Depends(require_external_key)) -> Dict[str, Any]:
|
|
plugin = PluginRegistry.get(request.plugin_name)
|
|
if not plugin:
|
|
raise HTTPException(status_code=404, detail=f"Plugin '{request.plugin_name}' not found")
|
|
|
|
if not plugin.enabled:
|
|
raise HTTPException(status_code=400, detail=f"Plugin '{request.plugin_name}' is disabled")
|
|
|
|
result = plugin.execute(request.params)
|
|
return {"success": True, "result": result}
|
|
|
|
|
|
@router.get("/plugins", summary="外部接口-获取可用插件列表")
|
|
async def get_plugins(_=Depends(require_external_key)) -> Dict[str, Any]:
|
|
plugins = PluginRegistry.get_all()
|
|
enabled_plugins = [p for p in plugins if p.enabled]
|
|
return {
|
|
"success": True,
|
|
"plugins": [p.get_info() for p in enabled_plugins],
|
|
"count": len(enabled_plugins)
|
|
}
|
|
|
|
|
|
@router.get("/nodes", summary="外部接口-获取可用节点")
|
|
async def get_available_nodes(_=Depends(require_external_key)) -> Dict[str, Any]:
|
|
from database_service import get_db_service
|
|
db_service = get_db_service()
|
|
if db_service:
|
|
nodes = db_service.get_enabled_nodes()
|
|
return {"success": True, "nodes": [n.to_dict() for n in nodes], "count": len(nodes)}
|
|
nodes = await node_manager.get_enabled_nodes()
|
|
return {"success": True, "nodes": [n.to_dict() for n in nodes], "count": len(nodes)}
|
|
|
|
|
|
@router.post("/ai/process", summary="外部接口-AI处理消息")
|
|
async def ai_process_message(
|
|
input_text: str,
|
|
context: Optional[Dict[str, Any]] = None,
|
|
model: Optional[str] = None,
|
|
_=Depends(require_external_key)
|
|
) -> Dict[str, Any]:
|
|
ai_plugin = PluginRegistry.get("simple_ai_agent")
|
|
if not ai_plugin or not ai_plugin.enabled:
|
|
raise HTTPException(status_code=400, detail="AI agent not available")
|
|
|
|
if model:
|
|
ai_plugin.model = model
|
|
|
|
result = ai_plugin.process(input_text, context or {})
|
|
return {"success": True, "result": result}
|
|
|
|
|
|
@router.post("/webhook/{event}", summary="外部接口-Webhook接收")
|
|
async def receive_webhook(event: str,
|
|
payload: Dict[str, Any],
|
|
_=Depends(require_external_key)) -> Dict[str, Any]:
|
|
webhook_plugin = PluginRegistry.get("webhook_trigger")
|
|
if webhook_plugin and webhook_plugin.enabled:
|
|
result = webhook_plugin.execute({
|
|
"event": event,
|
|
"data": payload
|
|
})
|
|
return {"success": True, "result": result}
|
|
return {"success": True, "message": "Webhook received", "event": event}
|