Cómo integrar la API de Google Calendar en tu aplicación
Tabla de Contenidos
Integra todos los calendarios usando una única API
Únete a nuestra lista de espera de la Unified Calendar API para obtener acceso a nuestra Unified Calendar API, que te permite integrar todos los proveedores de calendarios en tu aplicación mediante una única API.
En esta guía, explicaremos detalladamente cómo integrar la API de Google Calendar en tu aplicación, abarcando la configuración del proyecto de Google Cloud, los alcances requeridos, los inconvenientes y un ejemplo real de autorización.
Requisitos previos
Esta guía asume que dispones de una dirección de correo electrónico, un dominio ya listo para usar al crear el proyecto de Google Cloud, ciertos conocimientos de programación y una idea bastante clara de lo que quieres construir.
También resulta útil si nunca has trabajado con la API de Google Calendar y deseas familiarizarte con todos los pasos necesarios para integrarla en tu aplicación.
Cómo utilizar e integrar la API de Google Calendar en tu aplicación
1. Regístrate en Google Developer Console
Si todavía no tienes una cuenta en Google Developer Console, créala en https://console.cloud.google.com/.
2. Crea o selecciona un proyecto de Google Cloud existente
Google Cloud permite a desarrolladores y organizaciones tener varios proyectos. Asegúrate de estar en el proyecto correcto antes de realizar las siguientes operaciones.
Haz clic en el desplegable de proyectos en la parte superior izquierda de la pantalla. El nombre suele coincidir con el de tu proyecto.
Selecciona un proyecto existente o crea uno nuevo haciendo clic en «New Project» en la parte superior derecha del modal.
3. Habilita los servicios de la API de Google Calendar
Una vez creado el proyecto y verificado que estás en el correcto, sigue estos pasos para habilitar la API de Google Calendar:
Ve a la Consola de Google Cloud
Haz clic en «APIs & Services»
Haz clic en «Enable APIs and services»
Busca «Google Calendar API»
Haz clic en «Enable» para activar el servicio.
4. Configura la pantalla de consentimiento OAuth
Tras habilitar la API, el siguiente paso es configurar la pantalla de consentimiento OAuth. Esta es la interfaz que verán los usuarios al conectar su calendario con tu aplicación: normalmente incluye el logotipo, el nombre de la app, los permisos solicitados, etc.
Haz clic en la pestaña «OAuth Consent Screen».
Haz clic en «Get Started».
Rellena la sección «App Information». Introduce el nombre de la app y el correo de soporte.
Elige la audiencia. Puede ser interna o externa. Elige interna si la app no será pública y solo usuarios de tu organización podrán conectar sus calendarios. Elige externa si cualquier cuenta pública podrá iniciar sesión.
Introduce tu información de contacto. Google requiere un correo para notificar cambios en el proyecto.
Marca la casilla «Agree to the Google API Services: User Data Policy».
Haz clic en «Create».
5. Crea tu cliente OAuth
Tras configurar la pantalla de consentimiento, puedes crear el cliente OAuth del proyecto. Haz clic en la pestaña «Clients» y luego en «Create Client».
También puedes hacer clic en «Create OAuth Client» en la página de resumen.
Crea clientes para cada plataforma donde se ejecutará tu aplicación. Por ejemplo, si desarrollas una app web y otra para iOS, necesitarás un ID de cliente OAuth distinto para cada plataforma.
En este ejemplo crearemos un cliente «Web Application» y lo llamaremos «Web Client».
En este flujo también debemos configurar los orígenes JavaScript autorizados y las URI de redirección autorizadas.
En Authorized JavaScript origins, indica el dominio/URL que aloja tu app web, por ejemplo: myapp.domain.com
En Authorized redirect URLs, introduce todas las URL a las que redirigirás a los usuarios tras autenticarse. La URL se completará con el código de autorización y debe incluir protocolo.
Asegúrate de incluir también tus URL de redirección a localhost si usas la app en desarrollo. En este ejemplo incluiremos la redirección a localhost.
Tras completar los campos, haz clic en «Create». Google mostrará un modal con el Client ID y el Client Secret. Copia estos datos y guárdalos en un lugar seguro (normalmente en tu archivo .env
, pues los usarás en el flujo de autenticación). También puedes descargar el JSON y guardarlo en un gestor de secretos como 1Password.
Descarga el archivo JSON con el Client Secret o cópialo y guárdalo de forma segura: cuando cierres el modal, ya no podrás copiar el Client Secret.
6. Añade usuarios de prueba
Mientras desarrollas la aplicación localmente, no podrás conectar ninguna cuenta de Google Calendar a menos que incluyas usuarios de prueba. Esto se debe a que la app es externa y aún no está aprobada por Google.
Para añadir usuarios de prueba:
Haz clic en la pestaña «Audience».
Desplázate hasta la sección «Test Users».
Haz clic en «Add Users» y escribe el correo del usuario.
7. Añade los alcances de calendario que vayas a usar
Según la funcionalidad que ofrezca tu app, quizá necesites solicitar distintos alcances (scopes) al usuario al autorizar su cuenta de Google Calendar.
Piensa en los alcances como permisos para acceder a datos privados de la cuenta de Google: listar calendarios, ver eventos, etc.
Google clasifica los alcances en sensibles y no sensibles. Si añades alcances sensibles, tendrás que enviar la app para verificación. Esto también aplica si tu app ya está verificada y añades nuevos alcances sensibles.
Tras añadir todos los alcances necesarios, incluye una justificación y un video de demostración para cada uno antes de enviar la app a verificación.
Para gestionar los alcances:
Haz clic en la pestaña «Data Access».
Haz clic en «Add or remove scopes».
Busca el alcance por nombre o valor y agrégalo.
8. Familiarízate con la API de Google Calendar
Tras configurar el cliente y la pantalla de consentimiento, conviene explorar la página de descripción general de la API de Google Calendar y revisar los endpoints clave, como los de eventos y calendarios.
9. Usa un API de calendario unificado para integrar varios proveedores
Si solo necesitas Google Calendar, puedes saltar este paso. De lo contrario, te recomendamos usar una API de calendario unificada, que ofrezca un solo API para todos los proveedores.
Con un único API integrarás fácilmente Outlook en el futuro sin escribir código nuevo, evitarás mantener varias integraciones y no tendrás que aprender los entresijos de cada API.
Ejemplo de flujo de autorización en Google Calendar
El diagrama muestra un flujo OAuth sencillo que permite a los usuarios conectar Google Calendar con tu aplicación.
Google ofrece clientes para Node.js, Python, etc., pero por simplicidad usaremos llamadas HTTP y TypeScript.
Lado cliente (UI)
Primero, el lado cliente renderiza un botón «Connect Google Calendar».
const googleOauthUrl = getGoogleOAuthUrl()
<button href="googleOauthUrl" rel="noopener noreferrer"> Connect Google Calendar </button>
Recomendamos usar una función utilitaria para obtener la URL OAuth, mejorar la legibilidad y añadir parámetros (estado, forzar permisos, etc.).
const SCOPES = [
"openid",
"email",
"https://www.googleapis.com/auth/calendar.calendarlist",
"https://www.googleapis.com/auth/calendar.events",
"https://www.googleapis.com/auth/calendar.readonly",
// añade más scopes si los necesitas
];
export interface ClientState {
session: Session;
returnUrl?: string;
}
export function stateToB64(session: ClientState): string {
return encode(JSON.stringify(session));
}
export function getGoogleOAuthUrl(
state: ClientState,
) {
const params = new URLSearchParams({
client_id: process.env.GOOGLE_CLIENT_ID || "",
redirect_uri: `${getHostName()}/api/connect/google`, // cambia la URL si es necesario response_type: "code",
scope: SCOPES.join(" "),
prompt: "consent",
access_type: "offline",
state: stateToB64(state),
});
return `https://accounts.google.com/o/oauth2/v2/auth?${params}`;
}
El parámetro prompt admite tres valores: none, consent y select_account.
consent: muestra el modal de permisos aunque el usuario ya haya autorizado, útil si añades más scopes.
select_account: obliga al usuario a seleccionar una cuenta.
none: no muestra pantallas de autenticación ni consentimiento.
Lado API (backend)
Ahora creamos el manejador que recibe el código y los scopes y los intercambia por tokens.
import { z } from "zod";
const successSchema = z.object({
code: z.string(),
scope: z.string(),
state: z.string(),
});
const errorSchema = z.object({
error: z.string(),
});
type ErrorParams = z.infer<typeof errorSchema>;
const querySchema = z.union([successSchema, errorSchema]);
// Handler const googleHanlder: NextApiHandler = async (req, res) => {
try {
const result = querySchema.parse(req.query);
if (isError(result)) {
const q = new URLSearchParams({
error: "ACCESS_DENIED",
});
return res.redirect(`/?${q}`);
}
const { session, returnUr } = stateFromB64(
result.state
);
if (!hasRequiredScopes(result.scope)) {
const q = new URLSearchParams({
error: "MISSING_REQUIRED_PERMISSIONS",
});
return res.redirect(`/?${q}`);
}
const { access_token, refresh_token, id_token, expires_in } =
await exchangeCodeForTokens(result.code);
const { email } = decodeIdToken(id_token);
// Actualiza o inserta la conexión de calendario según tu caso const connection = await upsertConnection(
{
email,
accessToken: access_token,
refreshToken: refresh_token,
expiresInSeconds: expires_in,
status: ConnectionStatus.ACTIVE,
provider: CalendarProvider.GOOGLE,
scopes: result.scope,
reminderCount: 0,
lastRemindedAt: null,
},
session.user
);
const q = new URLSearchParams({
cid: connection.id,
});
if (returnUrl) q.append("returnUrl", returnUrl);
// Redirige de vuelta al cliente con la conexión o errores
res.redirect(
returnUrl ? returnUrl : `/calendars/google?${q}`
);
} catch (e: any) {
let error = JSON.stringify(e);
const querystr =
typeof req.query === "string" ? req.query : JSON.stringify(req.query);
console.error("Error en googleHandler", querystr);
console.error("No se pudo conectar la cuenta de Google", e);
const q = new URLSearchParams({
error,
});
return res.redirect(`/?${q}`);
}
};
También conviene tener funciones utilitarias para intercambiar el código por tokens, decodificar el ID token, obtener el estado en base 64, etc.
export async function exchangeCodeForTokens(code: string) {
const data = new FormData();
data.append("code", code);
data.append("client_id", process.env.GOOGLE_CLIENT_ID || "");
data.append("client_secret", process.env.GOOGLE_CLIENT_SECRET || "");
data.append("redirect_uri", `${getHostName()}/api/connect/google`); // tu URL
data.append("grant_type", "authorization_code");
try {
const result = await fetch("https://oauth2.googleapis.com/token", {
method: "POST",
body: data,
});
const json = await result.json();
if (json.error) throw json;
const parsed = responseSchema.parse(json);
return parsed;
} catch (e) {
console.error("Intercambio fallido");
throw e;
}
}
export function decodeIdToken(idToken: string) {
const data = jwt.decode(idToken);
if (typeof data === "string" || !data?.email) {
throw new Error(`No se pudo analizar id_token: ${idToken}`);
}
return data;
}
function isError(query: Record<string, any>): query is ErrorParams {
return Boolean(query.error);
}
export function stateFromB64(encoded: string): ClientState {
const str = decode(encoded);
return JSON.parse(str) as ClientState;
}
Las variables de entorno GOOGLE_CLIENT_ID
y GOOGLE_CLIENT_SECRET
usadas arriba corresponden al Client ID y Client Secret creados en el Paso 5. Asegúrate de copiarlos; tras cerrar el modal ya no podrás ver el Client Secret.
Inconvenientes al integrar la API de Google Calendar
La verificación puede tardar semanas. Planifica este retraso antes del lanzamiento, pues es común que Google rechace la app en la primera revisión.
Los webhooks caducan tras ~24 h; renuévalos siempre. Usa cron jobs para detectar webhooks que venzan en los próximos 20 min y renuévalos.
Solicita solo los scopes necesarios. Google es exhaustivo y los usuarios desconfían si pides permisos excesivos.
Gestiona cuotas y rate limits. Google impone límites por minuto y responderá con 403 o 429; aplica backoff exponencial.
Evita registrar datos personales. Elimina descripciones, correos de asistentes y demás información sensible al hacer logging.
Integra varios proveedores de calendario con la OneCal Unified Calendar API
En OneCal hemos sincronizado millones de eventos entre Google Calendar, Outlook e iCloud. Sabemos lo que implica integrar varios proveedores, conocer los detalles de cada API y lograr que todo funcione sin fisuras.
Por ello estamos desarrollando una Unified Calendar API que admite Outlook, Google Calendar e iCloud de forma nativa, permitiéndote integrar los principales proveedores mediante un único API robusto y fácil de usar.
Únete a la lista de espera de la Unified Calendar API para que te avisemos en cuanto lancemos el nuevo producto.