How to send a multipart/alternative email?

Hello Cuba developers,

The application I am working on for a client is used to send regular newsletters to subscribers. However, the client is reporting that these sometimes arrive in the spam folder of subscribers.

We are still looking into the exact reason as to why that is. However, one possibility is that our email does not offer a plaintext body as an alternative to HTML. Through a service such as mail-tester.com this comes forward as the most likely culprit.

-1.105 MIME_HTML_ONLY Message only has text/html MIME parts

The client has asked me to ensure emails are provided with both a HTML and plaintext body. Sadly the ‘EmailService’ class provided for the Cuba platform does not appear to offer this functionality. Though I do see some protected functions that have something to do with MIME multipart

Using the function setBodyContentType() you are either forced to use “text/plain; charset=UTF-8” or “text/html; charset=UTF-8”.

I have tried to be obstinant and filled in “multipart/alternative” regardless, but to no avail. The email remains queued. Below is a stacktrace. Note that I have tried a few variations of multipart (with boundary, charset etc).

^[[33mweb_1_82bdfe5abd18 |^[[0m 14:49:24.438 WARN  com.haulmont.cuba.core.app.Emailer - Unable to send email to 'test-2m50woe0d@srv1.mail-tester.com'
^[[33mweb_1_82bdfe5abd18 |^[[0m javax.mail.MessagingException: MIME part of type "multipart/mixed; boundary=test_boundary" contains object of type java.lang.String instead of MimeMultipart
^[[33mweb_1_82bdfe5abd18 |^[[0m         at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1475)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1125)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at javax.mail.internet.MimeMultipart.updateHeaders(MimeMultipart.java:515)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1471)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1125)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at javax.mail.internet.MimeMultipart.updateHeaders(MimeMultipart.java:515)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1471)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at javax.mail.internet.MimeMessage.updateHeaders(MimeMessage.java:2190)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at javax.mail.internet.MimeMessage.saveChanges(MimeMessage.java:2151)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at com.haulmont.cuba.core.app.EmailSender.createMimeMessage(EmailSender.java:104)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at com.haulmont.cuba.core.app.EmailSender.sendEmail(EmailSender.java:65)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at com.haulmont.cuba.core.app.Emailer.sendSendingMessage(Emailer.java:181)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at com.haulmont.cuba.core.app.Emailer$EmailSendTask.run(Emailer.java:738)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
^[[33mweb_1_82bdfe5abd18 |^[[0m         at java.lang.Thread.run(Thread.java:748)

Has anybody tried anything like this before? Multipart body seems pretty standard for MIME. Or perhaps I am going about this problem in the wrong way?

Hi,
CUBA did not pursure the goal to implement 100% of MIME functionality with EmailService.

You can create your own service, then copy parts of the com.haulmont.cuba.core.app.EmailSender to the implementation and modify the code so that it creates multipart body.

If you use the same injected JavaMailSender mailSender field, you will be able to set emailing properties with through standard CUBA configuration properties.

1 Like

Thank you Alex for the suggestion

I created my own EmailSender service and overwrote the bean in spring.xml. Testing the emails being sent shows the problem has been overcome. However I do request that this feature also be included in a future release of the Cuba platform, maybe with Email Templates?

Below I have posted a few select pieces of code for those interested.

public class MultipartEmailSender extends EmailSender implements EmailSenderAPI { 

....

@Override
protected MimeMessage createMimeMessage(SendingMessage sendingMessage) throws MessagingException {

    String keyword = "SPLIT_EMAIL_BODY";
    String[] email_bodies = sendingMessage.getContentText().split(keyword);

    MimeMultipart msgContent = new MimeMultipart( "alternative" );

    MimeBodyPart plainPart = new MimeBodyPart();
    plainPart.setContent(email_bodies[0], "text/plain" );
    plainPart.setHeader(MIME_VERSION, "1.0" );
    plainPart.setHeader("Content-Type", "text/plain" ); 
	
    msgContent.addBodyPart( plainPart );

    MimeBodyPart htmlPart = new MimeBodyPart();
    htmlPart.setContent(email_bodies[1], "text/plain" );
    htmlPart.setHeader( MIME_VERSION, "1.0" );
    htmlPart.setHeader( "Content-Type", "text/html" ); 

    msgContent.addBodyPart( htmlPart );

    MimeMessage msg = mailSender.createMimeMessage();
    msg.setContent( msgContent );
    msg.setFrom( new InternetAddress( sendingMessage.getFrom() ) );
    msg.addRecipient( Message.RecipientType.TO, new InternetAddress( sendingMessage.getAddress() ) );
    msg.setSubject( sendingMessage.getCaption() );

    msg.saveChanges();
    return msg;
}

and in spring.xml

<bean id="cuba_EmailSender" class="com.company_name.project_name.email.MultipartEmailSender"/>

Feel free to offer further suggestions.

Thanks for suggestion and sample code that worked for you.

I have created a github feature request: Ability to send emails with multipart body · Issue #2969 · cuba-platform/cuba · GitHub
I’m not sure though when it will be implemented.