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

Auteurs
Publié le

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

Inscrivez-vous sur notre liste d’attente pour l’API de calendrier unifiée afin d’obtenir l’accès à notre API de calendrier unifiée, qui vous permet d’intégrer tous les fournisseurs de calendriers dans votre application via une seule API.

Rejoindre la liste d’attenteAucune carte de crédit requise !

Dans notre précédent article sur comment intégrer l’API Google Calendar à votre application, nous avons expliqué toutes les étapes qu’un développeur doit suivre pour intégrer l’API Google Calendar dans son application.

Dans cet article, nous expliquerons comment intégrer l’API Outlook Calendar à votre application, notamment la création de l’enregistrement d’application Azure, la configuration des portées, la vérification, les pièges d’intégration et des exemples 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.

Notez que la possibilité de créer des applications en dehors d’un annuaire est obsolète. Si vous n’avez pas d’annuaire, 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

Veuillez visiter la page de connexion au portail Microsoft Azure et vous connecter.

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 visible par l’utilisateur pour votre application.

    2. Types de comptes pris en charge : la sélection 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 – idéal pour les applications SaaS multi-tenant.

    3. URI de redirection : facultatif selon votre type d’application. Pour une application web, vous en aurez probablement besoin ; c’est l’URI où Azure enverra les réponses OAuth. Sous « Select a platform », choisissez Web, puis saisissez l’URI (par ex. https://votreapp.com/auth/callback). Pour un flux d’authentification côté serveur, une URI Web est appropriée. Assurez-vous que le domaine est accessible et vous appartient.

    4. Cliquez sur Register.

    5. Une fois l’application enregistrée, Azure Active Directory affiche la page suivante où vous pouvez copier l’ID client et l’ID locataire. L’Application (client) ID est un GUID identifiant votre app. L’ID locataire n’est pas toujours nécessaire ; pour les apps multi-tenant, on utilise souvent l’endpoint common. Vous pouvez toutefois utiliser l’ID de locataire pour vos tests.

      Application Created

Conservez l’ID client et l’ID locataire dans un endroit sûr (en général comme variables d’environnement).

Étape 3 : Configurer les autorisations d’API

Une fois l’application enregistrée, configurez les autorisations calendrier. Ces autorisations sont présentées lors du flux OAuth ; l’utilisateur voit les portées avant d’accorder l’accès.

Par défaut, l’autorisation « User.Read » est attribuée. Si vous souhaitez seulement vous connecter et lire le profil utilisateur, vous pouvez ignorer cette étape.

Pour ajouter des autorisations :

  1. Dans la barre latérale gauche, section Manage, cliquez sur API Permissions.

  2. Cliquez sur + Add a permission.

    Click API Permissions
  3. Choisissez la carte Microsoft Graph (généralement la première).

    Click _Add a permission_ button
  4. Sélectionnez Delegated permissions ou Application permissions. Les permissions déléguées sont adaptées lorsque l’application agit au nom de l’utilisateur connecté ; les permissions d’application conviennent aux services en arrière-plan sans utilisateur connecté. Ici, nous choisirons Delegated Permissions.

    Click the _Microsoft Graph_ card
  5. Recherchez Calendars : cela affiche toutes les autorisations liées aux calendriers. Sélectionnez celles nécessaires au bon fonctionnement de votre application ; la plupart du temps, Calendars.ReadWrite et Calendars.ReadWrite.Shared (pour les calendriers partagés). Ces portées sont généralement déléguées utilisateur et ne nécessitent pas de consentement admin par défaut, mais certaines organisations restreignent ce consentement. Si un utilisateur d’un tenant externe ne peut pas consentir, un administrateur devra le faire.

    Click _Delegated Permissions_

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

Nous recommandons d’effectuer les opérations calendrier (écritures, lectures, mises à jour…) côté serveur ; il faut donc générer un secret client.

  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 et stockez-le précieusement (souvent dans votre fichier .env).

Vous ne pourrez plus voir ni copier le secret après avoir quitté la page ; assurez-vous de le sauvegarder.

Étape 5 : 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 recommandé pour un écran de consentement soigné. Définissez un domaine éditeur vérifié pour éviter que l’app apparaisse comme « non vérifiée ». Pour une app multi-tenant, Microsoft exige désormais une vérification éditeur pour un usage étendu. Sans cela, les utilisateurs externes peuvent être bloqués.

Branding & Properties screen

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

Après la configuration, explorez la documentation de l’API Microsoft Calendar Graph pour vous familiariser avec les points de terminaison de création, mise à jour et suppression d’événements.

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

Bien que Microsoft Graph soit bien documentée, nous recommandons d’utiliser un produit d’API de calendrier unifiée qui vous permet d’intégrer tous les fournisseurs via une seule API.

Ainsi, vous implémentez une unique API dans votre application tout en prenant en charge tous les fournisseurs, sans gérer leurs limitations ni différences. Vous évitez aussi la maintenance de multiples APIs, les changements de version ou les cas limites imprévus.

OneCal Unified Calendar API

OneCal Unified Calendar API Landing Page

Exemple de flux d’autorisation Outlook Calendar

Le diagramme suivant illustre un flux OAuth simplifié permettant aux utilisateurs de connecter leur calendrier Outlook à votre application.

Outlook OAuth 2.0 Flow

Consultez la documentation Microsoft sur le flux OAuth2 pour en savoir plus.

Côté client (UI)

const microsoftOauthUrl = getMicrosoftOAuthUrl()
<button href="microsoftOauthUrl"rel="noopener noreferrer"> Connecter 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 : login, none, consent, select_account.

  • response_mode accepte : query, fragment ou form_post. Ici, form_post demande à Microsoft d’envoyer un POST vers l’URI de redirection.

Côté API (Backend)

Ensuite, créons le handler API chargé de recevoir le code et les portées, puis de les échanger 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,
        reminderCount: 0,
        lastRemindedAt: null,
      },
      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, prévoyez des fonctions utilitaires pour échanger le code contre des jetons, etc.

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 de développeurs soumettent des apps chaque jour. Remplissez soigneusement tous les champs et prévoyez ce délai dans votre feuille de route.

  • Ne demandez que les portées indispensables : l’équipe Microsoft est très pointilleuse. N’exigez que ce qui est nécessaire ; cela facilitera l’approbation et rassurera les utilisateurs.

  • Les webhooks expirent : pensez à les renouveler : programmez une tâche régulière pour renouveler les abonnements quelques heures avant leur expiration.

  • Limitation et throttling : Microsoft applique des règles strictes. Évitez les appels élément par élément et implémentez un contrôle de débit pour ne pas déclencher l’erreur « MailboxConcurrency ».

    PortéeLimiteRemarques
    Par boîte (mailbox) (app ID + boîte)10 000 requêtes / 10 min et 4 requêtes simultanéesErreur « MailboxConcurrency ».
    Upload150 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 : un utilisateur peut saisir manuellement son fuseau ; gérez aussi ce cas.

  • Problèmes de consentement : Calendars.ReadWrite est délégué utilisateur, mais certains tenants bloquent le consentement. Prévoyez un flux « Demandez à votre admin » en cas d’erreur admin consent required.

Intégrez tous les fournisseurs de calendriers avec l’API unifiée OneCal

Les intégrations calendaires sont notre cœur de métier. Depuis 2022, nous synchronisons des milliards d’événements sur les principaux fournisseurs, et nos liens de planification sont utilisés par des milliers de professionnels.

Les leçons tirées de toutes ces APIs calendaires ont conduit à la création de l’API unifiée OneCal, permettant à nos utilisateurs d’économiser des centaines d’heures en se concentrant sur les fonctionnalités à forte valeur ajoutée.

Rejoignez la liste d’attente de notre API unifiée pour être informé dès le lancement et bénéficier des tarifs et remises de lancement.