KotlinからSendGridを利用してメール送信する

logo-text

SendGridサポートチームの菊田(@kikutaro_)です。先日、今年開催される「JavaOne」のセッションについて調べていたのですが、ふと気になって「Kotlin」というキーワードを調べたところ12件ありました。これは去年に比べて倍くらいの数です。また、今年の11月には「KotlinConf」という2日間に渡るカンファレンスが開催されるなど、開発者の間でKotlinへの注目度が増しています。その大きな要因として、今年5月に開催された「Google I/O 2017」でAndroidアプリの公式開発言語にKotlinが加わったことが挙げられます。

KotlinはJava仮想マシン上で動作するJVM言語の1つで、静的型付けのオブジェクト指向言語です。IntelliJ IDEAReSharperなどの開発者向け製品で有名な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アプリケーション本も出るようなので、今後色々と試していきたいと思います。