You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
2.4 KiB
Python
67 lines
2.4 KiB
Python
|
1 day ago
|
from datetime import datetime, timedelta, timezone
|
||
|
|
from fastapi import APIRouter, Depends, HTTPException
|
||
|
|
from pydantic import BaseModel
|
||
|
|
from sqlmodel import Session, select
|
||
|
|
|
||
|
|
from app.core.db import get_session
|
||
|
|
from app.models import GoogleAccount, AuditLog
|
||
|
|
from app.google.client import get_service
|
||
|
|
|
||
|
|
router = APIRouter()
|
||
|
|
|
||
|
|
class CreateEventIn(BaseModel):
|
||
|
|
title: str = "Reunión"
|
||
|
|
minutes_from_now: int = 10
|
||
|
|
duration_minutes: int = 60
|
||
|
|
timezone: str = "America/Lima"
|
||
|
|
attendees: list[str] = []
|
||
|
|
|
||
|
|
def get_account(session: Session, email: str) -> GoogleAccount:
|
||
|
|
acc = session.exec(select(GoogleAccount).where(GoogleAccount.email == email)).first()
|
||
|
|
if not acc:
|
||
|
|
raise HTTPException(status_code=404, detail="Cuenta no autorizada. Primero usa /auth/google/start.")
|
||
|
|
return acc
|
||
|
|
|
||
|
|
@router.post("/events")
|
||
|
|
def create_event(payload: CreateEventIn, account_email: str, session: Session = Depends(get_session)):
|
||
|
|
acc = get_account(session, account_email)
|
||
|
|
cal = get_service("calendar", "v3", acc.token_json)
|
||
|
|
|
||
|
|
# Usamos ISO con timezone local (Google acepta timeZone separado)
|
||
|
|
start_dt = datetime.now(timezone.utc) + timedelta(minutes=payload.minutes_from_now)
|
||
|
|
end_dt = start_dt + timedelta(minutes=payload.duration_minutes)
|
||
|
|
|
||
|
|
event = {
|
||
|
|
"summary": payload.title,
|
||
|
|
"start": {"dateTime": start_dt.isoformat(), "timeZone": payload.timezone},
|
||
|
|
"end": {"dateTime": end_dt.isoformat(), "timeZone": payload.timezone},
|
||
|
|
"attendees": [{"email": a} for a in payload.attendees],
|
||
|
|
"conferenceData": {
|
||
|
|
"createRequest": {
|
||
|
|
"requestId": f"meet-{int(datetime.utcnow().timestamp())}",
|
||
|
|
"conferenceSolutionKey": {"type": "hangoutsMeet"},
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
try:
|
||
|
|
created = cal.events().insert(
|
||
|
|
calendarId="primary",
|
||
|
|
body=event,
|
||
|
|
conferenceDataVersion=1,
|
||
|
|
sendUpdates="all" if payload.attendees else "none",
|
||
|
|
).execute()
|
||
|
|
|
||
|
|
meet_link = created.get("hangoutLink")
|
||
|
|
session.add(AuditLog(account_email=account_email, action="calendar_create_event", detail=f"meet={meet_link}"))
|
||
|
|
session.commit()
|
||
|
|
|
||
|
|
return {
|
||
|
|
"status": "created",
|
||
|
|
"eventId": created.get("id"),
|
||
|
|
"htmlLink": created.get("htmlLink"),
|
||
|
|
"meetLink": meet_link,
|
||
|
|
}
|
||
|
|
except Exception as e:
|
||
|
|
raise HTTPException(status_code=400, detail=str(e))
|