← На главную

Как отправить электронное письмо в Scala

В этой заметке будет показано, как в Scala послать письмо через гугловые SMTP-сервера с помощью пакета JavaMail. Притом не какое-нибудь простое письмо, а с прикрепленным файлом, в кодировке UTF-8 и с HTML, содержащим картинки. Функциональщины как таковой не будет, зато мы увидим, как выглядит использование Java-библиотек из Scala, а также ознакомимся с той частью Scala, которая «почти как Java, только лучше».

Нам понадобится файл build.sbt следующего содержания:

name := "gmail-sender" version := "0.2" scalaVersion := "2.10.1" libraryDependencies += "javax.mail" % "mail" % "1.5.0-b01" scalacOptions ++= Seq("-unchecked", "-deprecation")

Если у вас не установлена Scala 2.10.1, не беспокойтесь, sbt самостоятельно подтянет и скомпилирует ее. Это не займет много времени.

В простейшем случае работа с JavaMail выглядит следующим образом:

import javax.mail._ import javax.mail.internet._ import java.util._ object GmailSenderSimple extends App { if(args.size < 2) { println("Usage: gmail-sender-simple gmail-user gmail-password") sys.exit(1) } val Array(username, password, _*) = args val properties = new Properties() properties.put("mail.smtp.host", "smtp.gmail.com") properties.put("mail.smtp.starttls.enable","true") val session = Session.getDefaultInstance(properties) val message = new MimeMessage(session) message.setFrom(s"User Name <$username>") message.addRecipients(Message.RecipientType.TO, s"User Name <$username>") message.setSubject("Greetings!") message.setText("Hello!") Transport.send(message, username, password) }

Если передать программе в качестве аргументов ваш электронный адрес на GMail и пароль к нему, вы отправите сами себе простое текстовое письмо.

Обратите внимание на использование экстракторов, которые удобны не только при объявлении переменных, но и в сопоставлении с образцом:

scala> val Array(x, y, z @ _*) = Array(1,2,3,4,5) x: Int = 1 y: Int = 2 z: Seq[Int] = Vector(3, 4, 5) scala> List(1,2,3) match { case List() => "Empty list"; ⏎ case List (1, _, _) => "1 _ _"; case _ => "Whatever" } res0: String = 1 _ _

…, а также на интерполяцию строк, которая появилась в Scala 2.10:

scala> val str = s"x = $x, y = $y" str: String = x = 1, y = 2

Полагаю, тут все понятно, и можно перейти к более сложному примеру:

import javax.mail._ import javax.mail.internet._ import java.util._ object GmailSender extends App { if(args.size < 2) { println("Usage: gmail-sender gmail-user gmail-password") sys.exit(1) } val Array(username, password, _*) = args val properties = new Properties() properties.put("mail.smtp.host", "smtp.gmail.com") properties.put("mail.smtp.starttls.enable","true") val message = new MimeMessage(Session.getDefaultInstance(properties)) val multipart = new MimeMultipart() val alternative = new MimeMultipart("alternative") val imageId = UUID.randomUUID.toString val textPart, htmlPart, wrap, attachmentPart, imagePart = new MimeBodyPart() textPart.setText("Тело письма") alternative.addBodyPart(textPart) htmlPart.setContent( s"""|А это - тело письма в <strong>HTML</strong> | с картинкой: <img src="cid:$imageId" alt="" /> |""".stripMargin, "text/html; charset=UTF-8") alternative.addBodyPart(htmlPart) wrap.setContent(alternative) multipart.addBodyPart(wrap) attachmentPart.attachFile("./build.sbt") multipart.addBodyPart(attachmentPart) imagePart.attachFile("./afiskon.jpg") imagePart.setContentID(s"<$imageId>") multipart.addBodyPart(imagePart) message.setFrom(s"User Name <$username>") message.addRecipients(Message.RecipientType.TO, s"User Name <$username>") message.setSubject("Сабжект") message.setContent(multipart) Transport.send(message, username, password) }

Я надеюсь, что вы знаете, что такое multipart/alternative и прочее в этом духе, поскольку этот вопрос выходит за рамки поста. Если теперь запустить приведенную программу:

sbt "run user@gmail.com password"

… то вам придет примерно такое электронное письмо:

Отправка e-mail на Scala

Все, как обещано – юникод, прикрепленный файл, HTML c картинкой. Полную версию исходного кода вы найдете в этом архиве.

Дополнение: Работа с регулярными выражениями в Scala