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

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_
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy