Frege からメールが送信できるようになりました
ちょっとした Web アプリを作成しようと思うと、メール送信機能がないと困ります。例えば、ログイン機能を持っていれば必然的にパスワードリセットとかも必要になりますからね。
Haskell 風の JVM 言語 Frege でもフレームワーク Chinook を使用して Web アプリが作れますが、メールを送信するライブラリが見当たらなかったので自作しました。
なお、すでに Bintray に公開済みなので、各種ビルドツール経由で呼び出すことができます。現状、Frege のビルドは Gradle がデファクトスタンダードなので、以下でも Gradle で説明しましょう。
使い方
Gradle ビルド時に Bintray に問い合わせに行くように、build.gradle
にリポジトリを追加する必要があります。普段 Maven Central とか jCenter だけ使っていると忘れがちなので気を付けましょう。
あとは Frege コンパイラ自体と、Frege 用のタスクを Gradle に認識させるプラグインを追加すると、ビルド可能な最小の build.gradle
は以下のようになります。
plugins { id 'org.frege-lang' version '0.5' } apply plugin: 'org.frege-lang' repositories { jcenter() maven { url 'http://dl.bintray.com/y-taka-23/maven' } } dependencies { compile 'org.frege-lang:frege:3.23.288-gaa3af0c' compile 'io.cheshirecat:frege-email:0.1.0' }
さて、実際にメールを送信するコードを書いてみましょう。
送信サーバとしてはとりあえず Gmail を使用します。残念なことに現状 安全性の低いアプリからのアクセスを許可 しておく必要がありますが、いずれは対応したい。
コードはこんな感じになります。yourusername
と yourpassword
は手持ちの Google アカウントに差し替えてください。
module Main where import io.cheshirecat.frege.Email server = sslSMTPServer.{ hostName = "smtp.gmail.com" } auth = authentication.{ userName = "yourusername" , password = "yourpassword" } addr = address.{ email = "foo@gmail.com" } testMail = email.{ subject = "Test Mail" , from = addr , to = [addr] , message = "This is a test mail." } main _ = do flip catch handler $ do sendEmail server (Just auth) testMail where handler = \(e::EmailException) -> e.printStackTrace
このコードを src/main/frege/Main.fr
に置いておきます。
生成されるクラスファイルを直接 java
コマンドで叩いても実行できますが、Gradle から実行するのであればさらに build.gradle
に
apply plugin: 'application' mainClassName = 'Main'
を追加した上で gradle run
で実行すると Gmail にテストメールが届くはず。
Frege のおいしいところ
今回のライブラリは Apache Commons Email を呼び出していて、自前で実装しているロジックはほとんどありません。JVM 言語の利点としてよく「既存の Java 資産を使用できる」という点が挙げられますが、Frege もその例外ではなく、面倒な処理は全部 Java 呼び出しで済ませました。
ちなみに呼び出し部分のコードは こんな感じ になります。Frege による Java 連携に興味がある人は、次のスライドが役に立つはずです。
www.slideshare.net
また、前述の Gradle ビルドからわかる通り、作成したライブラリの配布についても、既存の Java のエコシステムに乗っかることができます。ライブラリを作る側の作業については若干気をつける点があるため、備忘録を兼ねてこのブログで書くつもりではありますが、それはまた別の話。