From 4898577ea172649d1d183108415324ef14e4f133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=98=8B=20Mansur?= Date: Tue, 17 Mar 2026 19:08:18 +0300 Subject: [PATCH 1/2] WD-694 update commons-email to commons-email2, add inline attachments and reply-to support --- README.md | 7 ++- email-service/build.gradle.kts | 3 +- .../com/icerockdev/service/email/Mail.kt | 39 ++++++++++--- email-service/src/test/kotlin/EmailTest.kt | 54 ++++++++++++++++++ email-service/src/test/resources/kotlin.png | Bin 0 -> 29145 bytes gradle.properties | 2 +- 6 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 email-service/src/test/resources/kotlin.png diff --git a/README.md b/README.md index f2e9d63..da5441b 100644 --- a/README.md +++ b/README.md @@ -37,13 +37,18 @@ implementation("com.icerockdev.service:email-service:0.5.2") fromName = "From Person" subject = "TEST EMAIL" to = mutableMapOf("to@icerockdev.com" to "Test Person") - html = "

Test test test

" + html = "

Test test test

" attachments = listOf( Mail.Attachment( file = File("test.pdf"), name = "test.pdf" ) ) + inlineAttachments = listOf( + file = File("test.png"), + cidName = "testpng", + name = "test.png" + ) }.sendAsync() ```` diff --git a/email-service/build.gradle.kts b/email-service/build.gradle.kts index aee9a4e..e183559 100644 --- a/email-service/build.gradle.kts +++ b/email-service/build.gradle.kts @@ -33,7 +33,7 @@ dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:${properties["coroutines_version"]}") // https://mvnrepository.com/artifact/org.apache.commons/commons-email - implementation("org.apache.commons:commons-email:${properties["common_email_version"]}") + implementation("org.apache.commons:commons-email2-jakarta:${properties["common_email2_version"]}") // logging implementation("ch.qos.logback:logback-classic:${properties["logback_version"]}") @@ -144,4 +144,3 @@ jreleaser { } } } - diff --git a/email-service/src/main/kotlin/com/icerockdev/service/email/Mail.kt b/email-service/src/main/kotlin/com/icerockdev/service/email/Mail.kt index a5c35c0..abfd06c 100644 --- a/email-service/src/main/kotlin/com/icerockdev/service/email/Mail.kt +++ b/email-service/src/main/kotlin/com/icerockdev/service/email/Mail.kt @@ -4,21 +4,21 @@ package com.icerockdev.service.email +import jakarta.activation.DataSource +import jakarta.activation.FileDataSource +import jakarta.activation.URLDataSource +import jakarta.mail.util.ByteArrayDataSource import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.launch -import org.apache.commons.mail.DefaultAuthenticator -import org.apache.commons.mail.Email -import org.apache.commons.mail.EmailConstants.UTF_8 -import org.apache.commons.mail.HtmlEmail +import org.apache.commons.mail2.core.EmailConstants.UTF_8 +import org.apache.commons.mail2.jakarta.DefaultAuthenticator +import org.apache.commons.mail2.jakarta.Email +import org.apache.commons.mail2.jakarta.HtmlEmail import org.slf4j.Logger import org.slf4j.LoggerFactory import java.io.File import java.net.URL -import javax.activation.DataSource -import javax.activation.FileDataSource -import javax.activation.URLDataSource -import javax.mail.util.ByteArrayDataSource class Mail(private val coroutineScope: CoroutineScope?, private val config: SMTPConfig) { @@ -38,6 +38,9 @@ class Mail(private val coroutineScope: CoroutineScope?, private val config: SMTP var fromEmail: String = "" var charset = UTF_8 var attachments: List = emptyList() + var inlineAttachments: List = emptyList() + var replyToEmail: String? = null + var replyToName: String? = null private var isHtml: Boolean = false private fun prepareEmail(): Email { @@ -76,6 +79,14 @@ class Mail(private val coroutineScope: CoroutineScope?, private val config: SMTP email.attach(attachment.dataSource, attachment.name, attachment.description) } + inlineAttachments.forEach { inline -> + email.embed(inline.dataSource, inline.name, inline.cidName) + } + + if (!replyToEmail.isNullOrBlank()) { + email.addReplyTo(replyToEmail, replyToName) + } + return email } @@ -114,6 +125,18 @@ class Mail(private val coroutineScope: CoroutineScope?, private val config: SMTP ) } + class InlineAttachment( + val dataSource: DataSource, + val cidName: String, + val name: String, + ) { + constructor(file: File, cidName: String, name: String) : this(FileDataSource(file), cidName, name) + constructor(url: URL, cidName: String, name: String) : this(URLDataSource(url), cidName, name) + constructor(data: ByteArray, cidName: String, name: String, charset: String = UTF_8) : this( + ByteArrayDataSource(data, "application/octet-stream;charset=$charset"), cidName, name + ) + } + private companion object { val LOGGER: Logger = LoggerFactory.getLogger(Mail::class.java) } diff --git a/email-service/src/test/kotlin/EmailTest.kt b/email-service/src/test/kotlin/EmailTest.kt index 9924754..75d763f 100644 --- a/email-service/src/test/kotlin/EmailTest.kt +++ b/email-service/src/test/kotlin/EmailTest.kt @@ -3,6 +3,7 @@ */ import com.dumbster.smtp.SimpleSmtpServer +import com.icerockdev.service.email.Mail import com.icerockdev.service.email.MailerService import com.icerockdev.service.email.SMTPConfig import kotlinx.coroutines.CoroutineScope @@ -12,8 +13,10 @@ import kotlinx.coroutines.runBlocking import org.junit.After import org.junit.Before import org.junit.Test +import java.io.File import kotlin.test.assertContains import kotlin.test.assertEquals +import kotlin.test.assertNotNull import kotlin.test.assertTrue @@ -66,4 +69,55 @@ class EmailTest { assertEquals(expected = 1, email.getHeaderValues("To").size) assertTrue { email.getHeaderValues("To").contains("Test Person ") } } + + @Test + fun testSendWithInlineAttachments() = runBlocking { + val imageFile = File("src/test/resources/kotlin.png") + val cidName = "kotlin-name" + val name = "kotlinlogo" + + mailerService.compose().apply { + fromEmail = "from@icerockdev.com" + fromName = "From Person" + subject = "TEST EMAIL" + to = mutableMapOf("to@icerockdev.com" to "Test Person") + html = "

Test Inline

" + + inlineAttachments = listOf( + Mail.InlineAttachment(imageFile, cidName, name) + ) + }.sendAsync().join() + + val emails = server.receivedEmails + val email = emails[0] + + assertContains(email.body, "") + assertContains(email.body, "Content-ID: <$cidName>") + assertContains(email.body, "Content-Disposition: inline") + assertContains(email.body, "name=$name") + } + + @Test + fun testSendWithReplyTo() = runBlocking { + val replyToEmail = "replyto@icerockdev.com" + val replyToName = "Reply Person" + + mailerService.compose().apply { + fromEmail = "from@icerockdev.com" + fromName = "From Person" + subject = "TEST EMAIL" + to = mutableMapOf("to@icerockdev.com" to "Test Person") + html = "

Test test test

" + this.replyToEmail = replyToEmail + this.replyToName = replyToName + }.sendAsync().join() + + val emails = server.receivedEmails + assertEquals(1, emails.size) + val email = emails[0] + + val replyToHeader = email.getHeaderValue("Reply-To") + assertNotNull(replyToHeader) + assertEquals("$replyToName <$replyToEmail>", replyToHeader) + } } diff --git a/email-service/src/test/resources/kotlin.png b/email-service/src/test/resources/kotlin.png new file mode 100644 index 0000000000000000000000000000000000000000..ac4a2dae91144b381f80621366c94ab2f0f34729 GIT binary patch literal 29145 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 literal 0 HcmV?d00001 diff --git a/gradle.properties b/gradle.properties index 85efe6e..d51793a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,4 +6,4 @@ logback_version=1.4.5 kotlin.code.style=official kotlin_version=1.7.21 coroutines_version=1.6.4 -common_email_version=1.5 +common_email2_version=2.0.0-M1 From b0cb6b21d16a19edf26f4201e0a09d10e86cd6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=98=8B=20Mansur?= Date: Wed, 18 Mar 2026 13:44:36 +0300 Subject: [PATCH 2/2] WD-694 update package version --- README.md | 2 +- email-service/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index da5441b..597cd86 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ repositories { } // Append dependency -implementation("com.icerockdev.service:email-service:0.5.2") +implementation("com.icerockdev.service:email-service:1.0.0") ```` ## Library usage diff --git a/email-service/build.gradle.kts b/email-service/build.gradle.kts index e183559..d3003dd 100644 --- a/email-service/build.gradle.kts +++ b/email-service/build.gradle.kts @@ -19,7 +19,7 @@ apply(plugin = "java") apply(plugin = "kotlin") group = "com.icerockdev.service" -version = "0.5.2" +version = "1.0.0" val sourcesJar by tasks.registering(Jar::class) { archiveClassifier.set("sources")