How to send embedded images with sendgrid emails?

不问归期 提交于 2019-12-01 18:39:16

I juggled around this for a little bit too. The solution was to Attach the image first and then to Embed afterwards with the direct name of the file in the email.

var myMessage = new SendGridMessage();
myMessage.AddTo("to@email.com");
myMessage.From = "from@email.com";
myMessage.Subject ="Forgotten Password";
string body = @"<div><img src='cid:email_reset' alt='Email Reset Header' border='0' /></div>" +
              @"<p>Content...</p>";

string att = Request.PhysicalApplicationPath + @"Content\files\images\email_reset.jpg";
var attachment = new Attachment(att, new ContentType("image/jpeg"));
var linkedResource = new LinkedResource(att, new ContentType("image/jpeg"));
myMessage.AddAttachment(attachment.ContentStream, attachment.Name);
myMessage.EmbedImage(attachment.Name, "email_reset");

myMessage.Text = WebUtility.HtmlDecode(Regex.Replace(body, "<[^>]*(>|$)", string.Empty));
myMessage.Html = body;

// Authenticate and Send the email

I talked with a SendGrid customer support engineer and he directed me here..

https://github.com/sendgrid/sendgrid-csharp/blob/ca91fad22dfec2cd1219267fe979c1d9a33a522e/SendGrid/SendGridMail/SendGrid.cs#L211

So your code would be...

var message = SendGrid.GetInstance();
message.Subject = "Warning";
message.From = new MailAddress("from_user@test.com");
message.To = new MailAddress[] { new MailAddress("to_user@test.com") };
message.Html = "<html><body><a href='http://www.mywebsite.com' title='My Website'><img src='cid:my_image' alt='My Image' border='0' /></a><br /><h1>My E-mail Title</h1>E-mail content.</body></html>";

// added    
message.EmbedImage(@"C:\my_image.png","my_image");
// added

var transportSMTP = SMTP.GetInstance(new NetworkCredential("user", "pass"));
transportSMTP.Deliver(message);

I'm looking for a way to add a MemoryStream object instead of a filename, which it doesn't look like this is available yet.

For anyone who is struggling with sending embedded images in the emails via SendGrid and using the stored templates, here's how it works:

/* In my case the images reside in the SQL DB as BLOBs but for this example it does not matter.
All you need is an array of bytes with your image.
*/
var imageContent = File.ReadAllBytes("Images\\logo_eml.jpg");
using (MemoryStream s = new MemoryStream(imageContent))
{
    ContentType ctype = new ContentType("image/jpg");
    var attachment = new System.Net.Mail.Attachment(s, ctype);
    var linkedResource = new LinkedResource(s, ctype);
    attachment.Name = "cibc_ins_logo_eml.jpg";
    emailMsg.AddAttachment(attachment.ContentStream, attachment.Name);
    emailMsg.EmbedImage(attachment.Name, linkedResource.ContentId + ".jpg");

    values.Add("%embedLogo%", linkedResource.ContentId + ".jpg");
}

string templateJSON = "{\"to\": [\"%to%\"],\r \"sub\": {\":name\": [\"%name%\"],\":embedLogo\": [\"%embedLogo%\"]},\r \"category\": [\"Quotes\"],\r \"filters\": {\"templates\": {\"settings\": {\"enable\": 1,\"template_id\": \"%templateid%\"}}}}"
emailMsg.Headers.Add("x-smtpapi", SubstituteTemplate(templateJSON, values));

The last line will replace the values. In my case it simply does a regex replace. This code will have to take care of substituting %embedLogo% in your particular JSON with the value of linkedResource.ContentId+".jpg" stored previously in the values which is a Dictionary<string,string>.

Here's what you need in the stored HTML template:

<img width="227" height="86" src="cid::embedLogo">

CID and two colons are critical.

Then Gmail will show the images embedded and not just attached!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!