Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ name: CI
on:
pull_request:
branches: [main]
push:
branches: [main]
workflow_dispatch:

jobs:
Expand All @@ -14,32 +12,37 @@ jobs:
env:
DOTNET_NOLOGO: true
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
MINVERBUILDMETADATA: build.$GITHUB_RUN_ATTEMPT

steps:
- name: Checkout
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0

- name: .NET SDK
- name: 👷 .NET SDK
uses: actions/setup-dotnet@v1
with:
dotnet-version: "6.0"

- name: Install dependencies
- name: Install dependencies
run: dotnet restore

- name: Build
run: dotnet build --configuration Release --no-restore
- name: 🔨 Build
run: dotnet build --configuration Release --no-restore /p:MinVerBuildMetadata=${{ github.run_number }}

# # - name: Test
# # run: dotnet test --no-restore --verbosity normal

- name: Pack
- name: 📦 Pack
run: dotnet pack ./src/FluentEmail.Graph/FluentEmail.Graph.csproj -c Release -o ./artifacts --no-build

- name: Artifacts
uses: actions/upload-artifact@v2
with:
name: artifacts
path: artifacts/**/*
# - name: Artifacts
# uses: actions/upload-artifact@v2
# with:
# name: artifacts
# path: artifacts/**/*

- name: 🚀 Publish to GitHub packages
run: dotnet nuget push "./artifacts/*.nupkg" --source "https://nuget.pkg.github.com/ESC-BV/index.json" --api-key "${{secrets.GITHUB_TOKEN}}"

29 changes: 14 additions & 15 deletions FluentEmail.Graph.sln
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentEmail.Graph.Tests", "
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E37EFC29-B838-4EC7-8DDD-48303FE8FD52}"
ProjectSection(SolutionItems) = preProject
GitVersion.yml = GitVersion.yml
README.md = README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample", "sample", "{A4341B5B-E943-490B-94AE-D4637A7AF37C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SendMailSample", "sample\SendMailSample\SendMailSample.csproj", "{5C9C773B-43AF-475C-A56A-96CDA259D4D8}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SendMailTestApp", "sample\SendMailTestApp\SendMailTestApp.csproj", "{24093217-E352-4B06-9138-C0641657F49D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -55,26 +54,26 @@ Global
{B01998E7-3FE2-4A66-968A-0B7725309129}.Release|x64.Build.0 = Release|Any CPU
{B01998E7-3FE2-4A66-968A-0B7725309129}.Release|x86.ActiveCfg = Release|Any CPU
{B01998E7-3FE2-4A66-968A-0B7725309129}.Release|x86.Build.0 = Release|Any CPU
{5C9C773B-43AF-475C-A56A-96CDA259D4D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5C9C773B-43AF-475C-A56A-96CDA259D4D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C9C773B-43AF-475C-A56A-96CDA259D4D8}.Debug|x64.ActiveCfg = Debug|Any CPU
{5C9C773B-43AF-475C-A56A-96CDA259D4D8}.Debug|x64.Build.0 = Debug|Any CPU
{5C9C773B-43AF-475C-A56A-96CDA259D4D8}.Debug|x86.ActiveCfg = Debug|Any CPU
{5C9C773B-43AF-475C-A56A-96CDA259D4D8}.Debug|x86.Build.0 = Debug|Any CPU
{5C9C773B-43AF-475C-A56A-96CDA259D4D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C9C773B-43AF-475C-A56A-96CDA259D4D8}.Release|Any CPU.Build.0 = Release|Any CPU
{5C9C773B-43AF-475C-A56A-96CDA259D4D8}.Release|x64.ActiveCfg = Release|Any CPU
{5C9C773B-43AF-475C-A56A-96CDA259D4D8}.Release|x64.Build.0 = Release|Any CPU
{5C9C773B-43AF-475C-A56A-96CDA259D4D8}.Release|x86.ActiveCfg = Release|Any CPU
{5C9C773B-43AF-475C-A56A-96CDA259D4D8}.Release|x86.Build.0 = Release|Any CPU
{24093217-E352-4B06-9138-C0641657F49D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{24093217-E352-4B06-9138-C0641657F49D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24093217-E352-4B06-9138-C0641657F49D}.Debug|x64.ActiveCfg = Debug|Any CPU
{24093217-E352-4B06-9138-C0641657F49D}.Debug|x64.Build.0 = Debug|Any CPU
{24093217-E352-4B06-9138-C0641657F49D}.Debug|x86.ActiveCfg = Debug|Any CPU
{24093217-E352-4B06-9138-C0641657F49D}.Debug|x86.Build.0 = Debug|Any CPU
{24093217-E352-4B06-9138-C0641657F49D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24093217-E352-4B06-9138-C0641657F49D}.Release|Any CPU.Build.0 = Release|Any CPU
{24093217-E352-4B06-9138-C0641657F49D}.Release|x64.ActiveCfg = Release|Any CPU
{24093217-E352-4B06-9138-C0641657F49D}.Release|x64.Build.0 = Release|Any CPU
{24093217-E352-4B06-9138-C0641657F49D}.Release|x86.ActiveCfg = Release|Any CPU
{24093217-E352-4B06-9138-C0641657F49D}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{110F6221-F88C-44D8-B9E3-B3D1B9691DFD} = {D1C8192B-F35B-4433-9E5F-05F9E92DA58F}
{B01998E7-3FE2-4A66-968A-0B7725309129} = {779D4366-494E-4582-ACDA-38D55AEC2EE5}
{5C9C773B-43AF-475C-A56A-96CDA259D4D8} = {A4341B5B-E943-490B-94AE-D4637A7AF37C}
{24093217-E352-4B06-9138-C0641657F49D} = {A4341B5B-E943-490B-94AE-D4637A7AF37C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F11BF11A-54C0-49CA-B567-850A4C6AC40A}
Expand Down
57 changes: 44 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
# Fork of NatchEurope/FluentEmail.Graph

Fork of [NatchEurope/FluentEmail.Graph](https://github.com/NatchEurope/FluentEmail.Graph) that modifies the `GraphSender` to use an upload session for sending emails with attachments that are 3MB or larger. I was receiving a Microsoft Graph API error when trying to use FluentEmail.Graph to send emails with attachments over 3MB.

[Microsoft Docs on using the Graph API to send large attachments](https://docs.microsoft.com/en-us/graph/outlook-large-attachments?tabs=csharp)

Unfortunately, the Microsoft Graph API `Send` method does not have a `SaveSentItems` argument like the `SendMail` method does, so I had to remove the option to disable saving sent items. See [Link 1](https://docs.microsoft.com/en-us/answers/questions/337574/graph-sdk-i-want-to-send-the-saved-draft-mail-but.html), [Link 2](https://docs.microsoft.com/en-us/graph/api/message-send?view=graph-rest-1.0&tabs=http), and [Link 3](https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/743).

# FluentEmail.Graph

Sender for [FluentEmail](https://github.com/lukencode/FluentEmail) that uses [Microsoft Graph API](https://docs.microsoft.com/en-us/graph/api/resources/mail-api-overview?view=graph-rest-1.0).
Sender for [FluentEmail](https://github.com/lukencode/FluentEmail) that
uses [Microsoft Graph API](https://docs.microsoft.com/en-us/graph/api/resources/mail-api-overview?view=graph-rest-1.0).

![Nuget](https://img.shields.io/nuget/v/FluentEmail.Graph)

Expand All @@ -34,19 +27,57 @@ Example config in `appsettings.json`
```json
{
"GraphSenderOptions": {
"AppId": "your app id",
"TenantId": "your tenant id",
"Secret": "your secret here",
"ClientId": "your app id",
"Secret": "your secret here"
}
}
```

## v2

The original version only used
the [user: sendMail](https://docs.microsoft.com/en-us/graph/api/user-sendmail?view=graph-rest-1.0&tabs=http) Graph API
endpoint. This could not handle attachments over 3MB.

Starting with v2, if you have included any attachments, the implementation will switch to the following:

- A [draft message](https://docs.microsoft.com/en-us/graph/api/user-post-messages?view=graph-rest-1.0&tabs=http) is
created
- Attachments are added
using [attachment: createUploadSession](https://docs.microsoft.com/en-us/graph/api/attachment-createuploadsession?view=graph-rest-1.0&tabs=http)
- The mail is sent
using [message: send](https://docs.microsoft.com/en-us/graph/api/message-send?view=graph-rest-1.0&tabs=http).

⚠️BREAKING: The `Mail.ReadWrite` permission is required when adding attachments.

[Microsoft Docs on using the Graph API to send large attachments](https://docs.microsoft.com/en-us/graph/outlook-large-attachments?tabs=csharp)

⚠️REMOVED: Unfortunately, the Microsoft Graph API `Send` method does not have a `SaveSentItems` argument like
the `SendMail` method
that was previously used. The `SaveSentItems` option has been removed and there is no way to disable this anymore. (
See [Link 1](https://docs.microsoft.com/en-us/answers/questions/337574/graph-sdk-i-want-to-send-the-saved-draft-mail-but.html)
, [Link 2](https://docs.microsoft.com/en-us/graph/api/message-send?view=graph-rest-1.0&tabs=http),
and [Link 3](https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/743)).

Uploading attachments to a draft message was contributed by [@huntmj01](https://github.com/huntmj01).

## Graph API Permissions

The `Mail.Send` permission must be granted.

Adding attachments? Then the `Mail.ReadWrite` permissions is also required.

## Release

Create new release with creation of new tag on main branch.

Start [publish](https://github.com/ESC-BV/FluentEmail.Graph/actions/workflows/publish.yml) manually, for the new tag. This will push the package to github and nuget.org
Start [publish](https://github.com/ESC-BV/FluentEmail.Graph/actions/workflows/publish.yml) manually, for the new tag.
This will push the package to github and nuget.org

## Origin

Code originally written by [Matt Goldman](https://github.com/matt-goldman) and [merged](https://github.com/lukencode/FluentEmail/pull/218) into FluentEmail repo. But it was not published to NuGet until January 2021. Because we needed this implementation we created a separate repo, modified the code a bit and published it to NuGet.
Code originally written by [Matt Goldman](https://github.com/matt-goldman)
and [merged](https://github.com/lukencode/FluentEmail/pull/218) into FluentEmail repo. But it was not published to NuGet
until January 2021. Because we needed this implementation we created a separate repo, modified the code a bit and
published it to NuGet.
63 changes: 0 additions & 63 deletions sample/SendMailSample/Program.cs

This file was deleted.

25 changes: 0 additions & 25 deletions sample/SendMailSample/SendMailSample.csproj

This file was deleted.

8 changes: 0 additions & 8 deletions sample/SendMailSample/appsettings.json

This file was deleted.

97 changes: 97 additions & 0 deletions sample/SendMailTestApp/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// See https://aka.ms/new-console-template for more information

using FluentEmail.Core;
using FluentEmail.Core.Interfaces;
using FluentEmail.Graph;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace SendMailTestApp;

using System.Reflection;

class Program
{
static async Task Main(string[] args)
{
var configurationRoot = GetConfigurationRoot(args);
var graphSenderOptions = configurationRoot.GetRequiredSection("GraphSenderOptions")
.Get<GraphSenderOptions>();
var fromAddress = configurationRoot.GetValue<string>("MailOptions:FromAddress");

var services = new ServiceCollection();
services.AddScoped<IFluentEmailFactory, FluentEmailFactory>();
services.AddFluentEmail(fromAddress)
.AddGraphSender(graphSenderOptions);
var serviceProvider = services.BuildServiceProvider();

// get mail service and out Graph sender
var emailFactory = serviceProvider.GetRequiredService<IFluentEmailFactory>();
var sender = serviceProvider.GetRequiredService<ISender>();
if (sender is not GraphSender)
{
Console.WriteLine("GraphSender not resolved.");

return;
}

Console.WriteLine("Enter destination e-mail address to send test mail to:");
var destinationAddress = Console.ReadLine();

Console.WriteLine("Add attachments? Type 'Y' for yes.");
var addAttachment = (Console.ReadLine() ?? string.Empty).Equals("Y", StringComparison.OrdinalIgnoreCase);

var email = emailFactory.Create();
email.SetFrom(fromAddress)
.To(destinationAddress)
.Subject("Test Email Graph API")
.Body("This is the <b>body</b> of the mail.");
email.Data.IsHtml = true;

if (addAttachment)
{
Console.WriteLine("Adding attachments - this will use another Graph API endpoint that needs the Mail.ReadWrite permission.");
email.AttachFromFilename("TestAttachmentSmall.txt");
email.AttachFromFilename("TestAttachmentLarge.txt");
}
else
{
Console.WriteLine("Not adding attachment - this will use default Graph API endpoint that needs the Mail.Send permission.");
}

var response = await sender.SendAsync(email);
if (response.Successful)
{
Console.WriteLine("Mail sent.");
}
else
{
Console.WriteLine("Mail was NOT sent.");
foreach (var errorMessage in response.ErrorMessages)
{
Console.WriteLine("ERROR");
Console.WriteLine(errorMessage);
}
}
}

private static IConfigurationRoot GetConfigurationRoot(string[] args)
{
var config = new ConfigurationBuilder();
config.AddJsonFile("appsettings.json", optional: true);

var appAssembly = Assembly.Load(new AssemblyName("SendMailTestApp"));
config.AddUserSecrets(appAssembly, optional: false);

config.AddEnvironmentVariables();

if (args is { Length: > 0 })
{
config.AddCommandLine(args);
}

var configurationRoot = config.Build();

return configurationRoot;
}
}
Loading