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

Publié le

Dans notre précédent article sur comment intégrer l’API Google Calendar à votre application, nous avons détaillé, étape par étape, ce qu’un développeur doit faire pour connecter Google Calendar à son application.

Dans cet article, nous faisons la même chose pour l’API Outlook Calendar. Nous verrons l’enregistrement d’application Azure, les portées, la vérification, les pièges d’intégration les plus courants et des exemples de code concrets.

Prérequis

Ce guide suppose que vous disposez déjà d’un compte Microsoft Travail ou Développeur avec accès à Azure Active Directory (désormais appelé Microsoft Entra ID).

Notez qu’il n’est plus possible de créer des applications en dehors d’un annuaire. Si vous n’en avez pas encore, rejoignez le programme Microsoft 365 Developer ou inscrivez-vous à Azure.

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

Étape 1 : Connectez-vous au portail Microsoft Azure

Ouvrez la page de connexion au portail Microsoft Azure et connectez-vous avec votre compte.

La page du portail Microsoft Azure.

Sign in to the Microsoft Azure Portal

Étape 2 : Enregistrer une nouvelle application

Après vous être connecté au portail Microsoft Azure :

  1. Accédez à Azure Active Directory. Azure App Directory Home
  2. Recherchez « App Registrations » dans la barre de recherche. Search App Registrations
  3. Cliquez sur « App Registrations ». Click App Registrations
  4. Cliquez sur « New registration ». Click New Registration
  5. Renseignez les champs obligatoires : Azure Active Directory - Register the application
    1. Nom : le nom de votre application. C’est celui que les utilisateurs verront sur l’écran de consentement.
    2. Types de comptes pris en charge : le bon choix dépend du type d’application que vous développez (usage interne ou multi-tenant). Dans cet exemple, nous choisirons « Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) », afin que les utilisateurs de n’importe quelle organisation (y compris Outlook.com) puissent utiliser l’application. C’est la meilleure option pour les produits SaaS et les autres applications multi-tenant.
    3. URI de redirection : ce champ est facultatif, car tous les types d’application n’en ont pas besoin. Pour une application web, vous en aurez très probablement besoin, puisque c’est l’URI où Azure envoie les réponses OAuth. Dans la liste « Select a platform », choisissez Web , puis saisissez l’URI de redirection (par ex. https://votreapp.com/auth/callback ). Pour un flux d’authentification côté serveur, une URI Web est le bon choix. Assurez-vous que le domaine est accessible et qu’il vous appartient.
    4. Cliquez sur Register .
    5. Après le clic sur « Register », Azure Active Directory crée votre application et affiche la page de présentation, où vous pouvez copier l’ID client et l’ID locataire. L’ Application (client) ID est un GUID qui identifie votre app. L’ ID locataire n’est pas toujours nécessaire. Pour les apps multi-tenant, on utilise généralement l’endpoint common , mais l’ID de locataire reste pratique pour vos tests dans votre propre tenant. Application Created

Étape 3 : Configurer les autorisations d’API

Une fois l’application enregistrée, il est temps de configurer les autorisations calendrier. Ces autorisations sont affichées pendant le flux OAuth, ce qui permet à l’utilisateur de voir les portées demandées par votre application avant d’accorder l’accès à ses calendriers.

Par défaut, votre application ne reçoit que l’autorisation « User.Read ». Si vous souhaitez seulement connecter l’utilisateur et lire son profil, vous pouvez ignorer cette étape.

Pour ajouter des autorisations d’API, suivez ces étapes :

  1. Cliquez sur l’onglet « Manage » dans la barre latérale gauche.
  2. Cliquez sur « API Permissions ». Cliquez sur API Permissions
  3. Cliquez sur le bouton « + Add a permission ». Cliquez sur le bouton _Add a permission_
  4. Trouvez la carte « Microsoft Graph » (c’est généralement la première carte du panneau qui s’ouvre à droite après le clic sur « Add a permission »). Cliquez sur la carte _Microsoft Graph_
  5. Choisissez entre « Delegated permissions » et « Application permissions ». Les permissions déléguées sont le bon choix lorsque votre application appelle l’API au nom de l’utilisateur connecté. Les permissions d’application, elles, conviennent lorsque l’application tourne comme service en arrière-plan, sans utilisateur connecté. Dans cet exemple, nous choisirons « Delegated Permissions ». Cliquez sur _Delegated Permissions_
  6. Recherchez « Calendars » : la recherche affiche toutes les autorisations liées aux calendriers. Ne sélectionnez que celles dont votre application a vraiment besoin pour fonctionner correctement. La plupart du temps, il s’agit de « Calendars.ReadWrite » et « Calendars.ReadWrite.Shared » (si vous avez besoin des calendriers partagés). Ces portées sont déléguées à l’utilisateur et ne nécessitent généralement pas de consentement admin, mais gardez à l’esprit que certaines organisations restreignent le consentement utilisateur. Si un utilisateur d’un tenant externe n’est pas autorisé à consentir, un administrateur de ce tenant devra accorder le consentement à votre app (généralement via une invite ou une URL de consentement admin). Recherchez les _autorisations Calendars_

Étape 4 : Activer les jetons d’identité (ID Tokens)

Toutes les applications n’ont pas besoin de cette étape, mais si vous souhaitez accéder aux informations de profil de l’utilisateur, comme le nom, l’adresse e-mail ou l’URL de la photo de profil, vous devez activer l’option ID Tokens sous Manage -> Authentication.

Grâce aux jetons d’identité, votre application peut identifier l’utilisateur juste après la connexion de son calendrier, sans appel API supplémentaire.

Enable ID Tokens option

Étape 5 : Générer un secret client

Nous recommandons d’effectuer toutes les opérations calendrier (lectures, écritures, mises à jour, etc.) côté serveur. C’est pourquoi vous devez générer un secret client.

Pour générer un secret client, suivez ces étapes :

  1. Cliquez sur l’onglet Certificates & secrets . Click the “Certificates & secrets tab”
  2. Cliquez sur New client secret . Click “New client secret”
  3. Saisissez une description et une date d’expiration. Enter a description and an expiration date

Une fois le secret généré, copiez-le immédiatement et stockez-le en lieu sûr (souvent dans votre fichier .env).

Étape 6 : Image de marque et vérification

Dans la section Branding & Properties de l’enregistrement, vous pouvez définir un logo et des informations (description, URL des conditions d’utilisation, etc.). C’est facultatif, mais nous le recommandons pour obtenir un écran de consentement soigné. Il est important de définir un domaine éditeur (en général votre domaine personnalisé, vérifié dans Azure AD), car il évite que l’app apparaisse comme « non vérifiée » au moment du consentement. Pour une app multi-tenant, Microsoft attend désormais une vérification éditeur pour un usage étendu. Sans cette vérification, les utilisateurs extérieurs à votre tenant peuvent être bloqués au moment du consentement à cause des politiques de sécurité introduites en novembre 2020.

Branding & Properties screen

Étape 7 : Se familiariser avec l’API Microsoft Graph Calendar

Une fois l’application configurée, explorez la documentation de l’API Microsoft Calendar Graph pour vous familiariser avec les points de terminaison de création, de mise à jour et de suppression d’événements.

Étape 8 : Envisager une API de calendrier unifiée pour intégrer tous les fournisseurs avec une seule API

L’API Microsoft Graph est plutôt bien documentée, mais nous recommandons tout de même de regarder du côté d’une API de calendrier unifiée, qui vous permet d’intégrer tous les fournisseurs via une seule API.

Avec une API de calendrier unifiée, vous implémentez une seule API dans votre application et prenez en charge tous les fournisseurs, quelles que soient leurs limitations ou les différences entre leurs APIs.

Autre avantage d’une API unique pour tous les calendriers : vous n’avez plus à maintenir plusieurs intégrations, à gérer les changements incompatibles ni à traiter des cas limites auxquels vous n’auriez jamais pensé.

L’API de calendrier unifiée Apiroc

Exemple de flux d’autorisation Outlook Calendar

Le diagramme ci-dessous montre un flux OAuth simple pour Outlook Calendar, qui permet aux utilisateurs de connecter leur calendrier Outlook à votre application.

Outlook OAuth 2.0 Flow

Consultez la documentation Microsoft sur le flux OAuth2 si vous voulez en savoir plus sur le flux OAuth2 de Microsoft.

Côté client (UI)

const microsoftOauthUrl = getMicrosoftOAuthUrl()
<button href="microsoftOauthUrl"   rel="noopener noreferrer"> Connect Outlook Calendar </button>
export const SCOPES = [
  "openid",
  "email",
  "profile",
  "offline_access",
  "Calendars.ReadWrite",
  "User.Read",
];

export interface ClientState {
  session: Session;
  returnUrl?: string;
}

export function stateToB64(session: ClientState): string {
  return encode(JSON.stringify(session));
}

export function getMicrosoftOAuthUrl(
  state: ClientState,
) {
  const nonce = uuid();
  const TENANT_ID = process.env.NEXT_PUBLIC_MICROSOFT_TENANT_ID;
  const params = new URLSearchParams({
    client_id: process.env.MICROSOFT_CLIENT_ID || "",
    redirect_uri: `${getHostName()}/api/connect/microsoft`,
    response_type: "code id_token",
    scope: SCOPES.join(" "),
    prompt: "consent",
    response_mode: "form_post",
    state: stateToB64(state),
    nonce,
  });
  return `https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/authorize?${params}`;
}
  • Le paramètre prompt accepte l’une de ces quatre valeurs : login , none , consent ou select_account .
  • Le paramètre response_mode accepte query , fragment ou form_post . Nous avons choisi form_post , car il demande à Microsoft d’envoyer une requête POST vers notre URI de redirection (côté serveur).

Côté API (Backend)

Ensuite, construisons le handler API. Il reçoit le code et les portées envoyés par le serveur Microsoft, puis les échange contre des jetons.

Dans cet exemple, nous utilisons zod pour la validation.

const successSchema = z.object({
  code: z.string(),
  state: z.string(),
  id_token: z.string(),
  session_state: z.string().optional(),
});

const errorSchema = z.object({
  error: z.string(),
  error_description: z.string().optional(),
});
type ErrorParams = z.infer<typeof errorSchema>;

const querySchema = z.union([successSchema, errorSchema]);

function isError(query: Record<string, any>): query is ErrorParams {
  return Boolean(query.error);
}

const microsoftHandler: NextApiHandler = async (req, res) => {
  try {
    const result = querySchema.parse(req.body);
    if (isError(result)) {
      const q = new URLSearchParams({
        error: "ACCESS_DENIED",
        provider: CalendarProvider.MICROSOFT,
      });

      console.error({ result });
      return res.redirect(302, `/?${q}`);
    }

    const { session, returnUrl } = stateFromB64(result.state);
    const { email } = decodeIdToken(result.id_token);
    const { access_token, refresh_token, expires_in, scope } =
      await exchangeCodeForTokens(result.code);

    const connection = await upsertConnection(
      {
        email,
        accessToken: access_token,
        refreshToken: refresh_token,
        expiresInSeconds: expires_in,
        status: ConnectionStatus.ACTIVE,
        provider: CalendarProvider.MICROSOFT,
        scopes: scope,
      },
      session.user
    );

    const q = new URLSearchParams({
      cid: connection.id,
    });
    if (returnUrl) q.append("returnUrl", returnUrl);

    res.redirect(302, returnUrl ? returnUrl : `/calendars/microsoft?${q}`);
  } catch (e: any) {
    let error = JSON.stringify(e);

    const querystr =
      typeof req.query === "string" ? req.query : JSON.stringify(req.query);

    const q = new URLSearchParams({
      error,
      provider: CalendarProvider.MICROSOFT,
    });
    return res.redirect(302, `/?${q}`);
  }
};

export default microsoftHandler;

Comme côté client, nous recommandons de prévoir de petites fonctions utilitaires, par exemple pour échanger le code contre des jetons.

const TENANT_ID = process.env.MICROSOFT_TENANT_ID;

export async function exchangeCodeForTokens(code: string) {
  const data = new FormData();
  data.append("client_id", process.env.MICROSOFT_CLIENT_ID || "");
  data.append("scope", SCOPES.join(" "));
  data.append("code", code);
  data.append("redirect_uri", `${getHostName()}/api/connect/microsoft`);
  data.append("grant_type", "authorization_code");
  data.append("client_secret", process.env.MICROSOFT_CLIENT_SECRET || "");

  try {
    const result = await fetch(
      `https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/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;
  }
}

Pièges fréquents de l’intégration Outlook Calendar

  • La vérification peut être longue et frustrante : des milliers, voire des millions de développeurs construisent sur Outlook, et Microsoft examine donc un grand nombre de soumissions chaque jour. Remplissez soigneusement tous les champs lors de la soumission et prévoyez le délai de vérification dans votre feuille de route.

  • Ne demandez que les portées indispensables : l’équipe Microsoft examine les apps de près, alors ne demandez que ce dont votre application a vraiment besoin pour ses fonctionnalités. Cela facilite l’approbation et aide aussi au moment où les utilisateurs accordent l’accès. Un utilisateur est vite troublé quand une app réclame des portées sans rapport avec ses fonctionnalités réelles.

  • Les webhooks expirent, pensez à les renouveler : si vous enregistrez des webhooks pour suivre les changements de calendrier, mettez en place une tâche en arrière-plan qui tourne toutes les quelques heures et renouvelle chaque abonnement sur le point d’expirer.

  • Limitation et throttling : Microsoft applique des règles strictes de limitation et de throttling. Évitez de récupérer les éléments un par un et ajoutez un contrôle de débit à vos propres appels API pour ne pas déclencher la fameuse erreur « MailboxConcurrency ». Le tableau ci-dessous résume ces limites :

    PortéeLimiteRemarques
    Par boîte (mailbox) (app ID + boîte)10 000 requêtes / 10 min et 4 requêtes simultanéesErreur « MailboxConcurrency ».
    Téléversement150 Mo PATCH/POST/PUT totaux / 5 min par boîtePeut survenir lors de pièces jointes volumineuses.
    Graph global130 000 requêtes / 10 s par app tous tenants confondusRare, mais possible lors de gros back-fills SaaS.
    Étiquette de repriseSur 429 ou 503/504, consulter l’entête Retry-After et appliquer un back-off exponentielLe Graph continue de throttler si vous insistez chaque seconde.
  • Pièges liés aux fuseaux horaires : dans Outlook, un utilisateur peut saisir manuellement le nom de son fuseau horaire (vous voyez où cela mène), alors assurez-vous que votre code gère aussi ce cas.

  • Problèmes de consentement : comme indiqué dans la section sur les portées, Calendars.ReadWrite est une permission déléguée. Beaucoup de tenants autorisent le consentement utilisateur, mais certains le bloquent. Préparez-vous à l’erreur admin consent required et proposez un flux convivial « Demandez à votre admin ».

Intégrez tous les fournisseurs de calendriers dans votre app avec l’API de calendrier unifiée Apiroc

Les intégrations calendaires sont notre cœur de métier. Notre équipe travaille depuis des années avec Google Calendar, Outlook et iCloud Calendar, et a construit des intégrations calendaires qui traitent des milliards d’appels API.

Les leçons tirées de toutes les grandes APIs calendaires ont nourri l’API de calendrier unifiée Apiroc. Elle fait gagner aux développeurs des centaines d’heures sur les problèmes liés aux calendriers, pour qu’ils puissent se concentrer sur les fonctionnalités qui font avancer leur produit.

Inscrivez-vous à Apiroc pour tester l’API de calendrier unifiée et intégrer plusieurs fournisseurs de calendrier à l’aide d’une seule API. Le plan gratuit ne nécessite pas de carte bancaire.

FAQ

Quel compte me faut-il pour utiliser l’API Calendrier Outlook ?

Il faut un compte Microsoft Work ou Developer avec accès à Azure Active Directory.

Quelles autorisations ajouter pour un accès complet au calendrier ?

Ajoutez Calendars.ReadWrite (et Calendars.ReadWrite.Shared si vous avez besoin des calendriers partagés) dans Microsoft Graph.

Pourquoi définir un domaine éditeur et un branding ?

La vérification de l’éditeur et un écran de consentement à vos couleurs empêchent votre application d’apparaître comme « non vérifiée », et ils sont désormais attendus pour la plupart des applications multi-locataires.

À quelle fréquence renouveler les abonnements webhook Outlook ?

Les webhooks calendrier de Graph expirent au bout de quelques heures. Prévoyez donc une tâche en arrière-plan qui renouvelle chaque abonnement sur le point d’expirer.

L’API Calendrier Outlook prend-elle en charge les notifications push ?

Oui. Créez un abonnement Microsoft Graph et vous recevrez des notifications de changement, sans avoir besoin de recourir au polling.

Existe-t-il un moyen plus simple d’intégrer Outlook, Google et iCloud ?

Oui. Une API de calendrier unifiée comme Apiroc regroupe les principaux fournisseurs derrière une interface JSON unique et cohérente. Avec l’API de calendrier unifiée Apiroc, vous n’avez pas à développer ni à maintenir une intégration distincte pour chaque fournisseur de calendrier.