io.taig.taigless.mailbox.JavaxMailbox.scala Maven / Gradle / Ivy
The newest version!
package io.taig.taigless.mailbox
import cats.ApplicativeThrow
import cats.effect.kernel.{Resource, Sync}
import cats.implicits._
import java.nio.charset.StandardCharsets
import java.util.Properties
import javax.mail._
import javax.mail.internet.{InternetAddress, MimeMessage}
final class JavaxMailbox[F[_]](session: Session, sender: Address)(implicit F: Sync[F]) extends Mailbox[F] {
override def send(recipient: Mailbox.Address, message: Mailbox.Message): F[Unit] =
JavaxMailbox.toAddress[F](recipient).flatMap { recipient =>
val email = new MimeMessage(session)
email.setFrom(sender)
email.setRecipients(Message.RecipientType.TO, Array(recipient))
email.setSubject(message.subject, JavaxMailbox.Utf8)
email.setText(message.content, JavaxMailbox.Utf8)
F.blocking(Transport.send(email))
}
}
object JavaxMailbox {
private val Utf8: String = StandardCharsets.UTF_8.displayName
private def toAddress[F[_]](address: Mailbox.Address)(implicit F: ApplicativeThrow[F]): F[Address] = address match {
case Mailbox.Address(email, None) => F.catchNonFatal(new InternetAddress(email))
case Mailbox.Address(email, Some(name)) => F.catchNonFatal(new InternetAddress(email, name, Utf8))
}
def apply[F[_]: Sync](session: Session, sender: Address): Mailbox[F] = new JavaxMailbox[F](session, sender)
def fromProperties[F[_]: Sync](
properties: Properties,
authenticator: Option[Authenticator],
sender: Mailbox.Address
): F[Mailbox[F]] = {
val session = Session.getInstance(properties, authenticator.orNull)
check(session) *> toAddress[F](sender).map(JavaxMailbox[F](session, _))
}
def fromCredentials[F[_]: Sync](
host: String,
port: Int,
username: String,
password: String,
sender: Mailbox.Address
): F[Mailbox[F]] = {
val properties = new Properties
properties.put("mail.smtp.auth", "true")
properties.put("mail.smtp.starttls.enable", "true")
properties.put("mail.smtp.host", host)
properties.put("mail.smtp.port", port)
val authenticator = new Authenticator {
override def getPasswordAuthentication: PasswordAuthentication =
new PasswordAuthentication(username, password)
}
fromProperties(properties, authenticator.some, sender)
}
private def check[F[_]](session: Session)(implicit F: Sync[F]): F[Unit] =
Resource
.fromAutoCloseable(F.blocking {
val transport = session.getTransport("smtp")
transport.connect()
transport
})
.use_
}