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

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

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

APIユーザを作成する

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

f:id:moongift:20190524133446p:plain

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キーになります。

class myAuth extends Authenticator {
  protected PasswordAuthentication getPasswordAuthentication(){
    String apiUser = "api@smtps.jp";
    String apiKey  = "YOUR_API_KEY";
    return new PasswordAuthentication(apiUser, apiKey);
  }
}

次にメール送信を行うクラスを定義します。このmainメソッドを実行することとします。

public class SendMail {
  public static String smtpHost = "sandbox.smtps.jp";
  public static String smtpPort = "10025";
  public static String smtpAuth = "true";
  
  public static void main(String[] args){
    smtp();
  }
  private static void smtp() {
  }
}

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

private static void smtp() {
  Properties objPrp=new Properties();
  objPrp.put("mail.smtp.host", SendMail.smtpHost);
  objPrp.put("mail.host", SendMail.smtpHost);
  objPrp.put("mail.smtp.port", SendMail.smtpPort);
  objPrp.put("mail.smtp.auth", SendMail.smtpAuth);
  // メールセッションを確立
  Session session = Session.getDefaultInstance(objPrp, new myAuth());
  // 省略
}

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

// 送信メッセージを生成
MimeMessage msg = new MimeMessage(session);
try {
  String to = "to@smtps.jp";
  String fromName = "Mailer";
  String fromAddress = "info@smtps.jp";
  String subject = "テストメール from Customers Mail Cloud";
  String body = "こんにちは";

  msg.setRecipients(Message.RecipientType.TO, to);
  InternetAddress objFrm= new InternetAddress(fromAddress, fromName);
  msg.setFrom(objFrm);
  msg.setSubject(subject,"UTF-8");
  msg.setText(body,"UTF-8");
  Transport.send(msg);
} catch (UnsupportedEncodingException e) {
  e.printStackTrace();
} catch (MessagingException e) {
  e.printStackTrace();
}      

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

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

APIサーバについて

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

プラン名 エンドポイントURL
無料トライアル https://sandbox.smtps.jp/api/v2/emails/send.json
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クラスです。

package sendmail;

public class MailJson {
  public String api_user;
  public String api_key;
  public String subject;
  public String text;
  public MailAddress from;
  public MailAddress[] to;
}

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

package sendmail;

public class MailAddress {
  public String name;
  public String address;
}

変数を設定する

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

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

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

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

// 送信元
MailAddress from = new MailAddress();
from.name = fromName;
from.address = fromAddress;
obj.from = from;

// 送信先
MailAddress to = new MailAddress();
to.name = toName;
to.address = toAddress;
obj.to = new MailAddress[1];
obj.to[0] = to;

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

ObjectMapper mapper = new ObjectMapper();
String json = 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リクエストオブジェクトを作成します。

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

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

CloseableHttpClient client = HttpClients.createDefault();
CloseableHttpResponse response = 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をぜひ使ってみてください。今回はJavaを使いましたが、汎用的なHTTPアクセスを行っていますので、他のプログラミング言語でも簡単に実装できるでしょう。

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