54 lines
3.5 KiB
Plaintext
54 lines
3.5 KiB
Plaintext
In the current folder, build a minimalistic ASP.NET Core MVC application that synchronizes Microsoft 365 Calendar changes for multiple authenticated users into a centralized Excel Online file every hour.
|
|
|
|
Core Tech Stack:
|
|
Framework: ASP.NET Core 10 (MVC)
|
|
Identity: Microsoft.Identity.Web & Microsoft.Identity.Web.MicrosoftGraph
|
|
API: Microsoft Graph SDK v5.x
|
|
Storage: SQLite (Entity Framework Core) for storing UserSyncState (UserId, Email, DeltaLink).
|
|
Requirements:
|
|
Authentication & Scopes:
|
|
Configure OpenID Connect to request Calendars.Read, Files.ReadWrite, and offline_access.
|
|
Use .AddMicrosoftIdentityWebApp and .EnableTokenAcquisitionToCallDownstreamApi in Program.cs.
|
|
Implement an in-memory or distributed token cache to ensure the background worker can refresh tokens silently using the offline_access scope.
|
|
Database Model:
|
|
Create a UserSyncState entity: string UserId (PK), string UserEmail, string LastDeltaLink.
|
|
This table tracks which users have opted into the sync and their progress.
|
|
Background Worker (CalendarSyncWorker : BackgroundService):
|
|
Trigger: Runs every 60 minutes.
|
|
Logic:
|
|
Iterate through all users in the UserSyncState table.
|
|
For each user, acquire a GraphServiceClient using ITokenAcquisition.GetAccessTokenForUserAsync.
|
|
Perform a Delta Query on the CalendarView.
|
|
Initial Sync Logic: If LastDeltaLink is null, start a new delta query with a range of 30 days. Use PageIterator to exhaust all pages until a @odata.deltaLink is returned.
|
|
Incremental Sync Logic: If LastDeltaLink exists, initialize the request using WithUrl(LastDeltaLink).
|
|
Save the new deltaLink back to the database after successful processing.
|
|
Excel Integration:
|
|
If changes (events) are found, append them to an Excel file named CalendarSync.xlsx in the App's root OneDrive folder.
|
|
Use the graphClient.Drives[driveId].Items[itemId].Workbook.Tables["EventsTable"].Rows.PostAsync method.
|
|
Columns: UserEmail, EventSubject, Start, End, ChangeType (Created/Updated/Deleted).
|
|
Project Files to Generate:
|
|
Program.cs (Auth and Service registration).
|
|
Models/UserSyncState.cs & Data/AppDbContext.cs.
|
|
Services/CalendarSyncWorker.cs (The core logic).
|
|
Controllers/HomeController.cs (With a SignIn action to onboard users).
|
|
appsettings.json (Template with placeholders for ClientId, TenantId, and ClientSecret).
|
|
Constraint:
|
|
Use Microsoft Graph SDK v5 syntax exclusively.
|
|
Do not use "Long-lived" access tokens manually; rely on ITokenAcquisition to handle refresh tokens via offline_access.
|
|
Ensure the code is clean, async/await throughout, and contains basic logging for the sync process.
|
|
Why this works for your scale:
|
|
ASP.NET BackgroundService: Unlike a simple loop, this is a managed part of the .NET lifecycle.
|
|
SQLite State: By storing the DeltaLink per user, you ensure that if the server restarts, you don't re-download the entire calendar; you pick up exactly where you left off.
|
|
Token Management: Using Microsoft.Identity.Web is the "Golden Path." It handles the complex logic of checking if an access token is expired and using the refresh token to get a new one without you writing a single line of OAuth refresh logic.
|
|
|
|
|
|
Write to the Excel file named CalendarSync in the root of the users OneDrive.
|
|
You should write events and log stats there.
|
|
|
|
Furthermore let the user know the sync status (next interval) status of current sync and some details regarding events that were recently synced in the web app (status page)
|
|
|
|
Provide a "Sync Now" button that forces the sync function to run independently of the interval.
|
|
|
|
If you have questions or are not sure what to build, you ask back before coding.
|
|
|