gmailのsmtpサーバー使うのが多分いちばん楽に用意できると思うのでgmailのsmtpサーバー使って送信する例を書きます。
trait GmailConfig extends SkinnyMailerConfig {
override def mailSmtpHost = "smtp.gmail.com"
/*
アカウント設定
*/
override def mailUser = "" // あなたのgmailアカウント名
override def mailPassword = "password" // あなたのgmailパスワード
override def mailDefaultFrom = "[email protected]" // デフォルトの送信元。書かなくてもOKですが、[email protected]が送信アドレスになるはずです。
}
SkinnyMailerConfigはデフォルトではsmtpsを使用して送信するせていになっているため、gmailサーバーならこれでOKなはずです
SkinnyMailerとSkinnyMailerConfigのmixinします。
class MyMailer extends SkinnyMailer with GmailConfig {
def send_email = mail(to = "送信先@gmail.com",
subject = "タイトル",
text = "コンテンツ")
.deliver
}
deliverメソッドを呼び出すとメールが送信されます。
mailメソッドは多分いちばんよく使われるテキストメール用に
def mail(to: String, from: String = config.mailDefaultFrom, subject: String = "", text: String = "") = getDefaultMessage
.from(new InternetAddress(from))
.to(to)
.subject(subject, mailDefaultCharset)
.text(text, mailDefaultCharset)
と定義されているだけなので、下記のように書いてもOKです。
class MyMailer extends SkinnyMailer with GmailConfig {
def send_email = getDefaultMessage
.to("送信先@gmail.com")
.from("送信元@gmail.com")
.subject("タイトル")
.text("コンテンツ")
.deliver
}
class MyMailer extends SkinnyMailer with GmailConfig {
def send_email = mail(to = "送信先@gmail.com", subject = "タイトル", text = "コンテンツ")
.attachment("ファイル名", "ファイルパス")
.attachment("ファイル名", "ファイルパス")
.deliver
}
これももちろん、下記のように書いてもOKです。
class MyMailer extends SkinnyMailer with GmailConfig {
def send_email = getDefaultMessage
.to("送信先@gmail.com")
.from("送信元@gmail.com")
.subject("タイトル")
.text("コンテンツ")
.attachment("ファイル名", "ファイルパス")
.attachment("ファイル名", "ファイルパス")
.deliver
}
sspでも使えばいいんじゃないかな!
ssp使えないならStringInterporationとか使えばいいんじゃないかな!
テスト対象クラスにSkinnyMockMailerをmixinします。
object TestMailer extends MyMailer extends SkinnyMockMailer
テストクラスの方にSkinnyMessageHelperをmixinします。
class FooSpec extends FlatSpec
with ShouldMatchers with SkinnyMessageHelper
一通しか送信しないような場合は、SkinnyMailTestSupportを利用すると便利です。
package skinny.test
import org.scalatest.FlatSpec
import org.scalatest.matchers.ShouldMatchers
import skinny.mail._
import javax.mail.MessagingException
class SkinnyMailTestSupportSpec extends FlatSpec
with ShouldMatchers with SkinnyMessageHelper
with SkinnyMailTestSupport {
behavior of "SkinnyMailTestSupportSpec"
override val singleMailTo = "[email protected]"
object MyMailer extends SkinnyMailer
with SkinnyMailerConfig
with SkinnyMockMailer {
def message = {
mail(to = singleMailTo,
subject = "test subject 日本語",
text="body 日本語").deliver
}
}
it should "singleMail basic" in {
singleMail()(MyMailer.message) { msg =>
msg.getSubject should be("test subject 日本語")
msg.getMailText should be("body 日本語")
// 添付ファイルを取りたいなら
// msg.getMailAttachmentFiles
} should be(true)
}
}
下記が書き方の定型文です。
singleMail(/* 送信されるメールアドレス。デフォルトはsingleMailToなのでto = singleMailToと書いた場合はいらない */)(/* ここで送信するメソッドを与える */) { msg =>
// ここでアサーション処理
} should be(true) // 1通のメールが送信されてきたときのみtrueを返す
これが定型文です。
SkinnyMailerはjavax.mailをラップして作っただけなので、mock_javamailを使えばできます。
it should "be available" in {
Mailbox.clearAll()
TestMailer.message.isRight should be(true)
TestMailer.message.isRight should be(true)
val inbox = Mailbox.get("[email protected]")
// 一通目
inbox.get(0).getSubject should be("subject")
inbox.get(0).getMailText should be("body")
// 二通目
inbox.get(1).getSubject should be("subject")
inbox.get(1).getMailText should be("body")
}
ちなみにConfigを毎回mixinするのはたるいので mail.confを用意して
mail {
default {
debug=true
mimeVersion="1.0"
charset="UTF-8"
contentType="text/plain"
from="[email protected]"
smtp {
host="smtp.skinny.org"
port=587
connectionTimeout=6000
timeout=6000
auth=false
starttls {
enable:true
}
}
transportProtocol="smtp"
user=""
password=""
}
}
こんな設定を書いておいて
class FooMailer extends SkinnyDefaultMailer
とするだけで終わりです。
でも、この設定ファイルは非常に微妙で、手抜き感に溢れてます。あとでやります。
TODO:
- deliverをEitherで返すのは微妙?
- 設定ファイルの設計…
- 設定ファイルがproductionやdevelopで分けれないって…
- リファクタリング
- CastExceptionを潰す
- あと何をやればいいかわからなくなってきた
https://github.com/BlackPrincess/skinny-framework/tree/mail
了解しました!よろしくお願いします。
ぜひぜ。pull request を merge したタイミングで team に追加しますね。