Skip to content

Latest commit

 

History

History
199 lines (158 loc) · 6.66 KB

File metadata and controls

199 lines (158 loc) · 6.66 KB

SideSoftware.Email

NuGet License: MIT

Overview

SideSoftware.Email is a .NET 10 library that provides a clean, injectable email service built on the Microsoft Graph API. It wraps Azure AD authentication and Graph API message sending behind a simple IEmailService abstraction, making it easy to send plain or HTML emails with attachments, CC/BCC recipients, and importance levels -- all through standard .NET dependency injection.

Installation

dotnet add package SideSoftware.Email

Quick Start

Register with configuration (appsettings.json)

using SideSoftware.Email.Extensions;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGraphEmail(builder.Configuration);

Register with manual options

using SideSoftware.Email.Extensions;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGraphEmail(options =>
{
    options.TenantId = "your-tenant-id";
    options.ClientId = "your-client-id";
    options.ClientSecret = builder.Configuration["KeyVault:GraphEmailSecret"]!;
    options.SenderAddress = "no-reply@contoso.com";
    options.SenderDisplayName = "Contoso Notifications";
});

Send an email

using SideSoftware.Email.Abstractions;

app.MapPost("/api/send-email", async (IEmailService emailService) =>
{
    var result = await emailService.SendAsync(
        to: "recipient@contoso.com",
        subject: "Hello from Graph API",
        body: "<p>This email was sent using SideSoftware.Email.</p>");

    return result.IsSuccess
        ? Results.Ok("Email sent successfully")
        : Results.Problem(result.ErrorMessage);
});

Features

  • Microsoft Graph API -- sends email through the Graph /sendMail endpoint (no SMTP required)
  • Dependency injection -- registers via IServiceCollection.AddGraphEmail() with configuration or manual options
  • Simple and advanced APIs -- quick SendAsync(to, subject, body) overload for basic emails; full EmailMessage model for complex scenarios
  • HTML and plain-text bodies with a single IsHtml toggle
  • File attachments -- attach any byte array with file name and content type
  • Multiple recipients -- To, CC, and BCC with optional display names
  • Reply-To support -- override the reply address independently from the sender
  • Importance levels -- Low, Normal, or High priority
  • Save to Sent Items -- configurable option to save sent messages in the sender's mailbox
  • Result pattern -- EmailResult returns success/failure with error details instead of throwing exceptions

Usage Examples

Simple Notification

Inject IEmailService into any service and send a quick HTML email:

using SideSoftware.Email.Abstractions;

public class NotificationService(IEmailService emailService)
{
    public async Task NotifyAsync(string email, string name)
    {
        var result = await emailService.SendAsync(
            to: email,
            subject: "Record Updated",
            body: $"""
                   <h2>Hi {name},</h2>
                   <p>Your record has been updated. Please review at your earliest convenience.</p>
                   <p>— Contoso</p>
                   """);

        if (!result.IsSuccess)
        {
            throw new InvalidOperationException($"Failed to send email: {result.ErrorMessage}");
        }
    }
}

Rich Email with Attachments

Use EmailMessage for full control over recipients, attachments, and importance:

using SideSoftware.Email.Abstractions;
using SideSoftware.Email.Enums;
using SideSoftware.Email.Models;

public class ReportService(IEmailService emailService)
{
    public async Task SendMonthlyReportAsync(byte[] pdfReport)
    {
        var message = new EmailMessage
        {
            To =
            [
                new EmailRecipient("bob@contoso.com", "Bob"),
                new EmailRecipient("ops@contoso.com", "Operations")
            ],
            Cc =
            [
                new EmailRecipient("admin@contoso.com")
            ],
            Subject = $"Monthly Report - {DateTime.Now:MMMM yyyy}",
            Body = """
                   <h2>Monthly Report</h2>
                   <p>Please find the attached monthly report.</p>
                   """,
            IsHtml = true,
            Importance = EmailImportance.High,
            Attachments =
            [
                new EmailAttachment
                {
                    FileName = $"Report-{DateTime.Now:yyyy-MM}.pdf",
                    Content = pdfReport,
                    ContentType = "application/pdf"
                }
            ]
        };

        var result = await emailService.SendAsync(message);

        if (!result.IsSuccess)
        {
            // Log, retry, or escalate as appropriate
        }
    }
}

Configuration

Add a GraphEmail section to your appsettings.json:

{
  "GraphEmail": {
    "TenantId": "your-azure-ad-tenant-id",
    "ClientId": "your-azure-ad-client-id",
    "ClientSecret": "your-azure-ad-client-secret",
    "SenderAddress": "no-reply@contoso.com",
    "SenderDisplayName": "Contoso Notifications",
    "SaveToSentItems": true
  }
}
Property Required Default Description
TenantId Yes -- Azure AD Tenant ID
ClientId Yes -- Azure AD Application (Client) ID
ClientSecret Yes -- Azure AD Client Secret
SenderAddress Yes -- Mailbox address to send from (e.g., no-reply@contoso.com)
SenderDisplayName No null Display name shown on sent emails
SaveToSentItems No true Whether to save sent messages in the sender's Sent Items folder

Azure AD Setup

To use this library you need an Azure AD app registration with the Microsoft Graph Mail.Send application permission:

  1. Go to Azure Portal > Azure Active Directory > App registrations > New registration
  2. Name the application (e.g., "Graph Email Service") and register it
  3. Copy the Application (client) ID and Directory (tenant) ID into your configuration
  4. Go to Certificates & secrets > New client secret, copy the secret value into your configuration
  5. Go to API permissions > Add a permission > Microsoft Graph > Application permissions
  6. Search for and add Mail.Send
  7. Click Grant admin consent for your tenant
  8. Ensure the SenderAddress mailbox exists in your Microsoft 365 tenant (a shared mailbox works well for this)

License

This project is licensed under the MIT License.