Skip to content

Commit

Permalink
Merge pull request #17437 from abpframework/mail
Browse files Browse the repository at this point in the history
Support attachments and `ExtraProperties` when sending emails.
  • Loading branch information
hikalkan committed Aug 25, 2023
2 parents e388905 + dc34d74 commit c17c4c2
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 29 deletions.
5 changes: 5 additions & 0 deletions docs/en/Emailing.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ namespace MyProject
`SendAsync` method has overloads to supply more parameters like;

* **from**: You can set this as the first argument to set a sender email address. If not provided, the default sender address is used (see the email settings below).
* **to**: You can set the target email address.
* **subject**: You can set the email subject.
* **body**: You can set the email body.
* **isBodyHtml**: Indicates whether the email body may contain HTML tags. **Default: true**.
* **attachments**: You can pass a list of `EmailAttachment` to add attachments to the email.
* **extraProperties**: You can pass extra properties and use these properties in your own `IEmailSender` implementation to implement more mail sending features.

> `IEmailSender` is the suggested way to send emails, since it makes your code provider independent.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ public BackgroundEmailSendingJob(IEmailSender emailSender)
EmailSender = emailSender;
}

public override async Task ExecuteAsync(BackgroundEmailSendingJobArgs args)
public async override Task ExecuteAsync(BackgroundEmailSendingJobArgs args)
{
if (args.From.IsNullOrWhiteSpace())
{
await EmailSender.SendAsync(args.To, args.Subject, args.Body, args.IsBodyHtml);
await EmailSender.SendAsync(args.To, args.Subject, args.Body, args.IsBodyHtml, args.Attachments, args.ExtraProperties);
}
else
{
await EmailSender.SendAsync(args.From!, args.To, args.Subject, args.Body, args.IsBodyHtml);
await EmailSender.SendAsync(args.From!, args.To, args.Subject, args.Body, args.IsBodyHtml, args.Attachments, args.ExtraProperties);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Data;

namespace Volo.Abp.Emailing;

Expand All @@ -18,5 +20,7 @@ public class BackgroundEmailSendingJobArgs
/// </summary>
public bool IsBodyHtml { get; set; } = true;

//TODO: Add other properties and attachments
public List<EmailAttachment>? Attachments { get; set; }

public ExtraPropertyDictionary? ExtraProperties { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace Volo.Abp.Emailing;

[Serializable]
public class EmailAttachment
{
public string? Name { get; set; }

public byte[]? File { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.Data;

namespace Volo.Abp.Emailing;

Expand All @@ -24,20 +28,33 @@ protected EmailSenderBase(IEmailSenderConfiguration configuration, IBackgroundJo
BackgroundJobManager = backgroundJobManager;
}

public virtual async Task SendAsync(string to, string? subject, string? body, bool isBodyHtml = true)
public virtual async Task SendAsync(string to, string? subject, string? body, bool isBodyHtml = true, List<EmailAttachment>? attachments = null, ExtraPropertyDictionary? extraProperties = null)
{
await SendAsync(new MailMessage
{
To = { to },
Subject = subject,
Body = body,
IsBodyHtml = isBodyHtml
});
await SendAsync(BuildMailMessage(null, to, subject, body, isBodyHtml, attachments, extraProperties));
}

public virtual async Task SendAsync(string from, string to, string? subject, string? body, bool isBodyHtml = true)
public virtual async Task SendAsync(string from, string to, string? subject, string? body, bool isBodyHtml = true, List<EmailAttachment>? attachments = null, ExtraPropertyDictionary? extraProperties = null)
{
await SendAsync(new MailMessage(from, to, subject, body) { IsBodyHtml = isBodyHtml });
await SendAsync(BuildMailMessage(from, to, subject, body, isBodyHtml, attachments, extraProperties));
}

protected virtual MailMessage BuildMailMessage(string? from, string to, string? subject, string? body, bool isBodyHtml = true, List<EmailAttachment>? attachments = null, ExtraPropertyDictionary? extraProperties = null)
{
var message = from == null
? new MailMessage { To = { to }, Subject = subject, Body = body, IsBodyHtml = isBodyHtml }
: new MailMessage(from, to, subject, body) { IsBodyHtml = isBodyHtml };

if (attachments != null)
{
foreach (var attachment in attachments.Where(x => x.File != null))
{
var fileStream = new MemoryStream(attachment.File!);
fileStream.Seek(0, SeekOrigin.Begin);
message.Attachments.Add(new Attachment(fileStream, attachment.Name));
}
}

return message;
}

public virtual async Task SendAsync(MailMessage mail, bool normalize = true)
Expand All @@ -50,11 +67,11 @@ public virtual async Task SendAsync(MailMessage mail, bool normalize = true)
await SendEmailAsync(mail);
}

public virtual async Task QueueAsync(string to, string subject, string body, bool isBodyHtml = true)
public virtual async Task QueueAsync(string to, string subject, string body, bool isBodyHtml = true, List<EmailAttachment>? attachments = null, ExtraPropertyDictionary? extraProperties = null)
{
if (!BackgroundJobManager.IsAvailable())
{
await SendAsync(to, subject, body, isBodyHtml);
await SendAsync(to, subject, body, isBodyHtml, attachments, extraProperties);
return;
}

Expand All @@ -64,16 +81,18 @@ await BackgroundJobManager.EnqueueAsync(
To = to,
Subject = subject,
Body = body,
IsBodyHtml = isBodyHtml
IsBodyHtml = isBodyHtml,
Attachments = attachments,
ExtraProperties = extraProperties
}
);
}

public virtual async Task QueueAsync(string from, string to, string subject, string body, bool isBodyHtml = true)
public virtual async Task QueueAsync(string from, string to, string subject, string body, bool isBodyHtml = true, List<EmailAttachment>? attachments = null, ExtraPropertyDictionary? extraProperties = null)
{
if (!BackgroundJobManager.IsAvailable())
{
await SendAsync(from, to, subject, body, isBodyHtml);
await SendAsync(from, to, subject, body, isBodyHtml, attachments, extraProperties);
return;
}

Expand All @@ -84,7 +103,9 @@ await BackgroundJobManager.EnqueueAsync(
To = to,
Subject = subject,
Body = body,
IsBodyHtml = isBodyHtml
IsBodyHtml = isBodyHtml,
Attachments = attachments,
ExtraProperties = extraProperties
}
);
}
Expand Down
22 changes: 15 additions & 7 deletions framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/IEmailSender.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Net.Mail;
using System.Collections.Generic;
using System.Net.Mail;
using System.Threading.Tasks;
using Volo.Abp.Data;

namespace Volo.Abp.Emailing;

Expand All @@ -15,7 +17,9 @@ Task SendAsync(
string to,
string? subject,
string? body,
bool isBodyHtml = true
bool isBodyHtml = true,
List<EmailAttachment>? attachments = null,
ExtraPropertyDictionary? extraProperties = null
);

/// <summary>
Expand All @@ -26,7 +30,9 @@ Task SendAsync(
string to,
string? subject,
string? body,
bool isBodyHtml = true
bool isBodyHtml = true,
List<EmailAttachment>? attachments = null,
ExtraPropertyDictionary? extraProperties = null
);

/// <summary>
Expand All @@ -49,7 +55,9 @@ Task QueueAsync(
string to,
string subject,
string body,
bool isBodyHtml = true
bool isBodyHtml = true,
List<EmailAttachment>? attachments = null,
ExtraPropertyDictionary? extraProperties = null
);

/// <summary>
Expand All @@ -60,8 +68,8 @@ Task QueueAsync(
string to,
string subject,
string body,
bool isBodyHtml = true
bool isBodyHtml = true,
List<EmailAttachment>? attachments = null,
ExtraPropertyDictionary? extraProperties = null
);

//TODO: Add other Queue methods too. Problem: MailMessage is not serializable so can not be used in background jobs.
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public async Task<SmtpClient> BuildClientAsync()
}
}

protected override async Task SendEmailAsync(MailMessage mail)
protected async override Task SendEmailAsync(MailMessage mail)
{
using (var smtpClient = await BuildClientAsync())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public MailKitSmtpEmailSender(ISmtpEmailSenderConfiguration smtpConfiguration,
SmtpConfiguration = smtpConfiguration;
}

protected override async Task SendEmailAsync(MailMessage mail)
protected async override Task SendEmailAsync(MailMessage mail)
{
using (var client = await BuildClientAsync())
{
Expand Down

0 comments on commit c17c4c2

Please sign in to comment.