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アプリケーション本も出るようなので、今後色々と試していきたいと思います。


