Skip to content

Commit

Permalink
Implement email attachments
Browse files Browse the repository at this point in the history
  • Loading branch information
ttoino committed Feb 25, 2023
1 parent 26a581a commit c1c29c2
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package pt.up.fe.ni.website.backend.email

import jakarta.activation.DataSource
import jakarta.activation.FileDataSource
import jakarta.activation.URLDataSource
import jakarta.validation.Valid
import jakarta.validation.constraints.Email
import java.io.File
import java.net.URL
import org.springframework.mail.javamail.MimeMessageHelper
import pt.up.fe.ni.website.backend.config.email.EmailConfigProperties
import pt.up.fe.ni.website.backend.model.Account
Expand All @@ -12,6 +17,7 @@ abstract class BaseEmailBuilder : EmailBuilder {
private var to: MutableSet<String> = mutableSetOf()
private var cc: MutableSet<String> = mutableSetOf()
private var bcc: MutableSet<String> = mutableSetOf()
private var attachments: MutableList<Attachment> = mutableListOf()

fun from(@Email email: String, personal: String = email) = apply {
from = email
Expand Down Expand Up @@ -42,11 +48,30 @@ abstract class BaseEmailBuilder : EmailBuilder {
bcc.addAll(users.map { it.email })
}

fun attach(name: String, content: DataSource) = apply {
attachments.add(Attachment(name, content))
}

fun attach(name: String, content: File) = apply {
attachments.add(Attachment(name, FileDataSource(content)))
}

fun attach(name: String, path: String) = apply {
attachments.add(Attachment(name, URLDataSource(URL(path))))
}

override fun build(helper: MimeMessageHelper, emailConfigProperties: EmailConfigProperties) {
helper.setFrom(from ?: emailConfigProperties.from, fromPersonal ?: emailConfigProperties.fromPersonal)

to.forEach(helper::setTo)
cc.forEach(helper::setCc)
bcc.forEach(helper::setBcc)

attachments.forEach { helper.addAttachment(it.name, it.content) }
}

protected data class Attachment(
val name: String,
val content: DataSource
)
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package pt.up.fe.ni.website.backend.email

import com.samskivert.mustache.Mustache
import java.io.ByteArrayInputStream
import org.springframework.boot.autoconfigure.mustache.MustacheResourceTemplateLoader
import org.springframework.mail.javamail.MimeMessageHelper
import pt.up.fe.ni.website.backend.config.email.EmailConfigProperties

abstract class TemplateEmailBuilder<T> : BaseEmailBuilder() {
private var data: T? = null

open val htmlTemplatePath: String? = null
open val textTemplatePath: String? = null

protected open fun subject(data: T?): String = ""
protected open fun subject(data: T?): String? = null
protected open fun htmlTemplatePath(data: T?): String? = null
protected open fun textTemplatePath(data: T?): String? = null
protected open fun attachments(data: T?): List<TemplateAttachment> = emptyList()

fun data(data: T) = apply {
this.data = data
Expand All @@ -20,19 +21,24 @@ abstract class TemplateEmailBuilder<T> : BaseEmailBuilder() {
override fun build(helper: MimeMessageHelper, emailConfigProperties: EmailConfigProperties) {
super.build(helper, emailConfigProperties)

helper.setSubject(subject(data))
val subject = subject(data)
if (subject != null) {
helper.setSubject(subject)
}

val mustache = Mustache.compiler().withLoader(
MustacheResourceTemplateLoader(emailConfigProperties.templatePrefix, emailConfigProperties.templateSuffix)
)
var text: String? = null
var html: String? = null

var text: String? = null
val textTemplatePath = textTemplatePath(data)
if (textTemplatePath != null) {
val textTemplate = mustache.loadTemplate(textTemplatePath)
text = textTemplate.execute(data)
}

var html: String? = null
val htmlTemplatePath = htmlTemplatePath(data)
if (htmlTemplatePath != null) {
val htmlTemplate = mustache.loadTemplate(htmlTemplatePath)
html = htmlTemplate.execute(data)
Expand All @@ -45,5 +51,16 @@ abstract class TemplateEmailBuilder<T> : BaseEmailBuilder() {
} else if (html != null) {
helper.setText(html, true)
}

for (attachment in attachments(data)) {
val template = mustache.loadTemplate(attachment.path(data))
val content = template.execute(data)
helper.addAttachment(attachment.name(data)) { ByteArrayInputStream(content.encodeToByteArray()) }
}
}

protected abstract inner class TemplateAttachment {
abstract fun path(data: T?): String
abstract fun name(data: T?): String
}
}

0 comments on commit c1c29c2

Please sign in to comment.