jstedfast / MimeKit

A .NET MIME creation and parser library with support for S/MIME, PGP, DKIM, TNEF and Unix mbox spools.
http://www.mimekit.net
MIT License
1.82k stars 369 forks source link

Add an image as an in line signature #1046

Closed alasdair-richardson closed 4 months ago

alasdair-richardson commented 4 months ago

I was trying to add an image as an in line signature, following the instructions on github. The code for my send method which added the image looked like this

public async Task SendAsync(string to, string subject, string bodyHtml)
        {
            var signatureFile = "Assets/small.png";

            var message = new MimeMessage();
            message.From.Add(address("VolunteerAdmin@example.com", "VolunteerAdmin"));
            message.To.Add(address(to));
            message.Subject = subject + " (#12345)";

            // generate a Content-Id for the image we'll be referencing
            var contentId = MimeUtils.GenerateMessageId();
            var toAdd = $"<br><img src=\"cid:{contentId}\" alt=\"{signatureFile}>";

            var builder = new BodyBuilder();
            // Set the html version of the message text
            builder.HtmlBody = bodyHtml + toAdd;
            // Since image is referenced from the html text, we'll need to add it
            // to builder.LinkedResources and then set the Content-Id header value
            var s = builder.LinkedResources.Add(signatureFile);
            s.ContentId = contentId;
            // Now we just need to set the message body and we're done
            message.Body = builder.ToMessageBody();

            using (var client = new SmtpClient ()) {
                await client.ConnectAsync("smtp.gmail.com", 587, false);

                // Note: only needed if the SMTP server requires authentication
                await client.AuthenticateAsync(userName, password);

                await client.SendAsync(message);
                await client.DisconnectAsync(true);
            }
        }

Unfortunately the image does not appear inline as expected. The relevant part of the eml file looks like

Date: Fri, 07 Jun 2024 13:59:28 +0100
Subject: {Spam?} Test email (#12345)
Message-Id: <512XSAZ99NU4.0UXE2TG2JKNY2@alasdair-lt>
To: alasdair@attar-richardson.com
MIME-Version: 1.0
Content-Type: multipart/related; boundary="=-CsM9JU5xfJje+bQSas0t2Q==";
    type="text/html"

--=-CsM9JU5xfJje+bQSas0t2Q==
Content-Type: text/html; charset=utf-8

<p>Test email only to home</p><br><img src="cid:UI2XSAZ99NU4.N2IWIPJM9Q2V1@alasdair-lt" alt="Assets/small.png>
--=-CsM9JU5xfJje+bQSas0t2Q==
Content-Type: image/png; name="Assets/small.png"
Content-Transfer-Encoding: base64
Content-Disposition: inline; filename="Assets/small.png"
Content-Location: Assets/small.png
Content-Id: <UI2XSAZ99NU4.N2IWIPJM9Q2V1@alasdair-lt>

iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAABQySURBVHhe7dbbkutGkgRA/f9Pa7ZGU6sSFCBB
... etc
.
--=-CsM9JU5xfJje+bQSas0t2Q==--

In thunderbird the result looks like

image

And in gmail

image

Originally posted by @alasdair-richardson in https://github.com/jstedfast/MimeKit/discussions/953#discussioncomment-9703931

alasdair-richardson commented 4 months ago

Sorry posted in the wrong place initially (as a comment to the welcome to the discussion post)! Not even sure if this is an issue or whether it should just be a discussion.

jstedfast commented 4 months ago

I think the problem is your HTML text:

<p>Test email only to home</p><br><img src="cid:UI2XSAZ99NU4.N2IWIPJM9Q2V1@alasdair-lt" alt="Assets/small.png>

Notice the lack of an end-quote for the alt-text.

Change your code to this:

var toAdd = $"<br><img src=\"cid:{contentId}\" alt=\"{signatureFile}\">";
alasdair-richardson commented 4 months ago

D'oh I thought I might be missing something simple but not that simple!. Thanks for your reponse it is working exactly as it is supposed to now.