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
18 changes: 18 additions & 0 deletions src/Senders/FluentEmail.SendGrid/IFluentEmailExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using FluentEmail.Core;
using FluentEmail.Core.Models;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace FluentEmail.SendGrid
{
public static class IFluentEmailExtensions
{
public static async Task<SendResponse> SendWithTemplateAsync(this IFluentEmail email, string templateId, object templateData)
{
var sendGridSender = email.Sender as ISendGridSender;
return await sendGridSender.SendWithTemplateAsync(email, templateId, templateData);
}
}
}
27 changes: 27 additions & 0 deletions src/Senders/FluentEmail.SendGrid/ISendGridSender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using FluentEmail.Core;
using FluentEmail.Core.Interfaces;
using FluentEmail.Core.Models;
using SendGrid;
using SendGrid.Helpers.Mail;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace FluentEmail.SendGrid
{
public interface ISendGridSender : ISender
{
/// <summary>
/// SendGrid specific extension method that allows you to use a template instead of a message body.
/// For more information, see: https://sendgrid.com/docs/ui/sending-email/how-to-send-an-email-with-dynamic-transactional-templates/.
/// </summary>
/// <param name="email">Fluent email.</param>
/// <param name="templateId">SendGrid template ID.</param>
/// <param name="templateData">SendGrid template data.</param>
/// <param name="token">Optional cancellation token.</param>
/// <returns>A SendResponse object.</returns>
Task<SendResponse> SendWithTemplateAsync(IFluentEmail email, string templateId, object templateData, CancellationToken? token = null);
}
}
53 changes: 45 additions & 8 deletions src/Senders/FluentEmail.SendGrid/SendGridSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace FluentEmail.SendGrid
{
public class SendGridSender : ISender
public class SendGridSender : ISendGridSender
{
private readonly string _apiKey;
private readonly bool _sandBoxMode;
Expand All @@ -30,8 +30,41 @@ public SendResponse Send(IFluentEmail email, CancellationToken? token = null)

public async Task<SendResponse> SendAsync(IFluentEmail email, CancellationToken? token = null)
{
var sendGridClient = new SendGridClient(_apiKey);
var mailMessage = await BuildSendGridMessage(email);

if (email.Data.IsHtml)
{
mailMessage.HtmlContent = email.Data.Body;
}
else
{
mailMessage.PlainTextContent = email.Data.Body;
}

if (!string.IsNullOrEmpty(email.Data.PlaintextAlternativeBody))
{
mailMessage.PlainTextContent = email.Data.PlaintextAlternativeBody;
}

var sendResponse = await SendViaSendGrid(mailMessage, token);

return sendResponse;
}

public async Task<SendResponse> SendWithTemplateAsync(IFluentEmail email, string templateId, object templateData, CancellationToken? token = null)
{
var mailMessage = await BuildSendGridMessage(email);

mailMessage.SetTemplateId(templateId);
mailMessage.SetTemplateData(templateData);

var sendResponse = await SendViaSendGrid(mailMessage, token);

return sendResponse;
}

private async Task<SendGridMessage> BuildSendGridMessage(IFluentEmail email)
{
var mailMessage = new SendGridMessage();
mailMessage.SetSandBoxMode(_sandBoxMode);

Expand All @@ -57,7 +90,10 @@ public async Task<SendResponse> SendAsync(IFluentEmail email, CancellationToken?
mailMessage.AddHeaders(email.Data.Headers.ToDictionary(kvp => kvp.Key, kvp => kvp.Value));
}

mailMessage.Categories = email.Data.Tags.ToList();
if(email.Data.Tags != null && email.Data.Tags.Any())
{
mailMessage.Categories = email.Data.Tags.ToList();
}

if (email.Data.IsHtml)
{
Expand Down Expand Up @@ -94,11 +130,6 @@ public async Task<SendResponse> SendAsync(IFluentEmail email, CancellationToken?
break;
}

if (!string.IsNullOrEmpty(email.Data.PlaintextAlternativeBody))
{
mailMessage.PlainTextContent = email.Data.PlaintextAlternativeBody;
}

if (email.Data.Attachments.Any())
{
foreach (var attachment in email.Data.Attachments)
Expand All @@ -109,6 +140,12 @@ public async Task<SendResponse> SendAsync(IFluentEmail email, CancellationToken?
}
}

return mailMessage;
}

private async Task<SendResponse> SendViaSendGrid(SendGridMessage mailMessage, CancellationToken? token = null)
{
var sendGridClient = new SendGridClient(_apiKey);
var sendGridResponse = await sendGridClient.SendEmailAsync(mailMessage, token.GetValueOrDefault());

var sendResponse = new SendResponse();
Expand Down
21 changes: 21 additions & 0 deletions test/FluentEmail.Core.Tests/SendGridSenderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,27 @@ public async Task CanSendEmail()
Assert.IsTrue(response.Successful);
}

[Test, Ignore("No sendgrid credentials")]
public async Task CanSendTemplateEmail()
{
const string subject = "SendMail Test";
const string templateId = "123456-insert-your-own-id-here";
object templateData = new
{
Name = toName,
ArbitraryValue = "The quick brown fox jumps over the lazy dog."
};

var email = Email
.From(fromEmail, fromName)
.To(toEmail, toName)
.Subject(subject);

var response = await email.SendWithTemplateAsync(templateId, templateData);

Assert.IsTrue(response.Successful);
}

[Test, Ignore("No sendgrid credentials")]
public async Task CanSendEmailWithReplyTo()
{
Expand Down