Comment intégrer l’API Google Calendar dans votre application

Auteurs
Publié le

Intégrez tous les calendriers à l’aide d’une seule API

Inscrivez-vous sur la liste d’attente de notre Unified Calendar API pour obtenir l’accès à notre Unified Calendar API, qui vous permet d’intégrer tous les fournisseurs de calendriers dans votre application grâce à une seule API.

Inscrivez-vous gratuitementAucune carte de crédit requise !

Dans ce guide, nous expliquerons en détail comment intégrer l’API Google Calendar dans votre application, en couvrant la configuration du projet Google Cloud, les portées requises, les pièges à éviter et un exemple concret d’autorisation.

Prérequis

Ce guide suppose que vous disposez d’une adresse e-mail, d’un domaine existant prêt à être utilisé lors de la configuration du projet Google Cloud, de quelques notions de programmation et d’une idée assez claire de ce que vous souhaitez construire.

Il sera également utile si vous n’avez jamais travaillé avec l’API Google Calendar et que vous souhaitez vous familiariser avec toutes les étapes nécessaires pour l’intégrer à votre application.

Comment utiliser et intégrer l’API Google Calendar dans votre application

1. Inscrivez-vous à la Google Developer Console

Si vous ne possédez pas encore de compte Google Developer Console, créez-en un à l’adresse https://console.cloud.google.com/.

2. Créez ou sélectionnez un projet Google Cloud existant

Google Cloud permet aux développeurs et aux organisations de gérer plusieurs projets. Assurez-vous d’être dans le bon projet pour les opérations suivantes.

Cliquez sur le menu déroulant des projets en haut à gauche de l’écran. Le nom correspond généralement à celui de votre projet.

Google Cloud Home

Sélectionnez un projet existant ou créez-en un nouveau en cliquant sur « New Project » en haut à droite de la fenêtre modale.

Google Cloud - Select Project

3. Activez les services de l’API Google Calendar

Une fois votre compte créé et le bon projet sélectionné, suivez ces étapes pour activer les services de l’API Google Calendar :

  1. Cliquez sur « APIs & Services »

    Google Cloud - Click APIs and Services
  2. Cliquez sur « Enable APIs and services »

    Google Cloud - Enable APIs and services
  3. Recherchez « Google Calendar API »

    Search for Google Calendar API service
  4. Cliquez sur « Enable » pour activer le service.

    Enable Google Calendar API service

4. Configurez l’écran de consentement OAuth

Après avoir activé les services de l’API Google Calendar, configurez l’écran de consentement OAuth. C’est l’interface que les utilisateurs voient lorsqu’ils connectent leur calendrier à votre application : logo, nom de l’appli, autorisations demandées, etc.

  1. Cliquez sur l’onglet « OAuth Consent Screen ».

    Click OAuth Consent Screen
  2. Cliquez sur « Get Started ».

    Click Get Started
  3. Remplissez la section « _App Information_ »**. Indiquez le nom de votre application et l’e-mail de support.

    Fill in the “App Information” section
  4. Choisissez l’audience. Sélectionnez Internal si votre appli n’est pas publique et que seuls les utilisateurs de votre organisation peuvent connecter leur calendrier. Choisissez External si n’importe quel compte public peut se connecter, qu’il fasse partie de votre organisation ou non.

    Choose the audience
  5. Renseignez vos coordonnées. Google exige une adresse e-mail pour vous notifier des modifications apportées à votre projet.

    Fill in your contact information.webp
  6. Cochez la case « Agree to the Google API Services: User Data Policy ».

    Check the Agree to the Google API Services
  7. Cliquez sur « Create ».

    Click “Create”

5. Créez votre client OAuth

Après avoir configuré l’écran de consentement, créez votre client OAuth pour le projet. Cliquez sur l’onglet « Clients », puis sur « Create Client ».

Vous pouvez aussi cliquer sur « Create OAuth Client » depuis la page d’aperçu.

Create OAuth Client

Vous pouvez créer un client pour chaque plateforme sur laquelle votre application fonctionnera (web, iOS, etc.).

Google Cloud - Client Options

Dans cet exemple, nous créons simplement un client « Web Application » nommé « Web Client ».

Google Cloud - Web Client

Nous définissons également les origines JavaScript autorisées ainsi que les URI de redirection autorisées.

Dans le champ Authorized JavaScript origins, saisissez le domaine/URL hébergeant votre application web, par exemple : myapp.domain.com

Google Cloud - Authorized Domains

Dans Authorized redirect URIs, indiquez toutes les URL de redirection utilisées après l’authentification. L’URL recevra le code d’autorisation et doit inclure le protocole.

Google Cloud - Setup Redirect URL

Assurez-vous également d’ajouter vos URL de redirection localhost à la liste blanche si l’application est utilisée en phase de développement. Dans cet exemple, nous ajoutons également notre URL localhost.

Après avoir rempli ces champs, cliquez sur « Create ». Google ouvrira une fenêtre modale affichant le Client ID et le Client Secret. Copiez-les et conservez-les en lieu sûr (souvent dans un fichier .env). Vous pouvez aussi télécharger le fichier JSON contenant ces informations et le stocker dans un gestionnaire de secrets comme 1Password.

OAuth Client Created - Modal

Téléchargez le fichier JSON contenant le Client Secret ou copiez-le immédiatement ; après fermeture de la modale, vous ne pourrez plus le récupérer.

6. Ajoutez des utilisateurs de test

En développement local, vous ne pourrez pas connecter de comptes Google Calendar, sauf si vous ajoutez des utilisateurs de test. Cela est dû au fait que votre appli est External et n’a pas encore été approuvée par Google.

  1. Cliquez sur l’onglet « Audience ».

    Google Cloud - Audience Tab
  2. Faites défiler jusqu’à la section « Test Users ».

    Test Users Section
  3. Cliquez sur « Add Users », puis saisissez l’e-mail de l’utilisateur.

    Add Test users by email

7. Ajoutez les portées calendrier nécessaires

Selon le cas d’usage que vous visez, vous devrez peut-être demander des portées (permissions) différentes à l’utilisateur lorsqu’il autorise son compte Google Calendar.

Les portées sont divisées en sensibles et non sensibles. Si vous ajoutez des portées sensibles, vous devrez soumettre votre appli pour vérification, et ce sera aussi le cas si vous en ajoutez d’autres plus tard.

Après avoir ajouté toutes les portées nécessaires, justifiez chacune d’elles et fournissez une vidéo de démonstration : c’est obligatoire lors de la vérification.

Pour gérer les portées :

  1. Cliquez sur l’onglet « Data Access ».

    Data Access Tab
  2. Cliquez sur « Add or remove scopes ».

    Add Or Remove Scopes Button
  3. Recherchez la portée par nom ou par valeur, puis ajoutez-la.

    Select Scopes Section

8. Familiarisez-vous avec l’API Google Calendar

Maintenant que nous avons configuré l’application cliente Google et toutes les informations nécessaires, il est utile d’explorer l’aperçu de l’API Google Calendar et les principaux endpoints (Events, Calendar, etc.).

9. Utilisez un service d’API de calendrier unifiée pour intégrer plusieurs fournisseurs via une seule API

Si Google Calendar est le seul calendrier que vous intégrez, passez cette étape. Sinon, nous vous recommandons d’utiliser une API de calendrier unifiée, qui offre une seule API pour tous les fournisseurs.

Ainsi, vous n’aurez qu’une intégration à maintenir et pourrez ajouter Outlook, par exemple, sans écrire de nouveau code.

Vous éviterez aussi de gérer plusieurs intégrations, changements majeurs et spécificités d’API pour chaque fournisseur.

Exemple de flux d’autorisation Google Calendar

Le schéma ci-dessous illustre un simple flux OAuth permettant aux utilisateurs de connecter leur Google Calendar à votre application.

Google Calendar OAuth flow

Google propose des clients Node.js, Python, etc., mais pour la simplicité nous utiliserons uniquement des appels HTTP et TypeScript.

Côté client (UI)

La première partie se trouve côté client/UI où nous affichons un bouton « Connect Google Calendar ».

const googleOauthUrl = getGoogleOAuthUrl()
<button href="googleOauthUrl" rel="noopener noreferrer"> Connect Google Calendar </button>

Nous recommandons d’utiliser une fonction utilitaire pour générer l’URL OAuth (meilleure lisibilité, ajout de paramètres, 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",
 // 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`,
 response_type: "code",
 scope: SCOPES.join(" "),
 prompt: "consent",
 access_type: "offline",
 state: stateToB64(state),
});
 return `https://accounts.google.com/o/oauth2/v2/auth?${params}`;
}

Le paramètre prompt accepte trois valeurs : none, consent ou select_account.

  • consent permet d’afficher la fenêtre d’autorisation, même si l’utilisateur a déjà donné son accord (utile si vous ajoutez de nouvelles portées).

  • select_account force la sélection de compte.

  • none n’affiche aucun écran.

Côté API (Backend)

Construisons ensuite le handler API qui récupère le code renvoyé par Google et l’échange contre des jetons.

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);

 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);

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}`);
}
};

Nous conseillons également d’avoir des fonctions utilitaires pour l’échange code → jetons, le décodage du token ID, la récupération de l’état, 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`);
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;
}

Les variables d’environnement process.env.GOOGLE_CLIENT_ID et process.env.GOOGLE_CLIENT_SECRET proviennent du Client ID et Client Secret créés à l’étape 5. Copiez-les bien : après fermeture de la fenêtre, vous ne pourrez plus récupérer le Client Secret.

Pièges à éviter lors de l’intégration de l’API Google Calendar

  • La vérification peut prendre plusieurs semaines ; anticipez avant le lancement. Le processus est long et il est fréquent d’obtenir un refus initial.

  • Les webhooks expirent au bout d’environ 24 h ; renouvelez-les systématiquement. Par exemple avec un cron qui repère les webhooks expirant dans 20 minutes.

  • Ne demandez que les portées nécessaires. Trop de permissions compliquent la vérification et rebutent les utilisateurs.

  • Gérez les quotas et le rate-limiting. Google applique des limites par minute/projet et par minute/utilisateur. Utilisez l’exponential back-off.

  • Évitez de journaliser des données personnelles. Supprimez descriptions d’événements, e-mails d’invités, etc.

Intégrez plusieurs fournisseurs de calendriers grâce à l’API de calendrier unifiée OneCal

Chez OneCal, nous avons synchronisé des millions d’événements entre Google Calendar, Outlook et iCloud. Forts de cette expérience, nous construisons une API de calendrier unifiée prenant en charge ces trois fournisseurs dès le départ.

Rejoignez notre liste d’attente pour l’API de calendrier unifiée afin d’être informé de son lancement.