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

Publié le

Dans ce guide, nous expliquons pas à pas comment intégrer l’API Google Calendar dans votre application. Nous couvrons la configuration du projet Google Cloud, les portées nécessaires, les pièges courants et un exemple concret de flux d’autorisation.

Prérequis

Ce guide suppose que vous disposez d’une adresse e-mail, d’un domaine utilisable lors de la configuration du projet Google Cloud, d’un peu d’expérience en programmation et d’une idée assez claire de ce que vous voulez construire.

Le guide est aussi utile si vous n’avez jamais travaillé avec l’API Google Calendar et que vous voulez comprendre chaque étape nécessaire pour l’ajouter à 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 d’avoir plusieurs projets. Vérifiez que vous êtes dans le bon projet avant de suivre les étapes ci-dessous.

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 que vous avez un compte et que vous êtes dans le bon projet, suivez ces étapes pour activer les services de l’API Google Calendar :

  1. Allez sur Google Cloud Console
  2. Cliquez sur « APIs & Services » Google Cloud - Click APIs and Services
  3. Cliquez sur « Enable APIs and services » Google Cloud - Enable APIs and services
  4. Recherchez « Google Calendar API » Search for Google Calendar API service
  5. 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, l’étape suivante consiste à configurer l’écran de consentement OAuth. C’est l’écran que les utilisateurs finaux voient lorsqu’ils connectent leur calendrier à votre application. Il affiche généralement votre logo, le nom de l’application, les autorisations demandées et plus encore.

  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 ». Dans cette section, indiquez le nom de votre application et l’e-mail de support client. 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. How to Integrate Google Calendar API Into Your App
  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

Une fois l’écran de consentement configuré, vous pouvez créer le client OAuth de votre 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 fonctionne. Par exemple, si vous développez une application web et une application iOS, il vous faut un Client ID OAuth distinct pour chacune.

Google Cloud - Client Options

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

Google Cloud - Web Client

Dans le même flux, nous définissons aussi les origines JavaScript autorisées et 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 vers lesquelles vous redirigez les utilisateurs après leur authentification auprès de Google. Google ajoute le code d’autorisation à cette URL, qui doit inclure le protocole.

Google Cloud - Setup Redirect URL

Après avoir rempli ces champs, cliquez sur « Create ». Google ouvre alors une fenêtre modale qui affiche le Client ID et le Client Secret. Copiez ces deux valeurs et conservez-les en lieu sûr (généralement dans votre fichier .env, car nous les utilisons dans le flux d’authentification ci-dessous). Vous pouvez aussi télécharger le fichier JSON et le stocker dans un gestionnaire de secrets comme 1Password.

OAuth Client Created - Modal

6. Ajoutez des utilisateurs de test

Pendant le développement local, vous ne pouvez connecter aucun compte Google Calendar tant que vous n’avez pas ajouté d’utilisateurs de test. La raison est que votre application est External et qu’elle n’a pas encore été approuvée par Google.

Pour ajouter des utilisateurs de test :

  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 voulez couvrir avec l’intégration, vous devrez peut-être demander des portées différentes à l’utilisateur lorsqu’il autorise son compte Google Calendar dans votre application.

Les portées sont des permissions que vous demandez aux utilisateurs. Elles permettent à votre application d’accéder aux données privées de leur compte Google, par exemple pour lister leurs calendriers ou lire leurs événements.

Google divise les portées en sensibles et non sensibles. Si vous ajoutez des portées sensibles, vous devez soumettre votre application à la vérification. C’est aussi le cas si votre application est déjà vérifiée et que vous ajoutez d’autres portées sensibles.

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 le client Google est configuré et que les utilisateurs peuvent connecter leurs calendriers, il est temps de se familiariser avec l’API elle-même. Nous vous conseillons de parcourir l’aperçu de l’API Google Calendar et de regarder les endpoints les plus importants, comme Events et Calendars.

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 voulez intégrer, vous pouvez passer cette étape. Sinon, nous vous recommandons d’utiliser une API de calendrier unifiée, qui vous offre une seule API pour tous les fournisseurs.

Avec une API de calendrier unifiée, vous ne construisez et ne maintenez qu’une seule intégration pour tous les fournisseurs. Si vous décidez plus tard de prendre en charge Outlook ou iCloud, vous pouvez les ajouter sans écrire une nouvelle intégration.

Vous évitez aussi de maintenir plusieurs intégrations, de gérer des changements majeurs et de passer du temps à apprendre les spécificités de l’API de chaque fournisseur.

Exemple de flux d’autorisation Google Calendar

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

Google Calendar OAuth flow

Google propose des bibliothèques clientes pour Node.js, Python et d’autres langages. Pour rester simple, nous utilisons ici uniquement des appels HTTP et TypeScript.

Côté client (UI)

La première partie est le 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 construire l’URL OAuth. Le code reste lisible et il devient facile de passer des paramètres, comme l’état du client ou le consentement forcé.


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

Le paramètre prompt accepte l’une de ces trois valeurs : none, consent ou select_account.

La valeur consent est utile lorsqu’un utilisateur a déjà autorisé ses calendriers, mais que vous voulez quand même que Google affiche à nouveau l’écran d’autorisation. C’est le cas, par exemple, lorsque vous ajoutez de nouvelles portées à votre application et que vous voulez que les utilisateurs les approuvent.

Un autre cas d’usage de consent est celui où l’utilisateur n’a pas accordé toutes les portées requises par votre application, et où vous voulez les lui demander à nouveau.

La valeur select_account demande à l’utilisateur de choisir un compte.

La valeur none n’affiche aucun écran d’authentification ni de consentement.

Côté API (Backend)

Construisons ensuite le handler API. Il reçoit le code et les portées envoyés par Google, puis échange le code contre des jetons. Dans cet exemple, nous utilisons zod pour la validation.

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

Comme côté client, nous conseillons de petites fonctions utilitaires pour échanger le code contre des jetons, décoder l’ID token, lire l’état en base64, 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`); // 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;
}

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

  • La vérification peut prendre plusieurs semaines, anticipez donc avant le lancement. Le processus d’approbation prend du temps et il est fréquent que la première soumission soit refusée. Intégrez ce délai à votre planning et informez toutes les parties prenantes.
  • Les webhooks expirent au bout d’environ 24 heures, renouvelez-les systématiquement. Vous pouvez enregistrer des webhooks pour détecter les changements d’un calendrier, mais ils expirent après environ 24 heures. Un cron peut repérer les webhooks qui expirent dans les 20 prochaines minutes et les renouveler.
  • Ne demandez que les portées nécessaires. Il peut sembler malin de demander autant de portées que possible, puisque vous ne savez jamais ce dont la prochaine version de votre application aura besoin. Nous recommandons de ne demander que ce dont votre application a réellement besoin. D’abord, Google est très rigoureux pendant la vérification, et les portées superflues entraînent des refus et des allers-retours jusqu’à l’approbation. Ensuite, les utilisateurs hésitent à accorder des portées qui ne correspondent pas à ce que fait l’application.
  • Gérez les quotas et la limitation de débit. Google applique un quota par minute et par projet, ainsi qu’un quota par minute, par projet et par utilisateur. Si vous dépassez l’un des deux, Google renvoie une erreur 403 usageLimits ou 429 rateLimitExceeded. Utilisez un backoff exponentiel pour rester sous ces limites.
  • Évitez de journaliser des données personnelles. Journaliser est acceptable, mais supprimez d’abord les données personnelles des événements, comme les descriptions et les e-mails des invités.

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

Notre équipe travaille depuis des années avec Google Calendar, Outlook et iCloud Calendar et a construit des intégrations de calendrier qui traitent des milliards d’appels d’API. Nous savons ce qu’il faut pour intégrer plusieurs fournisseurs, apprendre les spécificités de chaque API et faire fonctionner chaque implémentation de manière fiable.

C’est pourquoi nous avons créé Apiroc, une API de calendrier unifiée qui prend en charge Google Calendar, Microsoft Outlook et iCloud Calendar dès le départ. Vous pouvez intégrer tous les grands fournisseurs via une seule API robuste et facile à utiliser.

Vous pouvez commencer gratuitement, tester l’API avec jusqu’à 10 End User Accounts, découvrir ses fonctionnalités et passer à une offre supérieure plus tard si nécessaire. Aucune carte bancaire n’est requise.

FAQ

Pourquoi dois-je ajouter des utilisateurs de test ?

Une application externe non vérifiée ne peut être utilisée que par des comptes de test autorisés, pendant le développement et tant que Google ne l’a pas approuvée.

Combien de temps les webhooks Google Calendar restent-ils actifs ?

Les abonnements aux notifications push expirent au bout d’environ 24 heures. Votre backend doit donc les renouveler avant leur expiration.

Existe-t-il un moyen plus simple d’ajouter ultérieurement des calendriers Outlook ou iCloud ?

Oui. Une API de calendrier unifiée comme Apiroc vous permet d’intégrer Google, Outlook et iCloud via une seule API. Vous économisez ainsi le temps et le coût de développement et de maintenance d’intégrations séparées.

Ai-je besoin de « offline_access » pour les tâches en arrière-plan ?

Oui. Lorsque vous ajoutez access_type=offline à l’URL de consentement, Google renvoie un refresh token, ce qui permet à votre serveur d’appeler l’API même lorsque l’utilisateur est absent.