Kotlin でメールを送信する - SMTP & Email Sending API

Customers Mail Cloudではメール送信に際して、SMTPとAPIの二種類を提供しています。昔からの使い慣れたSMTPを使っても良いですし、SMTPのポート制限されている場合でも使えるAPIを利用しても良いでしょう。

今回はこの二つのメール送信方法について、Kotlinから利用する方法を紹介します。

APIユーザを作成する

API設定画面にて、APIユーザを作成します。アクセス権限として、SMTPは必須になります。API経由での配信を行う場合はSMTPに加えて、HTTP-APIも有効にしてください。

SMTPを使ったメール送信について

標準ライブラリだけで実装します。SMTPサーバのアドレスは指定されたものに置き換えてください。まず必要なライブラリを読み込みます。

import java.io.UnsupportedEncodingException;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

続いて認証情報を提供するクラスを作ります。これは Authenticator を継承します。この認証情報は先ほど作成したAPIユーザ名とAPIキーになります。

internal class MyAuth : Authenticator() {
    override fun getPasswordAuthentication(): PasswordAuthentication {
        val apiUser = "api@smtps.jp"
        val apiKey = "YOUR_API_KEY"
        return PasswordAuthentication(apiUser, apiKey)
    }
}

main関数の内容は、まずプロパティを使ってSMTPサーバを定義します。さらにネットワークセッションを作る際に、先ほどの認証情報を呼び出します。

    val smtpHost = "sandbox.smtps.jp"
    val smtpPort = "10025"
    val smtpAuth = "true"
    val objPrp = Properties()
    objPrp["mail.smtp.host"] = smtpHost
    objPrp["mail.host"] = smtpHost
    objPrp["mail.smtp.port"] = smtpPort
    objPrp["mail.smtp.auth"] = smtpAuth
    // メールセッションを確立
    val session = Session.getDefaultInstance(objPrp, MyAuth())

そしてメールを組み立てます。メールの送信は Transport.send(msg); で行います。メール送信はネットワーク状態などでエラーが出る可能性があるので、必ず try/catch を使います。

    // 送信メッセージを生成
    val msg = MimeMessage(session)
    try {
        val to = "to@smtps.jp"
        val fromName = "Mailer"
        val fromAddress = "info@smtps.jp"
        val subject = "テストメール from Customers Mail Cloud"
        val body = "こんにちは"
        msg.setRecipients(Message.RecipientType.TO, to)
        val objFrm = InternetAddress(fromAddress, fromName)
        msg.setFrom(objFrm)
        msg.setSubject(subject, "UTF-8")
        msg.setText(body, "UTF-8")
        Transport.send(msg)
    } catch (e: UnsupportedEncodingException) {
        e.printStackTrace()
    } catch (e: MessagingException) {
        e.printStackTrace()
    }

これでSMTP経由でのメール送信が完了します。

API経由でのメール送信について

APIサーバについて

APIサーバのエンドポイントURLは契約しているプランによって異なりますのでご注意ください。

プラン名 エンドポイントURL
Standardプラン https://te.smtps.jp/api/v2/emails/send.json
Proプラン https://SUBDOMAIN.smtps.jp/api/v2/emails/send.json

SUBDOMAINは、サービス利用開始時に申請いただいたものです

クラスを作成する

APIにはJSONを送信します。そのためのクラスを用意します。JSON全体を表すのがMailJsonクラスです。

class MailJson {
    var api_user: String? = null
    var api_key: String? = null
    var subject: String? = null
    var text: String? = null
    var from: MailAddress? = null
    var to: MutableList<MailAddress> = mutableListOf()
}

メールアドレス部分だけを表すのがMailAddressクラスです。

class MailAddress {
    var name: String? = null
    var address: String? = null
}

変数を設定する

変数はSMTPサーバ利用時とほぼ同等、SMTPサーバの代わりにエンドポイントURLを指定します。

    val toName = "User"
    val toAddress = "to@smtps.jp"
    val fromName = "Mailer"
    val fromAddress = "info@smtps.jp"
    val subject = "テストメール from Customers Mail Cloud"
    val text = "こんにちは"
    val apiUser = "api@moongift.jp"
    val apiKey = "Ya8JVuazQt3hhPN"
    val url = "https://pro.smtps.jp/api/v2/emails/send.json"

配信内容は先ほどのクラスを使って定義します。

    // JSONの組み立て
    val obj = MailJson()
    obj.api_user = apiUser
    obj.api_key = apiKey
    obj.subject = subject
    obj.text = text

    // 送信元
    val from = MailAddress()
    from.name = fromName
    from.address = fromAddress
    obj.from = from
    // 送信先
    val to = MailAddress()
    to.name = toName
    to.address = toAddress
    obj.to.add(to)

そしてクラスをJacksonを使ってJSON文字列にします。

    val mapper = ObjectMapper()
    val json: String = mapper.writeValueAsString(obj)

JSONの内容については 共通仕様 | Customers Mail Cloud を参照してください。

送信を行う

ではAPIサーバのエンドポイントURLと配信情報のパラメータを使ってメール送信を行います。メール送信APIはPOSTメソッドを使います。HTTPアクセスは org.apache.http を使います。JSON文字列にするJacksonも読み込みます。

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.util.EntityUtils;
import org.apache.http.entity.StringEntity;
// Jackson
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

HTTPメソッドとヘッダーの定義をし、HTTPリクエストオブジェクトを作成します。

    val entity = StringEntity(json, "UTF-8")
    val httpPost = HttpPost(url)
    httpPost.setHeader("Content-type", "application/json; charset=UTF-8")
    httpPost.setEntity(entity)

そしてHTTPリクエストを実行します。

    val client: CloseableHttpClient = HttpClients.createDefault()
    val response: CloseableHttpResponse = client.execute(httpPost)
    System.out.println(EntityUtils.toString(response.getEntity()))
    // 閉じる
    client.close()

送信が成功すると、下記のようにメールIDが返ってきます。

{"id":"\u003C314195997.17022.1560845073906@mta02.sandbox.smtps.jp\u003E"}

エラーがあると、下記のようにエラー内容が返ってきます。

{"errors":[{"code":"02-001","field":"text","message":"text is required."}]}

まとめ

サーバ上の制限によってSMTPが使えない場合でもHTTP経由でメール配信が行えますので、APIをぜひ使ってみてください。今回はKotlinを使いましたが、汎用的なHTTPアクセスを行っていますので、他のプログラミング言語でも簡単に実装できるでしょう。

さらに詳しい使い方についてはEmail Sending APIを参照してください。