Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Receive and send email with Scala

I'm planning to build a service using Scala and Akka that is going to depend on e-mail heavily. In fact, most of the communication with my service will be done by sending letters to it and getting a replies. I guess this means I need a reliable email server and ways to communicate with it from Scala.

Question is, what are the best practices for doing this? Which email server should I choose and what Scala solutions are there to accomplish this task?

like image 255
src091 Avatar asked Mar 09 '14 12:03

src091


2 Answers

Usually JavaMail API is used. In your project you can wrap it in your own Scala library or use existing one. Here is an example of using existing Mailer API in Lift framework:

package code
package config

import javax.mail.{Authenticator, PasswordAuthentication}
import javax.mail.internet.MimeMessage

import net.liftweb._
import common._
import util._

/*
* A Mailer config object that uses Props and auto configures for gmail
* if detected.
*/
object SmtpMailer extends Loggable {
  def init(): Unit = {

    var isAuth = Props.get("mail.smtp.auth", "false").toBoolean

    Mailer.customProperties = Props.get("mail.smtp.host", "localhost") match {
      case "smtp.gmail.com" => // auto configure for gmail
        isAuth = true
        Map(
          "mail.smtp.host" -> "smtp.gmail.com",
          "mail.smtp.port" -> "587",
          "mail.smtp.auth" -> "true",
          "mail.smtp.starttls.enable" -> "true"
        )
      case h => Map(
        "mail.smtp.host" -> h,
        "mail.smtp.port" -> Props.get("mail.smtp.port", "25"),
        "mail.smtp.auth" -> isAuth.toString
      )
    }

    //Mailer.devModeSend.default.set((m : MimeMessage) => logger.info("Sending Mime Message: "+m))

    if (isAuth) {
      (Props.get("mail.smtp.user"), Props.get("mail.smtp.pass")) match {
        case (Full(username), Full(password)) =>
          logger.info("Smtp user: %s".format(username))
          logger.info("Smtp password length: %s".format(password.length))
          Mailer.authenticator = Full(new Authenticator() {
            override def getPasswordAuthentication = new
              PasswordAuthentication(username, password)
          })
          logger.info("SmtpMailer inited")
        case _ => logger.error("Username/password not supplied for Mailer.")
      }
    }
  }
}

Many web frameworks would implement conveniece methods for you to deal with mime types, attachments, etc.

Needless to say that sending email is never 100% reliable. It's more like fire and forget operation. There is no confirmation or error propagation in mail protocols by default which is usually accepted as normal.

If you use SMTP mail sender you can connect it to any mail server whether it's an external one like gmail, or locally installed postfix.

like image 65
yǝsʞǝla Avatar answered Oct 07 '22 15:10

yǝsʞǝla


You can try courier which is a Scala layer on top of Java Mail that gives more fluent API. Unfortunately, at the moment there are no non-blocking solution for email sending on the JVM (correct me if I'm wrong).

like image 29
Tvaroh Avatar answered Oct 07 '22 16:10

Tvaroh