KotlinからSendGridを利用してメール送信する
- 2017年9月28日
- by 菊田 洋一
- Category: 技術ネタ
SendGridサポートチームの菊田(@kikutaro_)です。先日、今年開催される「JavaOne」のセッションについて調べていたのですが、ふと気になって「Kotlin」というキーワードを調べたところ12件ありました。これは去年に比べて倍くらいの数です。また、今年の11月には「KotlinConf」という2日間に渡るカンファレンスが開催されるなど、開発者の間でKotlinへの注目度が増しています。その大きな要因として、今年5月に開催された「Google I/O 2017」でAndroidアプリの公式開発言語にKotlinが加わったことが挙げられます。
KotlinはJava仮想マシン上で動作するJVM言語の1つで、静的型付けのオブジェクト指向言語です。IntelliJ IDEAやReSharperなどの開発者向け製品で有名なJet Brainsによって開発されました。型推論やnull安全、セミコロンレスなどの機能が揃っていて、Javaより簡潔に記述できるのが特徴です。
今回のブログではKotlinを使ってSendGridのメール送信を試してみたいと思います。
動作確認環境や実際に試したコードはこちらを参照してください。
Kotlin x HTTP Clientでメール送信
SendGridが公開しているWeb API v3を利用して、まずはシンプルにHTTPでAPIをコールしてみます。Kotlin関連のライブラリは既に色々なものがありますが、今回はこの中からFuelというHTTP Clientライブラリを利用しました。
試したのは次のようなコードです。メールアドレスやAPIキーはダミーにしているので、適宜読み換えてください。
package jp.co.kke.sendgrid.kotlin import com.github.kittinunf.fuel.core.FuelManager import com.github.kittinunf.fuel.httpPost import com.github.kittinunf.result.Result fun main(args : Array<String>) { var to = "to@example.com" var from = "from@example.com" var fromName = "SenderKotlin" var content = """ { "personalizations": [ { "to": [ { "email": "$to" } ] } ], "from": { "email": "$from", "name": "$fromName" }, "subject": "テスト", "content": [ { "type": "text/plain", "value": "Kotlinから送った" }, { "type": "text/html", "value": "<html><body>Kotlinから送った</body></html>" } ] } """ FuelManager.instance.baseHeaders = mapOf("Content-Type" to "application/json", "Authorization" to "Bearer *****APIキー*****") "https://api.sendgrid.com/v3/mail/send".httpPost().body((content)).response { req, res, result -> when(result) { is Result.Failure -> { println("APIのコールに失敗") } is Result.Success -> { when(res.httpStatusCode) { 202 -> println("メール送信成功") 400, 401, 413 -> println("SendGridから400番台のエラーコードが返ってきた") else -> println("想定していないコードが返ってきた") } } } println(req) println(res) println(result) } }
トリプルクォートによる文字列定義
前半部分、JSON形式でメール送信情報を定義しています。Kotlinではトリプルクォート(”””)で文字列を挟むことで生文字列(Raw String)を宣言できるため、エスケープなしで直観的にJSONデータを定義できます。Javaではトリプルクォートのような表現はないため、同じように定義すると二重引用符のエスケープ(\”)や改行に伴う文字列の連結(+)などが入り、どうしても見づらくなってしまいます。
//Javaの例 String content = "{" +"\"personalizations\": [" +"{" //……以下略
実際のシステムでは直接文字列を指定するのではなく、メールテンプレートのファイルから文字列を読み込んだり、JSONとオブジェクトのマッパーを利用したりします。そのため、あまり気にならない部分かもしれませんが、今回のようなちょっとしたサンプルコードを書く上では嬉しい表現方法です。
String Templatesによる変数の差し込み
JSON文字列の中では「$to」「$from」「$fromName」といった記述があります。これは冒頭に宣言した変数の値をそれぞれ差し込むことを意味し、String Templatesと呼ばれる機能です。SendGridでもsubstitutionsを利用した値の差し込みが可能なので、うまく使い分けながら組み合わせることで様々なパターンの差し込みを実現できそうです。
Collection (mapOfの利用)
Kotlinは豊富な標準ライブラリを揃えています。今回はCollectionを利用してHTTPヘッダの値(AuthorizationヘッダやAcceptヘッダなど)を次のように定義しました。
mapOf("Content-Type" to "application/json", "Authorzation" to "Bearer *****APIキー*****")
whenを使った処理分岐
コード後半のPOSTデータを投げる部分では、whenを使ってAPIコール結果の処理を分岐しています。JavaのSwitch文と違い、引数なしで次のような記述も可能です。
when{ result is Result.Failure -> { println("APIのコールに失敗") } result is Result.Success -> { //成功時の処理 } }
また、分岐条件に式を利用できるなど、柔軟性の高い記述が可能です。
Kotlin x SendGrid Javaライブラリでメール送信
Kotlinの魅力の1つに既存のJava資産を活用できる点があります。そこで今度はSendGridが公式に提供しているJavaライブラリを使ってメール送信してみます。
Kotlinで書く前にJavaのコード例を示します。SendGridのリポジトリにあるHelper Classを利用した例を掲載します。
import com.sendgrid.*; import java.io.IOException; public class Example { public static void main(String[] args) throws IOException { Email from = new Email("test@example.com"); String subject = "Sending with SendGrid is Fun"; Email to = new Email("test@example.com"); Content content = new Content("text/plain", "and easy to do anywhere, even with Java"); Mail mail = new Mail(from, subject, to, content); SendGrid sg = new SendGrid(System.getenv("SENDGRID_API_KEY")); Request request = new Request(); try { request.setMethod(Method.POST); request.setEndpoint("mail/send"); request.setBody(mail.build()); Response response = sg.api(request); System.out.println(response.getStatusCode()); System.out.println(response.getBody()); System.out.println(response.getHeaders()); } catch (IOException ex) { throw ex; } } }
これをKotlinに置きかえてみます。IDEのIntelliJ IDEAを使うと上記コードをペースト後「Kotlinへ変換しますか?」と聞かれます。Yesを選択すると次のようなコードへ自動変換してくれました。
package jp.co.kke.sendgrid.kotlin import com.sendgrid.* import java.io.IOException fun sendBySendGrid() { val from = Email("test@example.com") val subject = "Sending with SendGrid is Fun" val to = Email("test@example.com") val content = Content("text/plain", "and easy to do anywhere, even with Kotlin") val mail = Mail(from, subject, to, content) val sg = SendGrid("*****APIキー*****") val request = Request() try { request.method = Method.POST request.endpoint = "mail/send" request.body = mail.build() val response = sg.api(request) System.out.println(response.statusCode) System.out.println(response.body) System.out.println(response.headers) } catch (ex: IOException) { throw ex } }
上記2つのコードでは、Javaと比較して主に次の3点が異なります。
- 変数宣言で型の明示が不要(型推論)
- インスタンス生成にnewが不要
- セミコロンなし
全体的にすっきりした感じですが、上記サンプルコードのレベルだとJavaとあまり大きな差がないため面白みは薄いかもしれません。とはいえ、このような形でJavaのライブラリをそのまま利用できることは、既存資産を活かす上で非常に重要です。
このコード、もっとスマートに書けるのでは?という方は是非100% Pure KotlinなSendGridライブラリとしてsendgrid4ktのようなものを作っていただけると嬉しいです!
おわりに
いかがでしたでしょうか。私は今回はじめてKotlinを触ったのですが、とても書きやすい印象を受けました。もちろん、基本の文法部分しか触れていないため、というのはあると思いますが、今後も触ってみたいと思いました。
なお、KotlinはAndroidの開発で利用される機会が多いかと思いますが、モバイルアプリでSendGridを使う際はAPIキーをクライアントアプリ側に埋め込まないように注意してください。通常はバックエンドのサーバサイド側にメール送信機能を持たせる形が多いかと思います。mBaaSなどの環境を上手く活用すれば、サーバサイドとの連携も効率良く実装できます。
参考:
ニフティクラウドmobile backendを使ってスマホアプリからメールを送信する方法
Kiiを使ってスマホアプリからメールを送信する方法
現在KotlinはAndroidに限らず、サーバサイドでの利用も増えていると聞きます。今月末にはKotlin x Webアプリケーション本も出るようなので、今後色々と試していきたいと思います。