So integrierst du die Outlook Calendar API in deine App
- Autoren
- Name
- Eraldo Forgoli
- Veröffentlicht am
Inhaltsverzeichnis
Alle Kalender mit einer einzigen API integrieren
Tritt unserer Warteliste für die Unified Calendar API bei, um Zugriff auf unsere Unified Calendar API zu erhalten, mit der du alle Kalenderanbieter über eine einzige API in deine App integrieren kannst.
In unserem letzten Artikel über wie du die Google Calendar API in deine Anwendung integrierst haben wir alle Schritte erklärt, die ein Entwickler befolgen muss, um die Google Calendar API in seine Anwendung zu integrieren.
In diesem Artikel erklären wir, wie du die Outlook Calendar API in deine App integrierst – einschließlich der Einrichtung der Azure-App-Registrierung, der Festlegung von Scopes, der Verifizierung, möglicher Stolperfallen und praxisnaher Beispiele.
Voraussetzungen
Diese Anleitung setzt voraus, dass du bereits über ein Microsoft-Arbeits- oder -Entwicklerkonto mit Zugriff auf Azure Active Directory verfügst.
Beachte, dass die Möglichkeit, Anwendungen außerhalb eines Verzeichnisses zu erstellen, veraltet ist. Falls du kein Verzeichnis hast, solltest du dem Microsoft 365 Developer Program beitreten oder dich für Azure anmelden.
So verwendest und integrierst du die Outlook Calendar API in deine App
Schritt 1: Beim Microsoft Azure-Portal anmelden
Besuche die Anmeldeseite des Microsoft Azure-Portals und melde dich an.
Die Seite des Microsoft Azure-Portals.
Schritt 2: Eine neue Anwendung registrieren
Nachdem du dich beim Microsoft Azure-Portal angemeldet hast:
Navigiere zu Azure Active Directory
Suche in der Suchleiste nach „App Registrations“
Klicke auf „App Registrations“
Klicke auf „New registration“
Fülle die erforderlichen Felder aus:
Das erste Feld ist der Name deiner Anwendung, der den Nutzern angezeigt wird.
Wähle anschließend die unterstützten Kontotypen. Die Auswahl hängt davon ab, welchen Anwendungstyp du entwickelst (nur intern oder mandantenfähig). In diesem Beispiel wähle ich „Accounts in any organizational directory (Any Microsoft Entra ID tenant – Multitenant)“, damit Benutzer aus beliebigen Organisationen (einschließlich Outlook.com-Benutzer) meine App verwenden können – ideal für SaaS- oder andere mandantenfähige Anwendungen.
Gib die Redirect URI an: Das ist optional und hängt vom Anwendungstyp ab. Entwickelst du eine Web-Anwendung, benötigst du sie in der Regel, da Azure OAuth-Antworten an diese URI sendet. Wähle unter „Select a platform“ → Web und trage die Redirect URI ein (z. B.
https://deineapp.com/auth/callback
). Für serverseitige Auth-Flows ist eine Web-Redirect-URI passend. Achte darauf, dass die Domain erreichbar und in deinem Besitz ist.Klicke auf „Register“.
Nach dem Klick erstellt Azure Active Directory deine Anwendung und leitet dich auf die nächste Seite weiter, auf der du Client ID und Tenant ID kopieren kannst. Die Application (client) ID ist eine GUID, die deine App identifiziert. Die Directory (tenant) ID benötigst du nicht immer; bei mandantenfähigen Apps nutzt du normalerweise den Endpunkt
common
. Für Tests im eigenen Mandanten kannst du die Tenant ID jedoch verwenden.
Speichere Client ID und Tenant ID an einem sicheren Ort, in der Regel als Umgebungsvariablen.
Schritt 3: API-Berechtigungen konfigurieren
Nach der Registrierung deiner App musst du die Kalenderberechtigungen festlegen. Diese Berechtigungen werden im OAuth-Flow angezeigt, sodass der Nutzer sieht, auf welche Bereiche deine Anwendung zugreifen möchte, bevor er den Zugriff gewährt.
Standardmäßig erhält deine Anwendung die Berechtigung „User.Read“. Wenn du dich nur anmelden und ein Benutzerprofil lesen willst, kannst du diesen Schritt überspringen.
So fügst du API-Berechtigungen hinzu:
Klicke im linken Seitenmenü auf „Manage“.
Wähle „API Permissions“.
Klicke auf „+ Add a permission“.
Suche in der rechten Leiste nach der Kachel „Microsoft Graph“ (normalerweise die erste).
Entscheide dich zwischen „Delegated permissions“ und „Application permissions“. Delegierte Berechtigungen eignen sich, wenn deine Anwendung im Namen des angemeldeten Nutzers agiert. Anwendungsberechtigungen verwendet man dagegen für Hintergrunddienste ohne angemeldeten Nutzer. In diesem Beispiel nutze ich „Delegated permissions“.
Suche nach „Calendars“: Dies listet alle kalenderbezogenen Berechtigungen auf. Wähle die Berechtigungen, die deine Anwendung benötigt. Meist sind „Calendars.ReadWrite“ und „Calendars.ReadWrite.Shared“ sinnvoll (falls du Zugriff auf freigegebene Kalender brauchst). Kalenderscopes erfordern normalerweise keine Admin-Zustimmung, da sie nutzerdelegiert sind. Manche Organisationen beschränken jedoch die Nutzerzustimmung: Kann ein externer Nutzer nicht zustimmen, muss ein Admin deiner App zustimmen (per Admin-Consent-Prompt oder URL).
Schritt 4: Ein Client Secret erstellen
Wir empfehlen, Kalenderoperationen (Schreiben, Lesen, Updates usw.) serverseitig auszuführen; dafür brauchst du ein Client Secret.
So erzeugst du ein Client Secret:
Klicke auf den Tab „Certificates & secrets“
Klicke auf „New client secret“
Gib eine Beschreibung und ein Ablaufdatum an
Nach dem Erstellen des Client Secrets kopiere es und bewahre es sicher auf (üblicherweise in deiner .env-Datei).
Du kannst das Client Secret später nicht mehr einsehen oder kopieren – sichere es also, bevor du die Seite verlässt.
Schritt 5: Branding und Verifizierung
Im Bereich „Branding & Properties“ der App-Registrierung kannst du ein Logo und Informationen (App-Beschreibung, Nutzungsbedingungen-URL usw.) festlegen. Das ist optional, aber für einen professionellen Consent-Screen empfohlen. Wichtig ist, eine Publisher Domain (in der Regel deine verifizierte eigene Domain) zu setzen, um zu verhindern, dass die App bei der Zustimmung als „unverified“ erscheint. Für mandantenfähige Apps verlangt Microsoft mittlerweile eine Publisher-Verifizierung. Ohne diese Verifizierung können Benutzer außerhalb deines Mandanten aufgrund von Sicherheitsrichtlinien seit November 2020 blockiert sein.
Schritt 6: Mit der Outlook Graph API vertraut machen
Nachdem die Anwendung eingerichtet und alle Informationen eingetragen wurden, kannst du die Microsoft Calendar Graph API erkunden, um die spezifischen APIs zum Erstellen, Aktualisieren und Löschen von Ereignissen kennenzulernen.
Schritt 7: Überlege, einen Unified Calendar API-Dienst zu nutzen, um alle Kalenderanbieter über eine einzige API zu integrieren
Obwohl die Microsoft Graph API gut dokumentiert ist, empfehlen wir die Verwendung einer Unified Calendar API, die es dir ermöglicht, alle Kalenderanbieter über eine einzige API in deine Anwendung einzubinden.
So profitierst du davon, nur eine API zu implementieren und trotzdem alle Kalenderanbieter zu unterstützen – unabhängig von deren Einschränkungen oder Unterschieden.
Ein weiterer Vorteil: Du musst nicht mehrere Kalender-APIs pflegen, dich nicht um Breaking Changes kümmern und keine Edge-Cases behandeln, an die du nie gedacht hättest.
OneCal Unified Calendar API
Beispiel eines Outlook Calendar-Autorisierungsflows
Das folgende Flussdiagramm zeigt einen einfachen Outlook Calendar-OAuth-Flow, mit dem Benutzer ihren Outlook-Kalender mit deiner App verbinden können.
Weitere Informationen findest du in der Microsoft-Dokumentation zum OAuth 2.0-Autorisierungscode-Flow.
Client-Seite (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}`;
}
Der Parameter „prompt“ kann einen der vier Werte
login
,none
,consent
oderselect_account
haben.Der Parameter „response_mode“ kann die Werte
query
,fragment
oderform_post
annehmen. Wir wählenform_post
, damit Microsoft eine POST-Anfrage an unsere Redirect URI (Server) sendet.
API-Seite (Backend)
Als Nächstes bauen wir den API-Handler, der den Code und die Scopes vom Outlook-Server empfängt und gegen Tokens austauscht.
Im Beispiel verwenden wir zod
zur Validierung.
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);
console.error("Fehler im microsoftHandler", querystr);
console.error("Microsoft-Konto konnte nicht verknüpft werden", e);
const q = new URLSearchParams({
error,
provider: CalendarProvider.MICROSOFT,
});
return res.redirect(302, `/?${q}`);
}
};
export default microsoftHandler;
Ähnlich wie auf der Client-Seite empfehlen wir Hilfsfunktionen zum Austauschen des Codes gegen Tokens usw.
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("Token-Austausch fehlgeschlagen");
throw e;
}
}
Stolperfallen bei der Outlook Calendar API-Integration
Verifizierung kann dauern und frustrierend sein: Täglich reichen Tausende Entwickler Anwendungen bei Outlook ein, daher prüft Microsoft sehr gründlich. Fülle alle Angaben gewissenhaft aus und plane den Prüfprozess in deiner Roadmap ein.
Fordere nur die Scopes an, die du wirklich brauchst: Das beschleunigt nicht nur die Freigabe, sondern verhindert auch Verwirrung bei den Nutzern, wenn unnötige Berechtigungen angezeigt werden.
Webhooks laufen ab – erneuere sie rechtzeitig: Registrierst du Webhooks, um Kalenderänderungen zu verfolgen, setze einen Hintergrund-Job auf, der ablaufende Abonnements alle paar Stunden erneuert.
Rate Limiting und Throttling: Microsoft hat strenge Grenzwerte. Vermeide Einzelabrufe und implementiere eigenes Rate Limiting, um „MailboxConcurrency“-Fehler zu verhindern.
Zeitzonen-Tücken: Outlook-Nutzer können beliebige Zeitzonen eintippen – handle auch diesen Fall ab.
Consent- & Berechtigungsprobleme:
Calendars.ReadWrite
ist nutzerdelegiert, doch manche Mandanten erlauben keine Selbstzustimmung. Rechne mit „admin consent required“ und zeige einen freundlichen „Bitte Admin fragen“-Flow.
Integriere alle Kalenderanbieter in deine App mit der OneCal Unified Calendar API
Kalenderintegrationen sind unser Kerngeschäft. Seit 2022 haben wir Milliarden von Terminen zwischen allen großen Kalenderplattformen synchronisiert, und unsere Scheduling-Links werden weltweit von Tausenden Profis genutzt.
Die Erfahrungen aus all diesen Kalender-APIs haben zur OneCal Unified Calendar API geführt – damit unsere Nutzer Hunderte Stunden Entwicklungszeit sparen und sich stattdessen auf Features konzentrieren können, die ihr Produkt voranbringen.
Tritt unserer Unified Calendar API-Warteliste bei, um benachrichtigt zu werden, sobald wir starten, und profitiere von Frühbucherpreisen und Rabatten.