Ir al contenido

Calendario y agenda

Control Center se conecta a Google Calendar para que tu día quede junto a tu flota. Sincroniza tus eventos, los muestra en vistas de mes, semana, día y agenda, te avisa antes de que empiece una reunión y convierte cualquier evento en una reunión grabada y resumida.

Casi nada. La integración extrae los eventos y los muestra. No crea, edita ni elimina eventos, ni responde a invitaciones. Cada conexión por código de dispositivo, integrada o propia, solicita calendar.readonly más openid email.

Los eventos se sincronizan en la base de datos propia del espacio de trabajo en el servidor (<dataDir>/<workspaceId>/workspace.db) y cada cliente los muestra por RPC. Ningún cliente guarda una credencial de Google.

Las cuentas de calendario tienen alcance de espacio de trabajo, como todo lo demás en Control Center. Cada espacio de trabajo conecta su propia cuenta de Google (o varias) y los eventos y tokens de un espacio de trabajo nunca son visibles desde otro. Cambiar de espacio de trabajo cambia qué calendarios ves.

Un espacio de trabajo puede conectar varias cuentas de Google, como una cuenta de trabajo y una personal, y sus eventos se fusionan en las mismas vistas.

Por qué el inicio de sesión usa un código de dispositivo

Sección titulada «Por qué el inicio de sesión usa un código de dispositivo»

El cc_server headless no tiene navegador que reciba una redirección de OAuth. Por eso no usa ninguna: se autoriza con la concesión de código de dispositivo (RFC 8628). El servidor muestra un código de usuario corto y una URL de Google, tú apruebas en cualquier dispositivo que tenga navegador y el servidor consulta hasta que lo hagas. Una instalación headless puede conectar una cuenta precisamente porque no hay un endpoint de redirección que alojar.

La consecuencia que conviene conocer antes de usar tus propias credenciales: el tipo de cliente debe ser “TV and Limited Input devices” de Google. Google solo concede un conjunto de alcances permitidos a ese tipo de cliente, y un proyecto en el que Calendar no está permitido para él falla con invalid_scope; en ese caso necesitarías un cliente de loopback o web.

Los tokens nunca salen del servidor. Se escriben en el secrets.json del servidor, en su directorio de datos, con la clave google_google:<workspaceId>:<email>, junto a las bases de datos y bajo la misma frontera de confianza del sistema de archivos del host. El servidor actualiza el acceso automáticamente y, cuando Google invalida permanentemente una cuenta (una sesión revocada o caducada hace mucho), publica CalendarAuthExpired y muestra un banner de Reconectar en lugar de fallar en silencio.

Una compilación desde el código fuente no incluye ninguna credencial de Google: tú aportas tu propio id de cliente y tu secreto. Las compilaciones de versión oficiales incorporan un cliente de código de dispositivo no confidencial para que el flujo de conexión funcione de inmediato; el servidor solo guarda un marcador que lo referencia, nunca una copia. GOOGLE_OAUTH_CLIENT_ID (y su secreto) en el entorno siempre tiene precedencia sobre el par incorporado. A propósito no existe una opción --google-client-id: las opciones desconocidas se ignoran, y un secreto en la línea de comandos se puede leer con ps.

Para ejecutar tu propio proyecto de Google, consulta Conectar un Google Calendar.

El servidor extrae una ventana móvil de los eventos de cada cuenta conectada — todos los calendarios de la cuenta, no solo el principal — cada dos minutos, además de a petición (inicio, conexión, actualización manual). La cadencia corta es costeable porque el barrido es incremental: cada calendario lleva su propio token de sincronización, así que un calendario sin cambios cuesta una respuesta casi vacía en vez de volver a obtener una ventana de cinco meses.

Los eventos recurrentes se expanden en el servidor, así que ningún cliente analiza una regla de recurrencia. Navegar a un mes fuera de la ventana actual carga ese rango de forma diferida. Los eventos eliminados o que salieron del rango se reconcilian en la siguiente sincronización.

Vista Qué muestra
Mes Una cuadrícula de mes completo (con el paquete kalender)
Semana Los eventos con hora de una semana en una cuadrícula horaria
Día Los eventos con hora de un solo día en una cuadrícula horaria
Agenda Una lista desplazable de próximos eventos

Abre el calendario en /calendar; al seleccionar un evento se abre su detalle en /calendar/:eventId. La vista que eliges se guarda en las preferencias de ese cliente, así que no te sigue a otro dispositivo.

Un programador por minuto busca eventos que empiecen dentro de una ventana de antelación configurable y lanza una notificación «Reunión a punto de empezar» (un evento de dominio MeetingStartingSoon). La notificación incluye la URL para unirse cuando está presente y al hacer clic en ella se abre el detalle del evento. Las alertas se deduplican contra el alertedAt del evento, así que la misma reunión nunca genera dos alertas, ni siquiera entre reinicios, y un evento cuya hora de inicio pasó mientras la app estaba cerrada nunca vuelve a dispararse.

Dos límites son fáciles de pasar por alto. El programador se ejecuta del lado del cliente en el escritorio y solo para el espacio de trabajo que tienes abierto en ese momento: un espacio de trabajo en el que no estás no genera ninguna alerta. Y la compilación web no tiene ninguna canalización de notificaciones del sistema operativo, así que tampoco genera ninguna.

Desde un evento de calendario puedes iniciar una grabación de reunión inicializada con el título del evento. Control Center guarda un vínculo uno a uno entre la grabación y el evento, así que las notas de la reunión y la entrada del calendario permanecen conectadas sin que ninguna de las dos funciones dependa de la otra.

Grabar y vincular solo está disponible en el escritorio. En el cliente web, la acción informa que la grabación no está disponible, aunque el propio flujo de grabación de la pantalla de reuniones sí funciona en el navegador.