import uuid from fastapi import APIRouter, Depends, HTTPException, Request from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from database import get_db from config import settings from models import User, ChatSession, ChatMessage router = APIRouter(prefix="/api/wecom", tags=["wecom"]) @router.post("/callback") async def wecom_callback(request: Request, db: AsyncSession = Depends(get_db)): """ 接收企业微信回调消息,路由到AI助手处理并回复。 企微配置的回调URL指向此端点。 """ try: body = await request.json() except Exception: body = await request.body() msg_type = "text" wecom_user_id = "" content = "" if isinstance(body, dict): msg_type = body.get("msg_type", body.get("MsgType", "text")) wecom_user_id = body.get("user_id", body.get("FromUserName", "")) content = body.get("content", body.get("Content", "")) if not wecom_user_id or not content: return {"code": 200, "message": "received"} user_result = await db.execute( select(User).where(User.wecom_user_id == wecom_user_id) ) user = user_result.scalar_one_or_none() if not user: return {"code": 200, "message": "received", "data": {"note": "user not found"}} from agentscope.message import Msg session_result = await db.execute( select(ChatSession) .where(ChatSession.user_id == user.id, ChatSession.agent_type == "employee") .order_by(ChatSession.updated_at.desc()) .limit(1) ) session = session_result.scalar_one_or_none() session_id = f"wecom_{wecom_user_id}_{uuid.uuid4().hex[:8]}" if not session: session = ChatSession( user_id=user.id, agent_type="employee", session_id=session_id, ) db.add(session) await db.flush() user_msg = ChatMessage( session_id=session.id, user_id=user.id, role="user", content=content, ) db.add(user_msg) await db.flush() from agentscope_integration.factory import AgentFactory agent = await AgentFactory.create_agent( agent_type="employee", user_id=str(user.id), user_name=user.display_name, department_id=str(user.department_id) if user.department_id else None, ) input_msg = Msg(name="user", content=content, role="user") response = await agent.reply(input_msg) reply_text = response.get_text_content() if hasattr(response, 'get_text_content') else str(response) ai_msg = ChatMessage( session_id=session.id, user_id=user.id, role="assistant", content=reply_text, ) db.add(ai_msg) return { "code": 200, "message": "ok", "data": { "msg_type": msg_type, "user_id": wecom_user_id, "reply": reply_text, }, } @router.get("/config") async def get_wecom_config(request: Request): return { "code": 200, "data": { "bot_name": "企业AI助手", "status": "active" if settings.WECOM_CORP_ID else "unconfigured", "corp_id": settings.WECOM_CORP_ID or "", "agent_id": getattr(settings, 'WECOM_AGENT_ID', 0), "features": ["消息对话", "文件处理", "任务通知", "工作流触发"], }, } @router.put("/config") async def update_wecom_config(request: Request, payload: dict): import os env_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), '.env') updates = {} if "corp_id" in payload: updates["WECOM_CORP_ID"] = payload["corp_id"] if "secret" in payload: updates["WECOM_APP_SECRET"] = payload["secret"] if "agent_id" in payload: updates["WECOM_AGENT_ID"] = str(payload["agent_id"]) if "token" in payload: updates["WECOM_TOKEN"] = payload["token"] if "encoding_aes_key" in payload: updates["WECOM_ENCODING_AES_KEY"] = payload["encoding_aes_key"] if updates: lines = [] if os.path.exists(env_path): with open(env_path, 'r') as f: lines = f.readlines() existing_keys = {l.split('=')[0].strip() for l in lines if '=' in l and not l.startswith('#')} for key, value in updates.items(): if key in existing_keys: lines = [f"{key}={value}\n" if l.split('=')[0].strip() == key else l for l in lines] else: lines.append(f"{key}={value}\n") with open(env_path, 'w') as f: f.writelines(lines) for key, value in updates.items(): if hasattr(settings, key): setattr(settings, key, value) return {"code": 200, "message": "配置已保存"} @router.post("/send") async def send_wecom_message(request: Request, payload: dict): to_user = payload.get("to_user", "@all") msg_type = payload.get("msg_type", "text") content = payload.get("content", "") if not content: return {"code": 400, "message": "消息内容不能为空"} try: from agentscope_integration.tools.wecom_tools import send_notification result = send_notification(to_user, content, msg_type) return {"code": 200, "message": result} except Exception as e: return {"code": 500, "message": f"发送失败: {e}"}