mirror of
https://github.com/marcogll/talia_bot.git
synced 2026-01-13 21:35:19 +00:00
116 lines
4.1 KiB
Python
116 lines
4.1 KiB
Python
# app/calendar.py
|
|
# Este script maneja la integración con Google Calendar (Calendario de Google).
|
|
# Permite buscar espacios libres y crear eventos.
|
|
|
|
import datetime
|
|
from google.oauth2 import service_account
|
|
from googleapiclient.discovery import build
|
|
from googleapiclient.errors import HttpError
|
|
from config import GOOGLE_SERVICE_ACCOUNT_FILE, CALENDAR_ID
|
|
|
|
# Configuración de los permisos (SCOPES) para acceder al calendario
|
|
SCOPES = ["https://www.googleapis.com/auth/calendar"]
|
|
|
|
# Autenticación usando el archivo de cuenta de servicio (Service Account)
|
|
creds = service_account.Credentials.from_service_account_file(
|
|
GOOGLE_SERVICE_ACCOUNT_FILE, scopes=SCOPES
|
|
)
|
|
|
|
# Construcción del objeto 'service' que nos permite interactuar con la API de Google Calendar
|
|
service = build("calendar", "v3", credentials=creds)
|
|
|
|
|
|
def get_available_slots(
|
|
start_time, end_time, duration_minutes=30, calendar_id=CALENDAR_ID
|
|
):
|
|
"""
|
|
Busca espacios disponibles en el calendario dentro de un rango de tiempo.
|
|
|
|
Parámetros:
|
|
- start_time: Hora de inicio de la búsqueda.
|
|
- end_time: Hora de fin de la búsqueda.
|
|
- duration_minutes: Cuánto dura cada cita (por defecto 30 min).
|
|
- calendar_id: El ID del calendario donde buscar.
|
|
"""
|
|
try:
|
|
# Convertimos las fechas a formato ISO (el que entiende Google)
|
|
time_min = start_time.isoformat()
|
|
time_max = end_time.isoformat()
|
|
|
|
# Consultamos a Google qué horas están ocupadas (freebusy)
|
|
freebusy_query = {
|
|
"timeMin": time_min,
|
|
"timeMax": time_max,
|
|
"timeZone": "UTC",
|
|
"items": [{"id": calendar_id}],
|
|
}
|
|
|
|
freebusy_result = service.freebusy().query(body=freebusy_query).execute()
|
|
busy_slots = freebusy_result["calendars"][calendar_id]["busy"]
|
|
|
|
# Creamos una lista de todos los posibles espacios (slots)
|
|
potential_slots = []
|
|
current_time = start_time
|
|
while current_time + datetime.timedelta(minutes=duration_minutes) <= end_time:
|
|
potential_slots.append(
|
|
(
|
|
current_time,
|
|
current_time + datetime.timedelta(minutes=duration_minutes),
|
|
)
|
|
)
|
|
# Avanzamos el tiempo para el siguiente espacio
|
|
current_time += datetime.timedelta(minutes=duration_minutes)
|
|
|
|
# Filtramos los espacios que chocan con horas ocupadas
|
|
available_slots = []
|
|
for slot_start, slot_end in potential_slots:
|
|
is_busy = False
|
|
for busy in busy_slots:
|
|
busy_start = datetime.datetime.fromisoformat(busy["start"])
|
|
busy_end = datetime.datetime.fromisoformat(busy["end"])
|
|
# Si el espacio propuesto se cruza con uno ocupado, lo marcamos como ocupado
|
|
if max(slot_start, busy_start) < min(slot_end, busy_end):
|
|
is_busy = True
|
|
break
|
|
if not is_busy:
|
|
available_slots.append((slot_start, slot_end))
|
|
|
|
return available_slots
|
|
except HttpError as error:
|
|
print(f"Ocurrió un error con la API de Google: {error}")
|
|
return []
|
|
|
|
|
|
def create_event(summary, start_time, end_time, attendees, calendar_id=CALENDAR_ID):
|
|
"""
|
|
Crea un nuevo evento (cita) en el calendario.
|
|
|
|
Parámetros:
|
|
- summary: Título del evento.
|
|
- start_time: Hora de inicio.
|
|
- end_time: Hora de fin.
|
|
- attendees: Lista de correos electrónicos de los asistentes.
|
|
"""
|
|
# Definimos la estructura del evento según pide Google
|
|
event = {
|
|
"summary": summary,
|
|
"start": {
|
|
"dateTime": start_time.isoformat(),
|
|
"timeZone": "UTC",
|
|
},
|
|
"end": {
|
|
"dateTime": end_time.isoformat(),
|
|
"timeZone": "UTC",
|
|
},
|
|
"attendees": [{"email": email} for email in attendees],
|
|
}
|
|
try:
|
|
# Insertamos el evento en el calendario
|
|
created_event = (
|
|
service.events().insert(calendarId=calendar_id, body=event).execute()
|
|
)
|
|
return created_event
|
|
except HttpError as error:
|
|
print(f"Ocurrió un error al crear el evento: {error}")
|
|
return None
|