Отправка встроенных вложений электронной почты в Google App Engine (Java) - PullRequest
2 голосов
/ 07 марта 2012

У меня возникают проблемы с отображением встроенных вложений.Когда почтовый клиент получает сообщение, все вложения имеют Content-Disposition «вложение», хотя из журналов я вижу, что некоторые из них устанавливаются как «встроенные».Также каждый раз, когда я устанавливаю заголовок CID, он не попадает в почтовый клиент (например, если я просматриваю источник / оригинал).Каким-то образом он теряется, как и при расположении содержимого.

Я использую следующий код:

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("<"+image.cid+">");

        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);
}

Соответствующий фрагмент из моего журнала GAE:

play.Logger info: теперь прикрепляем изображение myimage.jpg, длиной 73336, тип контента image / jpeg, cid e4ae3388-312d-498e-b958-12e814507934@rsvp-rocket.appspot.com и расположение в строке

Соответствующий фрагмент источника электронной почты выглядит следующим образом:

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

<p style="color: gray;">Come to my wedding!</p><div><img src="cid:e4ae3388-312d-498e-b958-12e814507934@rsvp-rocket.appspot.com" border="0" /></div>
--20cf307f3beca61de604baa44d80--
--20cf307f3beca61df004baa44d82
Content-Type: image/jpeg; name="DamianKathrynWeddingSaveTheDate.jpg"
Content-Disposition: attachment; 
    filename="DamianKathrynWeddingSaveTheDate.jpg"
Content-Transfer-Encoding: base64

Есть мысли?Почему очищается расположение и CID?Я упускаю какой-то очевидный фрагмент или это пример тайного искусства электронной почты?

Обновление:

Я отправил исходящую электронную почту в объект Log в хранилище данных.Там я вижу, что встроенное изображение действительно имеет Content-Disposition «inline».Так что к тому времени, когда он попадает в почтовые клиенты, что-то уже удаляется.Странно то, что HTML-часть кодируется в base64 (как показано ниже).Это нормально?

Вот что приходит в Gmail:

Message-ID: <20cf307d02b099e30804bab9b98e@google.com>
Date: Thu, 08 Mar 2012 11:39:12 +0000
Subject: Test invite
From: My Name <myname@gmail.com>
To: My Name <myname@gmail.com>
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

<p style="color: gray;">Come to my wedding!</p><div><img src="cid:e4ae3388-312d-498e-b958-12e814507934@rsvp-rocket.appspot.com" border="0" /></div>
--20cf307d02b099e2f404bab9b98b--
--20cf307d02b099e2fb04bab9b98d
Content-Type: image/jpeg; name="DamianKathrynWeddingSaveTheDate.jpg"
Content-Disposition: attachment; 
    filename="DamianKathrynWeddingSaveTheDate.jpg"
Content-Transfer-Encoding: base64

/9j/4AAQSkZJRgABAQEBLAEsAAD/7QBSUGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAABkcAVoAAxsl

А вот что я записал для того же сообщения:

From: My Name <myname@gmail.com>
To: My Name <myname@gmail.com>
Message-ID: <29985819.01331206751990.JavaMail.javamailuser@localhost>
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: <e4ae3388-312d-498e-b958-12e814507934@rsvp-rocket.appspot.com>

/9j/4AAQSkZJRgABAQEBLAEsAAD/7QBSUGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAABkcAVoAAxsl

Есть идеи?Электронная почта на GAE быстро попадает в «слишком сложную» корзину, когда я смотрю на Amazon SES и Postmark.

Ответы [ 3 ]

1 голос
/ 08 марта 2012

Во-первых, рассмотрите возможность замены Session.getDefaultInstance () на Session.getInstance ().Я не знаю, имеет ли это какое-либо отношение к вашей проблеме, но это позволит избежать потенциальных проблем в будущем.

Чтобы выяснить, почему сообщение не проходит так, как вы ожидаете, сохраните копию непосредственно передTransport.send () с помощью msg.writeTo (новый FileOutputStream ("msg.txt")), затем сравните содержимое файла с тем, что вы видите в своем почтовом клиенте.Если они не совпадают, наиболее вероятной причиной является то, что один из используемых вами почтовых серверов преобразует сообщение в то, как оно считает, что сообщение должно выглядеть.Exchange делает это часто.

0 голосов
/ 28 сентября 2012

К сожалению, GAE не предоставляет такую ​​функциональность.

Google предоставляет стандартный API javax.mail для приложений GAE. Вам не нужно включать какие-либо файлы SUN / Oracle * .jar в свой список зависимостей. На самом деле GAE предоставляет собственную реализацию javax.mail, которая лишь частично совместима с оригинальной реализацией SUN. Кроме того, GAE выполняет некоторые совершенно неожиданные операции под капотом. Например, если вы отправляете электронное письмо в чистом виде, получатель получит многокомпонентное сообщение с «альтернативой» MIME, которое будет содержать разорванный текстовый текст в формате HTML и ваше оригинальное письмо в формате HTML. Также вы попадете в кучу исключений при попытке использовать html со встроенными в cid встроенными изображениями. Также любое вложение «MimeMultiPart» будет приводить к исключению или неопределенному поведению. Если вы внимательно изучите его, из документации Google станет очевидным, что поддержка javax.mail очень ограничена. Они даже упоминают это: «В целях безопасности части сообщений и вложения должны быть одного из нескольких разрешенных типов». Вероятно, безопасность является одной из причин такой ограниченной поддержки, но не является окончательной.

0 голосов
/ 09 марта 2012

Возможно, вы захотите отметить следующую проблему AppEngine:

http://code.google.com/p/googleappengine/issues/detail?id=965

...