All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ag.orbia.common.infrastructure.email.AmazonEmailSender.kt Maven / Gradle / Ivy

package ag.orbia.common.infrastructure.email

import com.amazonaws.services.simpleemail.AmazonSimpleEmailService
import com.amazonaws.services.simpleemail.model.RawMessage
import com.amazonaws.services.simpleemail.model.SendRawEmailRequest
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import java.io.ByteArrayOutputStream
import java.nio.ByteBuffer
import java.util.*
import javax.activation.DataHandler
import javax.mail.Message
import javax.mail.Session
import javax.mail.internet.InternetAddress
import javax.mail.internet.MimeBodyPart
import javax.mail.internet.MimeMessage
import javax.mail.internet.MimeMultipart
import javax.mail.util.ByteArrayDataSource


@Service
class AmazonEmailSender @Autowired constructor(
        private val sesClient: AmazonSimpleEmailService,
        private val emailBodyResolver: EmailBodyResolver
) : EmailSender() {

    @Value("\${aws.ses.configuration-set:#{null}}")
    private var configurationSet: String? = null

    override fun sendEmail(email: Email) {
        try {
            send(email)
        } catch (exception: Exception) {
            throw EmailNotSentException(exception)
        }
    }

    private fun send(email: Email) {
        if (email.configurationSetName == null) {
            email.configurationSetName = configurationSet
        }
        val emailRequest = createEmailRequest(email)
        send(emailRequest, email)
    }

    private fun createEmailRequest(email: Email): MimeMessage {
        val replyToAddresses = email.replyTo.map { addr -> InternetAddress(addr) }.toTypedArray()
        val message = MimeMessage(Session.getDefaultInstance(Properties()))
        message.setSubject(email.subject, "UTF-8")
        message.setFrom(InternetAddress(email.from))
        message.replyTo = replyToAddresses

        setRecipients(message, email)
        setBody(message, email)

        return message
    }

    private fun setRecipients(message: MimeMessage, email: Email) {
        val toAddresses = getInternetAddresses(email.to)
        val ccAddresses = getInternetAddresses(email.cc)
        val bccAddresses = getInternetAddresses(email.bcc)

        message.setRecipients(Message.RecipientType.TO, toAddresses)
        message.setRecipients(Message.RecipientType.CC, ccAddresses)
        message.setRecipients(Message.RecipientType.BCC, bccAddresses)
    }

    private fun getInternetAddresses(emailAddresses: Collection): Array {
        return emailAddresses.map { addr -> InternetAddress(addr) }.toTypedArray()
    }

    private fun setBody(message: MimeMessage, email: Email) {
        val textBodyContainer = setBodyText(email)
        val emailContainer = setAttachments(textBodyContainer, email)
        message.setContent(emailContainer)
    }

    private fun setBodyText(email: Email): MimeBodyPart {
        val body = MimeMultipart("alternative")
        val wrap = MimeBodyPart()

        val bodyText = MimeBodyPart()
        val bodyHtml = emailBodyResolver.resolve(email.body)
        bodyText.setContent(bodyHtml, "text/html; charset=UTF-8")

        body.addBodyPart(bodyText)
        wrap.setContent(body)
        return wrap
    }

    private fun setAttachments(emailTextBody: MimeBodyPart, email: Email): MimeMultipart {
        val emailContainer = MimeMultipart("mixed")
        emailContainer.addBodyPart(emailTextBody)

        email.attachments.forEach { attachment -> addAttachmentToContainer(attachment, emailContainer) }

        return emailContainer
    }

    private fun addAttachmentToContainer(emailAttachment: EmailAttachment, container: MimeMultipart) {
        val attachment = MimeBodyPart()
        val dataSource = ByteArrayDataSource(emailAttachment.fileContent, emailAttachment.mime)
        attachment.dataHandler = DataHandler(dataSource)
        attachment.fileName = emailAttachment.name

        container.addBodyPart(attachment)
    }

    private fun send(message: MimeMessage, email: Email) {
        val outputStream = ByteArrayOutputStream()
        message.writeTo(outputStream)

        val rawMessage = RawMessage(ByteBuffer.wrap(outputStream.toByteArray()))
        val rawRequest = SendRawEmailRequest(rawMessage)
        rawRequest.setDestinations(email.to)
        rawRequest.configurationSetName = email.configurationSetName
        sesClient.sendRawEmail(rawRequest)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy