from typing import Any from fastapi import HTTPException, status from sqlalchemy.orm import Session from app.core.config import get_settings from app.modules.audit.schemas import AuditLogCreate from app.modules.audit.service import AuditService from app.modules.feishu.client import FeishuClient class FeishuService: """Send Feishu messages and record audit entries for outbound actions.""" def __init__(self, db: Session): self.db = db self.audit = AuditService(db) self.client = FeishuClient() def verify_event(self, payload: dict[str, Any]) -> None: settings = get_settings() expected = settings.feishu_verification_token token = payload.get("token") if expected and token and token != expected: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid Feishu token", ) def send_text( self, text: str, receive_id: str | None = None, receive_id_type: str = "chat_id", actor: str = "system", ) -> dict[str, Any]: result = self.client.send_text(text, receive_id, receive_id_type) self.audit.log( AuditLogCreate( actor=actor, source="feishu", action="send_text", request_payload={ "receive_id": receive_id, "receive_id_type": receive_id_type, "text": text, }, response_payload=result, ) ) return result def send_card( self, card: dict[str, Any], receive_id: str | None = None, receive_id_type: str = "chat_id", actor: str = "system", ) -> dict[str, Any]: result = self.client.send_card(card, receive_id, receive_id_type) self.audit.log( AuditLogCreate( actor=actor, source="feishu", action="send_card", request_payload={ "receive_id": receive_id, "receive_id_type": receive_id_type, "card": card, }, response_payload=result, ) ) return result @staticmethod def build_basic_card(title: str, lines: list[str]) -> dict[str, Any]: return { "config": {"wide_screen_mode": True}, "header": {"title": {"tag": "plain_text", "content": title}}, "elements": [ {"tag": "div", "text": {"tag": "lark_md", "content": "\n".join(lines) or "暂无数据"}} ], }