from datetime import datetime from enum import Enum from typing import List from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel, HttpUrl from sqlalchemy.ext.asyncio import AsyncSession from app.database import get_db from app import crud class CallDirection(str, Enum): in_ = "in" out = "out" class UisCallEvent(BaseModel): eventType: str call_session_id: str direction: CallDirection employee_id: int employee_full_name: str contact_phone_number: str called_phone_number: str communication_group_name: str start_time: datetime finish_time: datetime talk_time_duration: int full_record_file_link: HttpUrl campaign_name: str class Config: from_attributes = True class CallEventResponse(BaseModel): id: int event_type: str call_session_id: str direction: str employee_id: int employee_full_name: str contact_phone_number: str called_phone_number: str communication_group_name: str start_time: datetime finish_time: datetime talk_time_duration: int full_record_file_link: str campaign_name: str created_at: datetime updated_at: datetime class Config: from_attributes = True router = APIRouter() @router.post("/webhook", response_model=CallEventResponse, status_code=201) async def create_call_event(callEvent: UisCallEvent, db: AsyncSession = Depends(get_db)): """Webhook для получения событий звонков от UIS""" # Проверяем, не существует ли уже событие с таким call_session_id existing_event = await crud.get_call_event_by_session_id(db, callEvent.call_session_id) if existing_event: raise HTTPException(status_code=400, detail="Call event with this session_id already exists") # Преобразуем Pydantic модель в словарь для БД call_event_data = { "event_type": callEvent.eventType, "call_session_id": callEvent.call_session_id, "direction": callEvent.direction, "employee_id": callEvent.employee_id, "employee_full_name": callEvent.employee_full_name, "contact_phone_number": callEvent.contact_phone_number, "called_phone_number": callEvent.called_phone_number, "communication_group_name": callEvent.communication_group_name, "start_time": callEvent.start_time, "finish_time": callEvent.finish_time, "talk_time_duration": callEvent.talk_time_duration, "full_record_file_link": str(callEvent.full_record_file_link), "campaign_name": callEvent.campaign_name, } db_call_event = await crud.create_call_event(db, call_event_data) return db_call_event @router.get("/events", response_model=List[CallEventResponse]) async def get_call_events( skip: int = 0, limit: int = 100, db: AsyncSession = Depends(get_db) ): """Получить список всех событий звонков""" events = await crud.get_all_call_events(db, skip=skip, limit=limit) return events @router.get("/events/{call_session_id}", response_model=CallEventResponse) async def get_call_event(call_session_id: str, db: AsyncSession = Depends(get_db)): """Получить событие звонка по session_id""" event = await crud.get_call_event_by_session_id(db, call_session_id) if not event: raise HTTPException(status_code=404, detail="Call event not found") return event @router.get("/events/employee/{employee_id}", response_model=List[CallEventResponse]) async def get_employee_call_events( employee_id: int, skip: int = 0, limit: int = 100, db: AsyncSession = Depends(get_db) ): """Получить все звонки конкретного сотрудника""" events = await crud.get_call_events_by_employee(db, employee_id, skip=skip, limit=limit) return events