import requests import csv # === Configuration === ACCESS_TOKEN = "YOUR_ACCESS_TOKEN_HERE" START_DATETIME = "2025-05-19T00:00:00Z" END_DATETIME = "2025-05-26T23:59:59Z" OUTPUT_FILE = "calendar.csv" # === Setup headers === headers = { "Authorization": f"Bearer {ACCESS_TOKEN}", "Prefer": 'outlook.timezone="UTC"' } # === Initial API endpoint === base_url = "https://graph.microsoft.com/v1.0/me/calendarview" params = { "$select": "subject,start,end", "startDateTime": START_DATETIME, "endDateTime": END_DATETIME } # === Event storage === all_events = [] # === Fetch all pages === print("Fetching events...") url = base_url while url: response = requests.get(url, headers=headers, params=params if url == base_url else None) if response.status_code != 200: print("Failed to fetch events:", response.status_code, response.text) break data = response.json() events = data.get("value", []) all_events.extend(events) # Get next page link url = data.get("@odata.nextLink") # === Write to CSV === print(f"Writing {len(all_events)} events to {OUTPUT_FILE}...") with open(OUTPUT_FILE, "w", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=["subject", "start", "end"]) writer.writeheader() for e in all_events: writer.writerow({ "subject": e.get("subject", ""), "start": e.get("start", {}).get("dateTime", ""), "end": e.get("end", {}).get("dateTime", "") }) print("Done.")