Come integrare l’API di Google Calendar nella tua app
Pubblicato il
In questa guida spieghiamo passo dopo passo come integrare la Google Calendar API nella tua app. Copriamo la configurazione del progetto Google Cloud, gli scope necessari, i problemi più comuni e un esempio reale di flusso di autorizzazione.
Prerequisiti
Questa guida presuppone che tu abbia un indirizzo email, un dominio da usare durante la configurazione del progetto Google Cloud, un po’ di esperienza di programmazione e un’idea abbastanza chiara di ciò che vuoi costruire.
La guida è utile anche se non hai mai lavorato con la Google Calendar API e vuoi capire ogni passaggio necessario per aggiungerla alla tua app.
Come usare e integrare la Google Calendar API nella tua app
1. Registrati alla Google Developer Console
Se non hai un account Google Developer Console, creane uno su https://console.cloud.google.com/.
2. Crea o scegli un progetto Google Cloud esistente
Google Cloud permette a sviluppatori e organizzazioni di avere più progetti. Assicurati di essere nel progetto giusto prima di eseguire i passaggi qui sotto.
Fai clic sul menu a discesa dei progetti in alto a sinistra. Il nome di solito corrisponde al nome del tuo progetto.
Seleziona un progetto esistente oppure crea un nuovo progetto cliccando "New Project" in alto a destra del modale.
3. Abilita i servizi Google Calendar API
Una volta che hai un account e sei nel progetto giusto, segui questi passaggi per abilitare i servizi Google Calendar API:
- Vai alla Google Cloud Console
- Fai clic su “APIs & Services”

- Fai clic su “Enable APIs and services”

- Cerca “Google Calendar API”

- Fai clic su "Enable" per abilitare il servizio.

4. Configura la schermata di consenso OAuth
Dopo aver abilitato i servizi Google Calendar API, il passo successivo è configurare la schermata di consenso OAuth. È la schermata che gli utenti finali vedono quando collegano il loro calendario alla tua app. Di solito mostra il logo, il nome dell’app, i permessi che richiedi e altro.
- Clicca sulla scheda "OAuth Consent Screen".

- Clicca "Get Started".

- Compila la sezione “App Information”. Inserisci il nome dell’app e l’email di supporto.

- Scegli il pubblico. Può essere interno o esterno. Scegli interno se l’app non sarà pubblica e solo gli utenti della tua organizzazione possono collegarsi; esterno se possono accedere anche account pubblici.

- Inserisci le informazioni di contatto. Google richiede un’email per notificare eventuali modifiche al progetto.

- Spunta la casella "Agree to the Google API Services: User Data Policy".

- Clicca “Create”.

5. Crea il tuo client OAuth
Una volta configurata la schermata di consenso OAuth, puoi creare il client OAuth per il tuo progetto. Clicca la scheda “Clients” e poi “Create Client”.
In alternativa, clicca "Create OAuth Client" nella pagina di panoramica.
Puoi creare un client per ogni piattaforma su cui gira la tua app. Ad esempio, se sviluppi una web app e un’app iOS, ti serve un ID client OAuth separato per ciascuna.
In questo esempio, creiamo un client “Web Application” chiamato “Web Client”.
Nello stesso flusso impostiamo anche gli authorized JavaScript origins e gli authorized redirect URI.
Nel campo Authorized JavaScript origins inserisci il dominio/URL che ospita la tua web app, ad esempio: myapp.domain.com
Nel campo Authorized redirect URIs inserisci tutti gli URL a cui reindirizzerai gli utenti dopo l’autenticazione con Google. Google aggiunge il codice di autorizzazione a questo URL, e l’URL deve includere il protocollo.
Dopo aver compilato i campi, clicca “Create”. Google apre quindi un modale che mostra Client ID e Client Secret. Copia entrambi i valori e conservali in un luogo sicuro (di solito nel file .env, perché li usiamo nel flusso di autenticazione qui sotto). Puoi anche scaricare il file JSON e salvarlo in un gestore di segreti come 1Password.
6. Aggiungi alcuni utenti di test
Durante lo sviluppo in locale non puoi collegare alcun account Google Calendar finché non aggiungi alcuni utenti di test. Il motivo è che l’app è esterna e non è ancora stata approvata da Google.
Per aggiungere utenti di test:
- Clicca la scheda “Audience”.

- Scorri fino alla sezione “Test Users”.

- Clicca “Add Users” e inserisci l’email dell’utente.

7. Aggiungi gli scope di calendario che intendi usare
A seconda del caso d’uso che vuoi risolvere con l’integrazione, potresti dover richiedere scope diversi quando gli utenti autorizzano il loro account Google Calendar nella tua app.
Pensa agli scope come ai permessi che chiedi agli utenti. Permettono alla tua app di accedere ai dati privati del loro account Google, ad esempio per elencare i calendari o leggere gli eventi.
Google divide gli scope in sensibili e non sensibili. Se aggiungi scope sensibili, devi inviare l’app per la verifica. Lo stesso vale se l’app è già verificata e aggiungi altri scope sensibili.
Per gestire gli scope:
- Clicca la scheda "Data Access".

- Clicca "Add or remove scopes".

- Cerca lo scope per nome o valore e aggiungilo.

8. Familiarizza con la Google Calendar API
Ora che l’app client di Google è configurata e tutte le informazioni necessarie perché gli utenti colleghino i loro calendari sono al loro posto, è il momento di familiarizzare con la Google Calendar API stessa.
Consigliamo di leggere la pagina panoramica della Google Calendar API e di guardare gli endpoint più importanti, come quelli di Events e Calendars.
9. Usa un servizio Unified Calendar API per integrare più provider con una sola API
Se Google Calendar è l’unico calendario che vuoi integrare, puoi saltare questo passaggio. Altrimenti ti consigliamo di usare una Unified Calendar API, che ti offre un’unica API per tutti i provider di calendari.
Con una Unified Calendar API costruisci e mantieni una sola integrazione per tutti i provider. Se in seguito decidi di supportare Outlook o iCloud, puoi aggiungerli senza scrivere una nuova integrazione.
Eviti anche di mantenere più integrazioni, di gestire breaking change e di passare tempo a imparare i dettagli dell’API di ogni provider.
Esempio di flusso di autorizzazione Google Calendar
Il diagramma qui sotto mostra un semplice flusso OAuth che permette agli utenti di collegare il loro Google Calendar alla tua app.
Google offre librerie client per Node.js, Python e altri linguaggi. Per semplicità, usiamo solo chiamate HTTP semplici e TypeScript per mostrare il flusso di autorizzazione.
Lato Client (UI)
La prima parte è il lato client (UI), dove mostriamo un pulsante “Connect Google Calendar”.
const googleOauthUrl = getGoogleOAuthUrl()
<button href="googleOauthUrl" rel="noopener noreferrer"> Connect Google Calendar </button>
Consigliamo di usare una funzione di utilità per costruire l’URL OAuth di Google. Mantiene il codice leggibile e rende facile passare parametri come lo stato del client o il consenso forzato.
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>",
// add more scopes as needed
];
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`, // change the redirect URL as needed
response_type: "code",
scope: SCOPES.join(" "),
prompt: "consent",
access_type: "offline",
state: stateToB64(state),
});
return `https://accounts.google.com/o/oauth2/v2/auth?${params}`;
}
Il parametro prompt può avere uno di tre valori: none, consent o select_account.
Il valore consent è utile quando un utente ha già autorizzato i suoi calendari, ma vuoi comunque che Google mostri di nuovo la schermata di autorizzazione. Succede, ad esempio, quando aggiungi nuovi scope alla tua app e vuoi che gli utenti li approvino.
Un altro caso per consent è quando l’utente non ha concesso tutti gli scope richiesti dalla tua app, quindi vuoi chiederli di nuovo.
Il valore select_account chiede all’utente di scegliere un account.
Il valore none non mostra alcuna schermata di autenticazione o consenso.
Lato API (Backend)
Creiamo poi l’handler API. Riceve il codice e gli scope da Google e scambia il codice con i token.
In questo esempio usiamo zod per la validazione.
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);
// Update or insert the calendar connection, depending on your use case
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);
// The API redirects back to the client side, returning the connection, or errors if any
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 in googleHandler", querystr);
console.error("Failed to connect Google account", e);
const q = new URLSearchParams({
error,
});
return res.redirect(`/?${q}`);
}
};
Come sul lato client, consigliamo piccole funzioni di utilità per scambiare il codice con i token, decodificare l’ID token, leggere lo stato da base64 e così via.
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`); // your 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("Exchange failed");
throw e;
}
}
export function decodeIdToken(idToken: string) {
const data = jwt.decode(idToken);
if (typeof data === "string" || !data?.email) {
throw new Error(`Could not parse 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;
}
Possibili problemi con l’integrazione della Google Calendar API
- La verifica può richiedere diverse settimane, quindi pianifica in anticipo e considera questo ritardo nella tua tabella di marcia. Il processo di approvazione richiede tempo ed è comune ricevere un rifiuto al primo invio. Inserisci questo ritardo nella tua pianificazione e informa tutte le persone coinvolte.
- I webhook scadono dopo circa 24 ore, quindi rinnovali sempre. Puoi registrare webhook per rilevare le modifiche a un calendario, ma scadono dopo circa 24 ore. Un cron job può trovare i webhook che scadono nei prossimi 20 minuti e rinnovarli.
- Richiedi solo gli scope di cui hai bisogno. Può sembrare furbo richiedere il maggior numero possibile di scope, visto che non sai mai di cosa avrà bisogno la prossima versione della tua app. Consigliamo di richiedere solo ciò che serve davvero alla tua app. Primo, Google è molto rigorosa durante la verifica e gli scope superflui portano a rifiuti e a un continuo scambio finché non ottieni l’approvazione. Secondo, gli utenti esitano a concedere permessi che non hanno senso rispetto a ciò che fa l’app.
- Gestisci quote e rate limiting. Google applica una quota al minuto per progetto e una quota al minuto per progetto e per utente. Se superi una delle due, Google restituisce un errore 403 usageLimits o 429 rateLimitExceeded. Usa il backoff esponenziale e tattiche simili per restare sotto questi limiti.
- Evita di registrare dati personali nei log. Loggare va bene, ma rimuovi prima i dati personali degli eventi, perché gli eventi contengono di solito descrizioni, email dei partecipanti e altri dettagli privati.
Integra più provider di calendario con la Apiroc Unified Calendar API
Il nostro team lavora da anni con Google Calendar, Outlook e iCloud Calendar e ha costruito integrazioni di calendario che gestiscono miliardi di chiamate API. Sappiamo cosa serve per integrare più provider, imparare i dettagli di ogni API e mantenere ogni implementazione affidabile nel tempo.
Per questo abbiamo creato Apiroc, una Unified Calendar API che supporta Google Calendar, Microsoft Outlook e iCloud Calendar fin da subito. Puoi integrare tutti i principali provider con un’unica API robusta e facile da usare.
Puoi iniziare gratuitamente, testare l’API con un massimo di 10 End User Account, scoprirne le funzionalità e fare l’upgrade in seguito se ti serve di più. Non è richiesta alcuna carta di credito.
Domande frequenti
Perché devo aggiungere utenti di test al mio client OAuth di Google?
Un’app esterna non verificata può essere usata solo da account di test autorizzati, durante lo sviluppo e finché Google non la approva.
Per quanto tempo restano attivi i webhook di Google Calendar?
Le sottoscrizioni alle notifiche push scadono dopo circa 24 ore. Il backend deve quindi rinnovarle prima della scadenza.
Esiste un modo più semplice per aggiungere in seguito i calendari Outlook o iCloud?
Sì. Una Unified Calendar API come Apiroc ti permette di integrare Google, Outlook e iCloud tramite un’unica API. Così risparmi il tempo e i costi di sviluppo e manutenzione di integrazioni separate.
Ho bisogno di “offline_access” per i processi in background?
Sì. Quando aggiungi access_type=offline all’URL di consenso, Google restituisce un refresh token, così il tuo server può chiamare l’API anche quando l’utente non è presente.
