diff --git a/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageHelper.java b/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageHelper.java index 9b5f9a73f..56b582fe7 100644 --- a/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageHelper.java +++ b/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageHelper.java @@ -7,6 +7,7 @@ import org.simplejavamail.email.AttachmentResource; import org.simplejavamail.email.Email; import org.simplejavamail.email.Recipient; +import org.simplejavamail.internal.util.MiscUtil; import javax.activation.DataHandler; import javax.activation.DataSource; @@ -64,7 +65,16 @@ public static MimeMessage produceMimeMessage(final Email email, final Session se } // create new wrapper for each mail being sent (enable sending multiple emails with one mailer) final MimeEmailMessageWrapper messageRoot = new MimeEmailMessageWrapper(); - final MimeMessage message = new MimeMessage(session); + final MimeMessage message = new MimeMessage(session) { + @Override + protected void updateMessageID() throws MessagingException { + if (valueNullOrEmpty(email.getId())) { + super.updateMessageID(); + } else { + setHeader("Message-ID", email.getId()); + } + } + }; // set basic email properties message.setSubject(email.getSubject(), CHARACTER_ENCODING); message.setFrom(new InternetAddress(email.getFromRecipient().getAddress(), email.getFromRecipient().getName(), CHARACTER_ENCODING)); diff --git a/src/main/java/org/simplejavamail/email/Email.java b/src/main/java/org/simplejavamail/email/Email.java index bfba57415..d3f3df347 100644 --- a/src/main/java/org/simplejavamail/email/Email.java +++ b/src/main/java/org/simplejavamail/email/Email.java @@ -39,6 +39,16 @@ */ @SuppressWarnings("SameParameterValue") public class Email { + + /** + * Optional ID, which will be used when sending using the underlying Java Mail framework. Will be generated otherwise. + *

+ * Note that id can only ever be filled by end-users for sending an email. This library will never fill this field when converting a MimeMessage. + *

+ * The id-format should be conform rfc5322#section-3.6.4 + */ + private String id; + /** * The sender of the email. Can be used in conjunction with {@link #replyToRecipient}. */ @@ -173,6 +183,13 @@ public void signWithDomainKey(@Nonnull final InputStream dkimPrivateKeyInputStre this.selector = checkNonEmptyArgument(selector, "selector"); } + /** + * Bean setter for {@link #id}. + */ + public void setId(@Nullable final String id) { + this.id = id; + } + /** * Sets the sender address. * @@ -355,6 +372,13 @@ public void addAttachment(@Nullable final String name, @Nonnull final DataSource attachments.add(new AttachmentResource(MiscUtil.encodeText(name), filedata)); } + /** + * Bean getter for {@link #id}. + */ + public String getId() { + return id; + } + /** * Bean getter for {@link #fromRecipient}. */ @@ -452,6 +476,7 @@ public boolean equals(final Object o) { @Override public String toString() { return "Email{" + + "\n\tid=" + id + "\n\tfromRecipient=" + fromRecipient + ",\n\treplyToRecipient=" + replyToRecipient + ",\n\ttext='" + text + '\'' + @@ -476,6 +501,7 @@ public String toString() { attachments = builder.getAttachments(); headers = builder.getHeaders(); + id = builder.getId(); fromRecipient = builder.getFromRecipient(); replyToRecipient = builder.getReplyToRecipient(); text = builder.getText(); diff --git a/src/main/java/org/simplejavamail/email/EmailBuilder.java b/src/main/java/org/simplejavamail/email/EmailBuilder.java index f2da34f49..887065e59 100644 --- a/src/main/java/org/simplejavamail/email/EmailBuilder.java +++ b/src/main/java/org/simplejavamail/email/EmailBuilder.java @@ -40,6 +40,16 @@ */ @SuppressWarnings("UnusedReturnValue") public class EmailBuilder { + + /** + * Optional ID, which will be used when sending using the underlying Java Mail framework. Will be generated otherwise. + *

+ * Note that id can only ever be filled by end-users for sending an email. This library will never fill this field when converting a MimeMessage. + *

+ * The id-format should be conform rfc5322#section-3.6.4 + */ + private String id; + private Recipient fromRecipient; /** * The reply-to-address, optional. Can be used in conjunction with {@link #fromRecipient}. @@ -139,13 +149,18 @@ public EmailBuilder() { } } - /** - * - */ public Email build() { return new Email(this); } + /** + * Sets the optional id to be used when sending using the underlying Java Mail framework. Will be generated otherwise. + */ + public EmailBuilder id(@Nullable final String id) { + this.id = id; + return this; + } + /** * Sets the sender address {@link #fromRecipient}. * @@ -523,6 +538,10 @@ public EmailBuilder signWithDomainKey(@Nonnull final InputStream dkimPrivateKeyI SETTERS / GETTERS */ + public String getId() { + return id; + } + public Recipient getFromRecipient() { return fromRecipient; } diff --git a/src/test/java/org/simplejavamail/mailer/MailerLiveTest.java b/src/test/java/org/simplejavamail/mailer/MailerLiveTest.java index 1fd6f3e74..3d9fc46c2 100644 --- a/src/test/java/org/simplejavamail/mailer/MailerLiveTest.java +++ b/src/test/java/org/simplejavamail/mailer/MailerLiveTest.java @@ -1,6 +1,7 @@ package org.simplejavamail.mailer; import org.junit.Before; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.simplejavamail.email.AttachmentResource; @@ -14,12 +15,14 @@ import testutil.testrules.TestSmtpServer; import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; import java.io.IOException; import java.util.Properties; import static javax.mail.Message.RecipientType.TO; import static org.assertj.core.api.Assertions.assertThat; import static org.simplejavamail.converter.EmailConverter.mimeMessageToEmail; +import static org.simplejavamail.internal.util.MiscUtil.valueNullOrEmpty; import static testutil.EmailHelper.normalizeText; import static testutil.EmailHelper.readOutlookMessage; @@ -45,6 +48,13 @@ public void createMailSession_StandardDummyMail() assertSendingEmail(EmailHelper.createDummyEmail()); } + @Test + @Ignore("Unfortunately, Wiser doesn't seem to get the ID back, but I confirmed with gmail that the (correct) ID should be there") + public void createMailSession_StandardDummyMailWithId() + throws IOException, MessagingException { + assertSendingEmail(EmailHelper.createDummyEmail("<123@456>")); + } + @Test public void createMailSession_OutlookMessageTest() throws IOException, MessagingException { @@ -78,7 +88,11 @@ public void createMailSession_OutlookMessageTest() private Email assertSendingEmail(final Email originalEmail) throws MessagingException { mailer.sendMail(originalEmail); - Email receivedEmail = mimeMessageToEmail(smtpServerRule.getOnlyMessage()); + MimeMessage receivedMimeMessage = smtpServerRule.getOnlyMessage(); + if (!valueNullOrEmpty(originalEmail.getId())) { + assertThat(receivedMimeMessage.getMessageID()).isEqualTo(originalEmail.getId()); + } + Email receivedEmail = mimeMessageToEmail(receivedMimeMessage); assertThat(receivedEmail).isEqualTo(originalEmail); return receivedEmail; } diff --git a/src/test/java/testutil/EmailHelper.java b/src/test/java/testutil/EmailHelper.java index cc5b66aa2..1afa81978 100644 --- a/src/test/java/testutil/EmailHelper.java +++ b/src/test/java/testutil/EmailHelper.java @@ -2,6 +2,7 @@ import org.simplejavamail.email.Email; +import javax.annotation.Nullable; import javax.mail.util.ByteArrayDataSource; import java.io.IOException; import java.io.InputStream; @@ -12,10 +13,15 @@ import static org.simplejavamail.converter.EmailConverter.outlookMsgToEmail; public class EmailHelper { - - public static Email createDummyEmail() + + public static Email createDummyEmail() throws IOException { + return createDummyEmail(null); + } + + public static Email createDummyEmail(@Nullable String id) throws IOException { final Email emailNormal = new Email(); + emailNormal.setId(id); emailNormal.setFromAddress("lollypop", "lol.pop@somemail.com"); // normally not needed, but for the test it is because the MimeMessage will // have it added automatically as well, so the parsed Email will also have it then @@ -25,7 +31,7 @@ public static Email createDummyEmail() emailNormal.setText("We should meet up!"); emailNormal.setTextHTML("We should meet up!"); emailNormal.setSubject("hey"); - + // add two text files in different ways and a black thumbs up embedded image -> ByteArrayDataSource namedAttachment = new ByteArrayDataSource("Black Tie Optional", "text/plain"); namedAttachment.setName("dresscode.txt"); // normally not needed, but otherwise the equals will fail @@ -35,12 +41,12 @@ public static Email createDummyEmail() emailNormal.addEmbeddedImage("thumbsup", parseBase64Binary(base64String), "image/png"); return emailNormal; } - + public static Email readOutlookMessage(final String filePath) { InputStream resourceAsStream = EmailHelper.class.getClassLoader().getResourceAsStream(filePath); return outlookMsgToEmail(resourceAsStream); } - + public static String normalizeText(String text) { return text.replaceAll("\\r\\n", "\n").replaceAll("\\r", "\n"); }