Skip to content

Commit aa3a419

Browse files
committed
1 parent e1a8a83 commit aa3a419

File tree

4 files changed

+35
-49
lines changed

4 files changed

+35
-49
lines changed

src/Senders/FluentEmail.Azure.Email/AzureEmailSender.cs

Lines changed: 29 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.IO;
43
using System.Linq;
54
using System.Threading;
65
using System.Threading.Tasks;
76
using Azure;
87
using Azure.Communication.Email;
9-
using Azure.Communication.Email.Models;
108
using Azure.Core;
119
using FluentEmail.Core;
1210
using FluentEmail.Core.Interfaces;
@@ -20,6 +18,13 @@ public class AzureEmailSender : ISender
2018
{
2119
private EmailClient _emailClient;
2220

21+
/// <summary>
22+
/// The priority header to use when specifying the importance of an email.
23+
/// Values: 1-High, 3-Normal (default), 5-Low
24+
/// https://sendgrid.com/blog/magic-email-headers/
25+
/// </summary>
26+
const string PriorityHeader = "X-Priority";
27+
2328
/// <summary>
2429
/// Initializes a new instance of <see cref="AzureEmailSender"/>
2530
/// </summary>
@@ -96,8 +101,10 @@ public async Task<SendResponse> SendAsync(IFluentEmail email, CancellationToken?
96101

97102
var emailRecipients = new EmailRecipients(toRecipients, ccRecipients, bccRecipients);
98103

99-
var sender = $"{email.Data.FromAddress.Name} <{email.Data.FromAddress.EmailAddress}>";
100-
var emailMessage = new EmailMessage(sender, emailContent, emailRecipients);
104+
// Azure Email Sender doesn't allow us to specify the 'from' display name (instead the sender name is defined in the blade configuration)
105+
// var sender = $"{email.Data.FromAddress.Name} <{email.Data.FromAddress.EmailAddress}>";
106+
var sender = email.Data.FromAddress.EmailAddress;
107+
var emailMessage = new EmailMessage(sender, emailRecipients, emailContent);
101108

102109
if (email.Data.ReplyToAddresses.Any(a => !string.IsNullOrWhiteSpace(a.EmailAddress)))
103110
{
@@ -111,7 +118,7 @@ public async Task<SendResponse> SendAsync(IFluentEmail email, CancellationToken?
111118
{
112119
foreach (var header in email.Data.Headers)
113120
{
114-
emailMessage.CustomHeaders.Add(new EmailCustomHeader(header.Key, header.Value));
121+
emailMessage.Headers.Add(header.Key, header.Value);
115122
}
116123
}
117124

@@ -123,19 +130,19 @@ public async Task<SendResponse> SendAsync(IFluentEmail email, CancellationToken?
123130
}
124131
}
125132

126-
emailMessage.Importance = email.Data.Priority switch
133+
emailMessage.Headers.Add(PriorityHeader, (email.Data.Priority switch
127134
{
128-
Priority.High => EmailImportance.High,
129-
Priority.Normal => EmailImportance.Normal,
130-
Priority.Low => EmailImportance.Low,
131-
_ => EmailImportance.Normal
132-
};
135+
Priority.High => 1,
136+
Priority.Normal => 3,
137+
Priority.Low => 5,
138+
_ => 3
139+
}).ToString());
140+
133141

134142
try
135143
{
136-
var sendEmailResult = (await _emailClient.SendAsync(emailMessage, token ?? CancellationToken.None)).Value;
137-
138-
var messageId = sendEmailResult.MessageId;
144+
EmailSendOperation sendOperation = await _emailClient.SendAsync(WaitUntil.Started, emailMessage, token ?? CancellationToken.None);
145+
var messageId = sendOperation.Id;
139146
if (string.IsNullOrWhiteSpace(messageId))
140147
{
141148
return new SendResponse
@@ -147,32 +154,21 @@ public async Task<SendResponse> SendAsync(IFluentEmail email, CancellationToken?
147154
// We want to verify that the email was sent.
148155
// The maximum time we will wait for the message status to be sent/delivered is 2 minutes.
149156
var cancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(2));
150-
SendStatusResult sendStatusResult;
151-
do
152-
{
153-
sendStatusResult = await _emailClient.GetSendStatusAsync(messageId, cancellationToken.Token);
154-
155-
if (sendStatusResult.Status != SendStatus.Queued)
156-
{
157-
break;
158-
}
159-
160-
await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken.Token);
161-
} while (!cancellationToken.IsCancellationRequested);
157+
var sendStatusResult = sendOperation.WaitForCompletion(cancellationToken.Token).Value;
162158

163-
if (cancellationToken.IsCancellationRequested)
159+
if (sendStatusResult.Status == EmailSendStatus.Succeeded)
164160
{
165161
return new SendResponse
166162
{
167-
ErrorMessages = new List<string> { "Failed to send email, timed out while getting status." }
163+
MessageId = messageId
168164
};
169165
}
170166

171-
if (sendStatusResult.Status == SendStatus.OutForDelivery)
167+
if (cancellationToken.IsCancellationRequested)
172168
{
173169
return new SendResponse
174170
{
175-
MessageId = messageId
171+
ErrorMessages = new List<string> { "Failed to send email, timed out while getting status." }
176172
};
177173
}
178174

@@ -189,17 +185,7 @@ public async Task<SendResponse> SendAsync(IFluentEmail email, CancellationToken?
189185
};
190186
}
191187
}
192-
193-
private async Task<EmailAttachment> ConvertAttachment(Attachment attachment) =>
194-
new(attachment.Filename, attachment.ContentType,
195-
await GetAttachmentAsBase64String(attachment.Data));
196188

197-
private async Task<string> GetAttachmentAsBase64String(Stream stream)
198-
{
199-
using var ms = new MemoryStream();
200-
201-
await stream.CopyToAsync(ms);
202-
203-
return Convert.ToBase64String(ms.ToArray());
204-
}
205-
}
189+
private async Task<EmailAttachment> ConvertAttachment(Attachment attachment) =>
190+
new(attachment.Filename, attachment.ContentType, await BinaryData.FromStreamAsync(attachment.Data));
191+
}

src/Senders/FluentEmail.Azure.Email/FluentEmail.Azure.Email.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
</ItemGroup>
1616

1717
<ItemGroup>
18-
<PackageReference Include="Azure.Communication.Email" Version="1.0.0-beta.1" />
18+
<PackageReference Include="Azure.Communication.Email" Version="1.0.1" />
1919
</ItemGroup>
2020

2121
</Project>

src/Senders/FluentEmail.Azure.Email/FluentEmailAzureEmailBuilderExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public static FluentEmailServicesBuilder AddAzureEmailSender(
1414
this FluentEmailServicesBuilder builder,
1515
string connectionString)
1616
{
17-
builder.Services.TryAdd(ServiceDescriptor.Scoped<ISender>(_ => new AzureEmailSender(connectionString)));
17+
builder.Services.TryAdd(ServiceDescriptor.Singleton((IServiceProvider x) => (ISender)(object)new AzureEmailSender(connectionString)));
1818
return builder;
1919
}
2020

@@ -23,7 +23,7 @@ public static FluentEmailServicesBuilder AddAzureEmailSender(
2323
string connectionString,
2424
EmailClientOptions options)
2525
{
26-
builder.Services.TryAdd(ServiceDescriptor.Scoped<ISender>(_ => new AzureEmailSender(connectionString, options)));
26+
builder.Services.TryAdd(ServiceDescriptor.Singleton((IServiceProvider x) => (ISender)(object)new AzureEmailSender(connectionString, options)));
2727
return builder;
2828
}
2929

@@ -33,7 +33,7 @@ public static FluentEmailServicesBuilder AddAzureEmailSender(
3333
AzureKeyCredential keyCredential,
3434
EmailClientOptions options = default)
3535
{
36-
builder.Services.TryAdd(ServiceDescriptor.Scoped<ISender>(_ => new AzureEmailSender(endpoint, keyCredential, options)));
36+
builder.Services.TryAdd(ServiceDescriptor.Singleton((IServiceProvider x) => (ISender)(object)new AzureEmailSender(endpoint, keyCredential, options)));
3737
return builder;
3838
}
3939

@@ -43,7 +43,7 @@ public static FluentEmailServicesBuilder AddAzureEmailSender(
4343
TokenCredential tokenCredential,
4444
EmailClientOptions options = default)
4545
{
46-
builder.Services.TryAdd(ServiceDescriptor.Scoped<ISender>(_ => new AzureEmailSender(endpoint, tokenCredential, options)));
46+
builder.Services.TryAdd(ServiceDescriptor.Singleton((IServiceProvider x) => (ISender)(object)new AzureEmailSender(endpoint, tokenCredential, options)));
4747
return builder;
4848
}
4949
}

test/FluentEmail.Core.Tests/AzureEmailSenderTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.IO;
33
using System.Threading.Tasks;
44
using NUnit.Framework;

0 commit comments

Comments
 (0)