Monitoring emails in real-time is a common requirement for businesses. With Microsoft Graph API, you can automatically log email details, download attachments, and maintain daily logs. In this article, we’ll create a .NET Web API to handle email notifications.
1. Introduction
Microsoft Graph API provides access to Office 365 services like emails, calendars, and users.
With this setup, we can:
- Subscribe to a user’s inbox
- Receive webhook notifications for new emails
- Log email details to a file in JSON format
- Download attachments automatically
This is useful for automated email monitoring and reporting.
2. Prerequisites
Before starting, ensure you have:
- .NET 6/7/8 project
- Visual Studio or VS Code
- Office 365 account
-
NuGet packages:
Microsoft.Graph Azure.Identity Newtonsoft.Json
3. Setting Up Microsoft Graph API
3.1 Register an Application in Azure
i. Go to Azure Portal (https://portal.azure.com/) → App Registrations → New Registration
ii. Provide a name (GraphNotificationDemo), Supported account types (Accounts in any organizational directory and personal Microsoft accounts) and redirect URI (https://localhost)
Click Register.
iii. Note down the Application (client) ID and Directory (tenant) ID for later use.
iv. Add a client secret (Manage → Certificates & secrets → New client secret → Enter a "Description", and select the "Expires" duration.
Click Add.
v. Note down the client secret value for future reference.
vi. API Permissions (Manage → API Permissions → Add a permission → Microsoft Graph)
vii. Add API permissions:
Mail.Read Mail.ReadWrite Mail.ReadBasic 4. Ngrok
Ngrok allows calls from the internet to be directed to your application running locally without needing to create firewall rules.
Install Ngrok from https://ngrok.com/
On the command prompt, Run below command:
ngrok http 5000 5. Create an ASP.NET Core web API project
i. Open Visual Studio 2022 and create a new project. From the available templates, select ASP.NET Core Web API.
ii. Give your project a specific name and choose the location where you want to save it. After that, click the Next button.
iii. In the next step, select the framework as .NET 8 (LTS), since it is the latest long-term support version. Finally, click Create to generate your new Web API project.
iv. Add the below NuGet packages to the project.
Azure.Identity Microsoft.Graph Newtonsoft.Json v. Create a configuration class:
public class MyConfig { public string AppId { get; set; } public string TenantId { get; set; } public string AppSecret { get; set; } public string Ngrok { get; set; } } vi. Add your credentials in appsettings.json.
"MyConfig": { "AppId": <<--YOUR CLIENT ID-->>, "AppSecret": <<--YOUR CLIENT Secret-->>, "TenantId": <<--YOUR Tenant Id-->>, "Ngrok": <<--YOUR Ngrok URL-->> } vii. Update Program.cs file:
using changenotifications.Models; var config = new MyConfig(); builder.Configuration.Bind("MyConfig", config); builder.Services.AddSingleton(config); //app.UseHttpsRedirection(); -- comment out the following line to disable SSL redirection. viii. Subscribing to a User Inbox:
What is a subscription?
A subscription tells Graph API to send POST requests to your server whenever a new email arrives. Subscriptions expire, so we’ll set up auto-renew.
var subscription = new Subscription { ChangeType = "created", NotificationUrl = $"{config.Ngrok}/api/notifications", Resource = $"/users/{userId}/mailFolders('Inbox')/messages", ExpirationDateTime = DateTime.UtcNow.AddMinutes(5), ClientState = "SecretClientState" }; var newSubscription = await graphClient.Subscriptions.PostAsync(subscription); ix. Webhook Endpoint
Create a [HttpPost] endpoint to receive notifications:
[HttpPost] public async Task<ActionResult> Post([FromQuery] string validationToken) { if (!string.IsNullOrEmpty(validationToken)) return Ok(validationToken); // Graph validation } x. Parsing Notifications
After receiving a POST, extract userId and messageId to fetch the full email:
var message = await graphClient.Users[userId].Messages[messageId].GetAsync(); xi. Logging Email Details
We log key email details such as the subject, sender, recipients (To & CC), received and sent dates, body preview, and attachments.
var logFile = Path.Combine(BaseDir, "logs", $"EmailLog_{DateTime.UtcNow:yyyyMMdd}.txt"); await File.AppendAllTextAsync(logFile, JsonSerializer.Serialize(logEntry, new JsonSerializerOptions { WriteIndented = true })); xii. Downloading Attachments
If the email has attachments, save them in a folder:
if (attachment is FileAttachment fileAtt) { var savePath = Path.Combine(msgFolder, fileAtt.Name); await File.WriteAllBytesAsync(savePath, fileAtt.ContentBytes); } Folder structure:
C:\EmailAttachments\20250819\<MessageId>\ xiii. Auto-Renew Subscriptions
Subscriptions expire. Use a Timer to renew:
if (subscription.ExpirationDateTime < DateTime.UtcNow.AddMinutes(2)) RenewSubscription(subscription); 6. Test the application
i. Open Swagger in the browser, trigger the subscribe-inbox GET endpoint from the Notifications controller, and you will receive a response like below.
After subscribing, the system sends an email to the user, logs all email details, and saves any email attachments in the file path C:\EmailAttachments.
7. Summary
In this article, we learned how to use Microsoft Graph API with .NET to read emails, create inbox subscriptions, handle real-time notifications, log email details into daily text files, and download attachments. We also covered how to set up auto-renewal for subscriptions to keep the system running continuously. With this setup, you can build a reliable email monitoring and processing system for business or personal applications.
8. Code Download
The code developed during this article can be found here.










Top comments (0)