Как отправить электронное письмо в Scala
20 марта 2013
В этой заметке будет показано, как в Scala послать письмо через гугловые SMTP-сервера с помощью пакета JavaMail. Притом не какое-нибудь простое письмо, а с прикрепленным файлом, в кодировке UTF-8 и с HTML, содержащим картинки. Функциональщины как таковой не будет, зато мы увидим, как выглядит использование Java-библиотек из Scala, а также ознакомимся с той частью Scala, которая «почти как Java, только лучше».
Нам понадобится файл build.sbt следующего содержания:
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.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 и пароль к нему, вы отправите сами себе простое текстовое письмо.
Обратите внимание на использование экстракторов, которые удобны не только при объявлении переменных, но и в сопоставлении с образцом:
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:
str: String = x = 1, y = 2
Полагаю, тут все понятно, и можно перейти к более сложному примеру:
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 и прочее в этом духе, поскольку этот вопрос выходит за рамки поста. Если теперь запустить приведенную программу:
… то вам придет примерно такое электронное письмо:
Все, как обещано — юникод, прикрепленный файл, HTML c картинкой. Полную версию исходного кода вы найдете в этом архиве.
Дополнение: Работа с регулярными выражениями в Scala
Метки: Scala, Функциональное программирование.
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.