From a3897807061cb66c019c2f65df98c048a1333e90 Mon Sep 17 00:00:00 2001 From: John Carew Date: Mon, 16 Dec 2024 09:43:11 -0600 Subject: [PATCH] Add support for inline attachments in SmtpMailer (#413) Enhanced the `Attachment` class by adding a `ContentId` property to support inline content. Updated `SmtpMailer` to handle attachments with non-empty `ContentId` as linked resources, generating RFC-compliant `ContentId` using `MimeKit.Utils.MimeUtils.GenerateMessageId()`. Modified the HTML body to reference the correct `ContentId`. Attachments with empty or whitespace `ContentId` are added as regular attachments. Co-authored-by: James Hickey --- Src/Coravel.Mailer/Mail/Attachment.cs | 3 ++- Src/Coravel.Mailer/Mail/Mailers/SmtpMailer.cs | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Src/Coravel.Mailer/Mail/Attachment.cs b/Src/Coravel.Mailer/Mail/Attachment.cs index b3bdb950..3932680e 100644 --- a/Src/Coravel.Mailer/Mail/Attachment.cs +++ b/Src/Coravel.Mailer/Mail/Attachment.cs @@ -3,6 +3,7 @@ namespace Coravel.Mailer.Mail public class Attachment { public byte[] Bytes { get; set; } - public string Name { get; set; } + public string Name { get; set; } + public string ContentId { get; set; } } } \ No newline at end of file diff --git a/Src/Coravel.Mailer/Mail/Mailers/SmtpMailer.cs b/Src/Coravel.Mailer/Mail/Mailers/SmtpMailer.cs index f3933213..1791cee3 100644 --- a/Src/Coravel.Mailer/Mail/Mailers/SmtpMailer.cs +++ b/Src/Coravel.Mailer/Mail/Mailers/SmtpMailer.cs @@ -89,7 +89,16 @@ private static void SetMailBody(MessageBody message, IEnumerable att { foreach (var attachment in attachments) { - bodyBuilder.Attachments.Add(attachment.Name, attachment.Bytes); + if (string.IsNullOrWhiteSpace(attachment.ContentId) == false) + { + var image = bodyBuilder.LinkedResources.Add(attachment.Name, attachment.Bytes); + // We do this instead of using their value because RFC states the Content-Id value MUST be in the message id format. + image.ContentId = MimeKit.Utils.MimeUtils.GenerateMessageId(); + // Now replace where they applied it in the html template with the updated correct version + bodyBuilder.HtmlBody = bodyBuilder.HtmlBody.Replace($"\"cid:{attachment.ContentId}\"", $"\"cid:{image.ContentId}\"", System.StringComparison.OrdinalIgnoreCase); + } + else + bodyBuilder.Attachments.Add(attachment.Name, attachment.Bytes); } }