Note that there are some explanatory texts on larger screens.

plurals
  1. POSending inline email attachments on Google App Engine (Java)
    text
    copied!<p>I'm having difficulty getting my inline attachments to show up inline. When the email client receives the message all of the attachments are with <strong><em>Content-Disposition</em></strong> "attachment" even though I can see from the logs that I'm setting some to "inline". Also anytime I set the CID header it is not making it to the email client (eg. if I view the source / original). Somehow it is being lost as with the content-disposition.</p> <p>I am using the following code:</p> <pre><code>public static void performSend(Event event, Guest guest) throws Exception { Properties props = new Properties(); Session session = Session.getDefaultInstance(props, null); String htmlBody = event.getEmail().getHtmlBody(event.getInlineInvitationImages(), guest); Multipart mp = new MimeMultipart(); MimeBodyPart htmlPart = new MimeBodyPart(); htmlPart.setContent(htmlBody, "text/html"); mp.addBodyPart(htmlPart); //Add attachments for(InvitationImage image : event.getInvitationImages()) { Logger.info("Now attaching image %s, with length %d, content type %s, cid %s and disposition %s", image.filename, image.imageData.length, image.contentType, image.cid, image.getDisposition().toString()); MimeBodyPart attachment = new MimeBodyPart(); attachment.setDisposition(image.getDisposition()); attachment.setFileName(image.filename); attachment.setContentID("&lt;"+image.cid+"&gt;"); DataSource src = new ByteArrayDataSource(image.imageData, image.contentType); attachment.setDataHandler(new DataHandler(src)); mp.addBodyPart(attachment); } Message msg = new MimeMessage(session); msg.setFrom(new InternetAddress("myname@gmail.com", "My Name")); msg.addRecipient(Message.RecipientType.TO, new InternetAddress(guest.email, guest.getFullname())); msg.setSubject(event.getEmail().subject); msg.setContent(mp); msg.saveChanges(); //Log the email ByteArrayOutputStream baos = new ByteArrayOutputStream(); msg.writeTo(baos); new Log(baos.toByteArray()).save(); Transport.send(msg); } </code></pre> <p>A relevant snippet from my GAE log is </p> <blockquote> <p>play.Logger info: Now attaching image myimage.jpg, with length 73336, content type image/jpeg, cid e4ae3388-312d-498e-b958-12e814507934@rsvp-rocket.appspot.com and disposition inline</p> </blockquote> <p>A relevant snippet of the email source looks like this :</p> <pre><code>Content-Type: multipart/mixed; boundary=20cf307f3beca61df004baa44d82 Return-Path: 3-jJXTwsJDD0qruo-qnbjdsflZhk.bnljZxcddcnqfZmgnslZhk.bnl@apphosting.bounces.google.com X-OriginalArrivalTime: 07 Mar 2012 10:05:47.0455 (UTC) FILETIME=[DE047CF0:01CCFC49] --20cf307f3beca61df004baa44d82 Content-Type: multipart/alternative; boundary=20cf307f3beca61de604baa44d80 --20cf307f3beca61de604baa44d80 Content-Type: text/plain; charset=ISO-8859-1; format=flowed; delsp=yes Come to my wedding! --20cf307f3beca61de604baa44d80 Content-Type: text/html; charset=ISO-8859-1 &lt;p style="color: gray;"&gt;Come to my wedding!&lt;/p&gt;&lt;div&gt;&lt;img src="cid:e4ae3388-312d-498e-b958-12e814507934@rsvp-rocket.appspot.com" border="0" /&gt;&lt;/div&gt; --20cf307f3beca61de604baa44d80-- --20cf307f3beca61df004baa44d82 Content-Type: image/jpeg; name="DamianKathrynWeddingSaveTheDate.jpg" Content-Disposition: attachment; filename="DamianKathrynWeddingSaveTheDate.jpg" Content-Transfer-Encoding: base64 </code></pre> <p>Any thoughts? Why is the disposition and CID being cleared? Am I missing some obvious piece or is this an example of the arcane arts of email?</p> <h1>Update:</h1> <p>I've dumped the outgoing email to a Log entity in the datastore. In there I can see that the inline image does indeed have the Content-Disposition of "inline". So by the time it gets to the email clients, something has removed it. The weird thing is that the html part is base64 encoded (as per below). Is this normal?</p> <p>Here's what arrives at Gmail:</p> <pre><code>Message-ID: &lt;20cf307d02b099e30804bab9b98e@google.com&gt; Date: Thu, 08 Mar 2012 11:39:12 +0000 Subject: Test invite From: My Name &lt;myname@gmail.com&gt; To: My Name &lt;myname@gmail.com&gt; Content-Type: multipart/mixed; boundary=20cf307d02b099e2fb04bab9b98d --20cf307d02b099e2fb04bab9b98d Content-Type: multipart/alternative; boundary=20cf307d02b099e2f404bab9b98b --20cf307d02b099e2f404bab9b98b Content-Type: text/plain; charset=ISO-8859-1; format=flowed; delsp=yes Come to my wedding! --20cf307d02b099e2f404bab9b98b Content-Type: text/html; charset=ISO-8859-1 &lt;p style="color: gray;"&gt;Come to my wedding!&lt;/p&gt;&lt;div&gt;&lt;img src="cid:e4ae3388-312d-498e-b958-12e814507934@rsvp-rocket.appspot.com" border="0" /&gt;&lt;/div&gt; --20cf307d02b099e2f404bab9b98b-- --20cf307d02b099e2fb04bab9b98d Content-Type: image/jpeg; name="DamianKathrynWeddingSaveTheDate.jpg" Content-Disposition: attachment; filename="DamianKathrynWeddingSaveTheDate.jpg" Content-Transfer-Encoding: base64 /9j/4AAQSkZJRgABAQEBLAEsAAD/7QBSUGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAABkcAVoAAxsl </code></pre> <p>And here's what is logged by me for the same message:</p> <pre><code>From: My Name &lt;myname@gmail.com&gt; To: My Name &lt;myname@gmail.com&gt; Message-ID: &lt;29985819.01331206751990.JavaMail.javamailuser@localhost&gt; Subject: Test invite MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_0_20814850.1331206751553" ------=_Part_0_20814850.1331206751553 Content-Type: text/html Content-Transfer-Encoding: base64 PHAgc3R5bGU9ImNvbG9yOiBncmF5OyI+Q29tZSB0byBteSB3ZWRkaW5nITwvcD48ZGl2PjxpbWcg c3JjPSJjaWQ6ZTRhZTMzODgtMzEyZC00OThlLWI5NTgtMTJlODE0NTA3OTM0QHJzdnAtcm9ja2V0 LmFwcHNwb3QuY29tIiBib3JkZXI9IjAiIC8+PC9kaXY+ ------=_Part_0_20814850.1331206751553 Content-Type: image/jpeg; name=DamianKathrynWeddingSaveTheDate.jpg Content-Transfer-Encoding: base64 Content-Disposition: inline; filename=DamianKathrynWeddingSaveTheDate.jpg Content-ID: &lt;e4ae3388-312d-498e-b958-12e814507934@rsvp-rocket.appspot.com&gt; /9j/4AAQSkZJRgABAQEBLAEsAAD/7QBSUGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAABkcAVoAAxsl </code></pre> <p>Any ideas? Email on GAE is quickly making it to the "too-hard" basket when I look at Amazon SES and Postmark.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload