javakotlinresttemplatemailgunmime-message

Create mime email message from scratch (for Mailgun API)


How can I compose mime email message in Java (or Kotlin)? I don't understand how to use javax.mail.internet.MimeMessage because I don't have smtp, but https endpoint (using Mailgun service).

Below code sends multipart/form-data request, but in target mailbox there is just plain text received (html not rendered), without "Subject" and proper "From".

So it appears that I have to embed this in mimeMessage, that I attach as form-data. But how?

val fileMap: MultiValueMap<String, String> = LinkedMultiValueMap()
val contentDisposition = ContentDisposition
        .builder("form-data")
        .name("message")
        .filename("message.mime")
        .build()
fileMap.add(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString())

val mimeMessage = "<html>some <b>nice</b> html</html>".toByteArray() // <<-- How to build this properly?
val fileEntity = HttpEntity<ByteArray>(mimeMessage, fileMap)

val headers = HttpHeaders()
headers.contentType = MediaType.MULTIPART_FORM_DATA

val parts: MultiValueMap<String, Any> = LinkedMultiValueMap()
parts.add("file", fileEntity)
parts.add("from", mailProperties.fromAddress)
parts.add("to", email.to)
parts.add("subject", email.subject)

val requestEntity: HttpEntity<MultiValueMap<String, Any>> = HttpEntity(parts, headers)
val res = restTemplate.postForEntity("https://api.eu.mailgun.net/v3/mydomain.com/messages.mime", requestEntity, String::class.java)

Solution

  • Well, I found the way to compose correct mime message and then send it as multipart/form-data. Looks not too clean, but at least it works:

    In the original code, instead of:

    val mimeMessage = "<html>some <b>nice</b> html</html>".toByteArray()
    

    I did the following:

    val impl = JavaMailSenderImpl()
    val msg = impl.createMimeMessage()
    val helper = MimeMessageHelper(msg, true)
    helper.setFrom(mailProperties.fromAddress)
    helper.addTo(email.to)
    helper.setSubject(email.subject)
    helper.setText("<html>some <b>nice</b> html</html>", true)
    val out = ByteArrayOutputStream()
    helper.mimeMessage.writeTo(out)
    val mimeMessage = out.toByteArray()