Skip to content

Instantly share code, notes, and snippets.

@mariussoutier
Created August 23, 2012 12:13
Show Gist options
  • Star 89 You must be signed in to star a gist
  • Fork 24 You must be signed in to fork a gist
  • Save mariussoutier/3436111 to your computer and use it in GitHub Desktop.
Save mariussoutier/3436111 to your computer and use it in GitHub Desktop.
Sending mails fluently in Scala
package object mail {
implicit def stringToSeq(single: String): Seq[String] = Seq(single)
implicit def liftToOption[T](t: T): Option[T] = Some(t)
sealed abstract class MailType
case object Plain extends MailType
case object Rich extends MailType
case object MultiPart extends MailType
case class Mail(
from: (String, String), // (email -> name)
to: Seq[String],
cc: Seq[String] = Seq.empty,
bcc: Seq[String] = Seq.empty,
subject: String,
message: String,
richMessage: Option[String] = None,
attachment: Option[(java.io.File)] = None
)
object send {
def a(mail: Mail) {
import org.apache.commons.mail._
val format =
if (mail.attachment.isDefined) MultiPart
else if (mail.richMessage.isDefined) Rich
else Plain
val commonsMail: Email = format match {
case Plain => new SimpleEmail().setMsg(mail.message)
case Rich => new HtmlEmail().setHtmlMsg(mail.richMessage.get).setTextMsg(mail.message)
case MultiPart => {
val attachment = new EmailAttachment()
attachment.setPath(mail.attachment.get.getAbsolutePath)
attachment.setDisposition(EmailAttachment.ATTACHMENT)
attachment.setName(mail.attachment.get.getName)
new MultiPartEmail().attach(attachment).setMsg(mail.message)
}
}
// TODO Set authentication from your configuration, sys properties or w/e
// Can't add these via fluent API because it produces exceptions
mail.to foreach (commonsMail.addTo(_))
mail.cc foreach (commonsMail.addCc(_))
mail.bcc foreach (commonsMail.addBcc(_))
commonsMail.
setFrom(mail.from._1, mail.from._2).
setSubject(mail.subject).
send()
}
}
}
package something
object Demo {
import mail._
send a new Mail (
from = ("john.smith@mycompany.com", "John Smith"),
to = "boss@mycompany.com",
cc = "hr@mycompany.com",
subject = "Import stuff",
message = "Dear Boss..."
)
send a new Mail (
from = "john.smith@mycompany.com" -> "John Smith",
to = Seq("dev@mycompany.com", "marketing@mycompany.com"),
subject = "Our New Strategy (tm)",
message = "Please find attach the latest strategy document.",
richMessage = "Here's the <blink>latest</blink> <strong>Strategy</strong>..."
)
send a new Mail (
from = "john.smith@mycompany.com" -> "John Smith",
to = "dev@mycompany.com" :: "marketing@mycompany.com" :: Nil,
subject = "Our 5-year plan",
message = "Here is the presentation with the stuff we're going to for the next five years.",
attachment = new java.io.File("/home/boss/important-presentation.ppt")
)
}
@Dinduks
Copy link

Dinduks commented Mar 4, 2014

Thank you for sharing this.

@MMMarcy
Copy link

MMMarcy commented Dec 22, 2014

Thanks man, really appreciate

Copy link

ghost commented Mar 20, 2015

Thank you for sharing this

@hraban
Copy link

hraban commented Mar 31, 2015

Hi, thanks for sharing. What's the license on this code? Can it be used in commercial projects?

@thiloplanz
Copy link

Can you add a license header?

@schon
Copy link

schon commented Oct 26, 2015

Thank you for sharing this

@azickh
Copy link

azickh commented Jan 22, 2016

Hi, I'm posting html, but get html content like attachments. What is the problem?

val html = """<html>Thanks for Joining!
               |You’re going to love Gifty.uz
               |
               |To complete your registration for ***, please <a href="http://mydomain.com/somepath">confirm</a> your email.
               |
               |Need help? Have feedback? Feel free to contact us</html>""".stripMargin

send a new Mail(
  from = mynoreply@gmail.com -> "noreplay",
  to = Seq("myrcpt@gmail.com"),
  subject = "Some subject",
  message = "Some plain content",
  richMessage = html
)

Thanks, Aziz

Copy link

ghost commented May 31, 2016

This is awesome

@futureage
Copy link

Thank you for sharing this

@prayagupa
Copy link

this is so fluent. thanks @mariussoutier

@tusharbabbar
Copy link

Beautifully written. Thanks. 👍

@kwidjaja1312
Copy link

Thanks a lot

@ammills01
Copy link

Thanks for sharing!

@gawalimangesh007
Copy link

Hi mariussoutier, I am getting below error

Exception in thread "main" org.apache.commons.mail.EmailException: Cannot find valid hostname for mail session
at org.apache.commons.mail.Email.getMailSession(Email.java:639)
at org.apache.commons.mail.Email.buildMimeMessage(Email.java:1278)
at org.apache.commons.mail.Email.send(Email.java:1447)
at Mail.package$send$.a(mail.scala:59)
at Seal_Phy$.main(Seal_Phy.scala:173)
at Seal_Phy.main(Seal_Phy.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:738)
at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:187)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:212)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:126)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)

@dsjayakar
Copy link

You need to set email server hostname by commonsMail.setHostName("your email server host")

@larsjaas
Copy link

larsjaas commented Mar 3, 2018

Tiny nit: The example should be attachment = Some(new java.io.File(...))

@amuradyan
Copy link

Thanks a lot man

@RezaBidar
Copy link

sample for gmail and multi file support

package object Mail {

  implicit def stringToSeq(single: String): Seq[String] = Seq(single)
  implicit def liftToOption[T](t: T): Option[T] = Some(t)

  sealed abstract class MailType
  case object Plain extends MailType
  case object Rich extends MailType
  case object MultiPart extends MailType

  case class Mail(
                   from: (String, String), // (email -> name)
                   to: Seq[String],
                   cc: Seq[String] = Seq.empty,
                   bcc: Seq[String] = Seq.empty,
                   subject: String,
                   message: String,
                   richMessage: Option[String] = None,
                   attachments: Seq[(java.io.File)] = Seq.empty
                 )

  object send {
    def a(mail: Mail) {
      import org.apache.commons.mail._

      val format =
        if (mail.attachments.nonEmpty) MultiPart
        else if (mail.richMessage.isDefined) Rich
        else Plain

      val commonsMail: Email = format match {
        case Plain => new SimpleEmail().setMsg(mail.message)
        case Rich => new HtmlEmail().setHtmlMsg(mail.richMessage.get).setTextMsg(mail.message)
        case MultiPart => {
          val multipartEmail = new MultiPartEmail()
          mail.attachments.foreach { file =>
            val attachment = new EmailAttachment()
            attachment.setPath(file.getAbsolutePath)
            attachment.setDisposition(EmailAttachment.ATTACHMENT)
            attachment.setName(file.getName)
            multipartEmail.attach(attachment)
          }
          multipartEmail.setMsg(mail.message)
        }
      }

      // TODO Set authentication from your configuration, sys properties or w/e

      // Can't add these via fluent API because it produces exceptions
      mail.to foreach (commonsMail.addTo(_))
      mail.cc foreach (commonsMail.addCc(_))
      mail.bcc foreach (commonsMail.addBcc(_))

      // gmail config
      commonsMail.setHostName("smtp.googlemail.com")
      commonsMail.setAuthentication("email","pass")
      commonsMail.setSSLOnConnect(true)
      commonsMail.setSmtpPort(465)

      commonsMail.
        setFrom(mail.from._1, mail.from._2).
        setSubject(mail.subject).
        send()
    }
  }
}

@venkatnbcu
Copy link

venkatnbcu commented Apr 20, 2019

Hi All,

Thanks, advance. Is there any possible ways to send Spark dataframe via mail, in normal or HTML using this Code?

@yuvaraj-hubino
Copy link

Hi All,
I am getting the below, can anyone clarify the reason

Error during processing of request: 'Sending the email to the following server failed : smtp.gmail.com:465'. Completing with 500 Internal Server Error response. To change default exception handling behavior, provide a custom ExceptionHandler.
org.apache.commons.mail.EmailException: Sending the email to the following server failed : smtp.gmail.com:465

Configuration

commonsMail.setHostName("smtp.gmail.com")
commonsMail.setAuthentication("test@gmail.com","password")
commonsMail.setSSLOnConnect(true)
commonsMail.setSmtpPort(465)

@yuvaraj-hubino
Copy link

sample for gmail and multi file support

package object Mail {

  implicit def stringToSeq(single: String): Seq[String] = Seq(single)
  implicit def liftToOption[T](t: T): Option[T] = Some(t)

  sealed abstract class MailType
  case object Plain extends MailType
  case object Rich extends MailType
  case object MultiPart extends MailType

  case class Mail(
                   from: (String, String), // (email -> name)
                   to: Seq[String],
                   cc: Seq[String] = Seq.empty,
                   bcc: Seq[String] = Seq.empty,
                   subject: String,
                   message: String,
                   richMessage: Option[String] = None,
                   attachments: Seq[(java.io.File)] = Seq.empty
                 )

  object send {
    def a(mail: Mail) {
      import org.apache.commons.mail._

      val format =
        if (mail.attachments.nonEmpty) MultiPart
        else if (mail.richMessage.isDefined) Rich
        else Plain

      val commonsMail: Email = format match {
        case Plain => new SimpleEmail().setMsg(mail.message)
        case Rich => new HtmlEmail().setHtmlMsg(mail.richMessage.get).setTextMsg(mail.message)
        case MultiPart => {
          val multipartEmail = new MultiPartEmail()
          mail.attachments.foreach { file =>
            val attachment = new EmailAttachment()
            attachment.setPath(file.getAbsolutePath)
            attachment.setDisposition(EmailAttachment.ATTACHMENT)
            attachment.setName(file.getName)
            multipartEmail.attach(attachment)
          }
          multipartEmail.setMsg(mail.message)
        }
      }

      // TODO Set authentication from your configuration, sys properties or w/e

      // Can't add these via fluent API because it produces exceptions
      mail.to foreach (commonsMail.addTo(_))
      mail.cc foreach (commonsMail.addCc(_))
      mail.bcc foreach (commonsMail.addBcc(_))

      // gmail config
      commonsMail.setHostName("smtp.googlemail.com")
      commonsMail.setAuthentication("email","pass")
      commonsMail.setSSLOnConnect(true)
      commonsMail.setSmtpPort(465)

      commonsMail.
        setFrom(mail.from._1, mail.from._2).
        setSubject(mail.subject).
        send()
    }
  }
}

I got the below error while using the given code snippet.

https://gist.github.com/mariussoutier/3436111#gistcomment-3242151

As well found the solution for the issue using the below link

https://stackoverflow.com/a/59760500/7199780

So is it safe?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment