You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

161 lines
5.3 KiB

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}"}