はじめに
AWSのSES(Simple Email Service)を使用する機会があったため、復習も兼ねて、Javaプログラムでメール送信する方法をまとめたいと思います。
SMTPを使用する方法とAWS SDKを使用する方法を記載します。
Amazon SESについて
- Amazon SES(Simple Email Service)はAmazonが提供するメール配信サービス
- 導入コストが低く、小規模で安価な運用が可能
- 毎月最初の 62,000 通のメールについては無料で送信できる(SES料金)
- AWSの他のサービスを使用することでメールログの保存や分析が可能
事前準備(SESコンソール)
プログラムを作成する前に下記をする必要があります。
送信元(From)アドレスの認証、送信先(To)アドレスの認証
アカウントはサンドボックスと呼ばれるテスト環境に新規ユーザーとして作成されるため、確認した E メールアドレスでの E メール送受信のみができます。
未確認の E メールアドレスに E メールを送信する、1 日あたりに送信できる E メールの数を増やす、高速で E メールを送信するためには、アカウントをサンドボックスの外に移動する必要があります。
手順
- AWSにログインし、SESコンソールを開く
- 「Email Addresses」をクリック
- 「Verify a New Email Address」ボタンをクリック
- 認証するメールアドレスを入力して、「Verify This Email Address」ボタンをクリック
- 受信したメール内のリンクをクリック
- 手順2.の画面を開くと指定したメールアドレスのVerification Statusがverified(認証済み)になっている
これでメールアドレスの認証は完了です。
「Send a Test Email」ボタンをクリックでメールが送受信できるか確認できます。
SMTPユーザーを作成して認証情報(ユーザー名とパスワード)を取得する(SMTPを使用する場合のみ)
手順
- AWSにログインし、SESコンソールを開く
- 「SMTP Settings」をクリック
- 「Create My SMTP Credentials」ボタンをクリック
- SMTPユーザーの名前を入力して「作成」ボタンをクリック(名前はデフォルト値でも可)
- 「ユーザーの SMTP セキュリティ認証情報を表示」をクリック
- 表示された認証情報をコピーして安全な場所に保存しておく or 「認証情報のダウンロード」でcsvをダウンロード
IAMコンソール > アクセス管理 > ユーザー で作成したSMTPユーザーを確認できます。
アクセスキーIDとシークレットアクセスキーを取得(AWS SDKを使用する場合のみ)
手順
- AWSにログインし、IAMコンソールを開く
- ダッシュボードのルートアクセスキーの削除のプルダウンの「セキュリティ認証情報の管理」ボタンをクリック
- アクセスキーのプルダウンの「新しいアクセスキーの作成」ボタンをクリック
- アクセスキーIDとシークレットアクセスキーをメモするか、キーファイルをダウンロードをする
動作環境
- Eclipse Version: 2020-06 (4.16.0)
- javaバージョン
$ java -version
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)
Javaプログラム SMTP
- EclipseでMavenプロジェクトを作成
- pom.xmlにJavaMailの依存関係を追加(MvnRepositoryでJavaMailを検索して最新バージョンのjarを追加)
- メール送信プログラム作成
<!-- 依存関係 -->
<dependencies>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
</dependencies>
public class SesSmtpSample {
// 送信者アドレスと送信者名(SESコンソールで認証したメールアドレス)
static final String FROM = "sender@example.com";
static final String FROMNAME = "Sender Name";
// 宛先アドレス(SESコンソールで認証したメールアドレス)
static final String TO = "recipient@example.com";
// SESコンソールで作成したSMTPユーザー名とパスワード
static final String SMTP_USERNAME = "smtp_username";
static final String SMTP_PASSWORD = "smtp_password";
// SESコンソールで作成したConfig Setを指定。メールログの保存をするときなどに使用する。今回は不要なのでコメントアウト
// static final String CONFIGSET = "ConfigSet";
// Amazon SES SMTPのエンドポイント(リージョンがオレゴンの場合はus-west-2)
static final String HOST = "email-smtp.us-west-2.amazonaws.com";
// Amazon SES SMTPのエンドポイントのポート番号.
static final int PORT = 587;
// メール件名
static final String SUBJECT = "Amazon SES test (SMTP interface accessed using Java)";
// 本文
static final String BODY = String.join(
System.getProperty("line.separator"),
"<h1>Amazon SES SMTP Email Test</h1>",
"<p>This email was sent with Amazon SES using the ",
"<a href='https://github.com/javaee/javamail'>Javamail Package</a>",
" for <a href='https://www.java.com'>Java</a>."
);
public static void main(String[] args) throws Exception {
// SMTPサーバーを定義
Properties props = System.getProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.port", PORT);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
// メールセッションの確立
Session session = Session.getDefaultInstance(props);
// メール作成
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(FROM,FROMNAME));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(TO));
msg.setSubject(SUBJECT);
msg.setContent(BODY,"text/html");
// Configuration Setを設定。今回は使用しないのでコメントアウト
//msg.setHeader("X-SES-CONFIGURATION-SET", CONFIGSET);
Transport transport = session.getTransport();
// メール送信
try {
System.out.println("Sending...");
// SMTPサーバに接続
transport.connect(HOST, SMTP_USERNAME, SMTP_PASSWORD);
// メール送信
transport.sendMessage(msg, msg.getAllRecipients());
System.out.println("Email sent!");
} catch (Exception ex) {
System.out.println("The email was not sent.");
System.out.println("Error message: " + ex.getMessage());
} finally {
// 接続終了
transport.close();
}
}
}
SMTPのエンドポイントはリージョンによって変わります。
AWSのリファレンスで確認できます。
Javaプログラム AWS SDK
AWS Toolkit for Eclipseをインストール
- Eclipseを起動し、「Eclipceマーケットプレイス」を開く
- 「aws」で検索すると一番上に「AWS Toolkit for Eclipse」があるはずなので、それをインストール
- インストール後にEclipceを再起動すると、AWSのアクセスキーIDとシークレットアクセスキーの入力が求められるため、入力する
上記の作業を行うとホームディレクトリに認証情報の共有ファイルが作成されます。
このファイルがないとAWS SDKを使用したプログラムは動かないようです。
OS | ファイルパス |
---|---|
Windows | C:\Users<yourUserName>.aws\credentials |
Linux, macOS, or Unix | ~/.aws/credentials |
[default]
aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID
aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY
AWS Java Projectを作成
- 「File」メニューで「AWS Java Project」を選択
- プロジェクト名を入力して、AWS SDK for Java Samplesで「Amazon Simple Email Service JavaMail Sample」を選択して、「完了」ボタンをクリック
- 「AmazonSESSample.java」が作成されるので、それを編集
public class AmazonSESSample {
// 送信者アドレス(SESコンソールで認証したメールアドレス)
static final String FROM = "sender@example.com";
// 宛先アドレス(SESコンソールで認証したメールアドレス)
static final String TO = "ecipient@example.com";
// SESコンソールで作成したConfig Setを指定。メールログの保存するときなどに使用する。今回は不要なのでコメントアウト
// static final String CONFIGSET = "ConfigSet";
// メール件名
static final String SUBJECT = "Amazon SES test (AWS SDK for Java)";
// 本文(HTMLメール用)
static final String HTMLBODY = "<h1>Amazon SES test (AWS SDK for Java)</h1>"
+ "<p>This email was sent with <a href='https://aws.amazon.com/ses/'>"
+ "Amazon SES</a> using the <a href='https://aws.amazon.com/sdk-for-java/'>"
+ "AWS SDK for Java</a>";
// 本文(HTMLメール以外)
static final String TEXTBODY = "This email was sent through Amazon SES "
+ "using the AWS SDK for Java.";
public static void main(String[] args) throws IOException {
try {
AmazonSimpleEmailService client =
AmazonSimpleEmailServiceClientBuilder.standard()
// リージョンを指定(US_WESST_2はオレゴン)
.withRegion(Regions.US_WEST_2).build();
SendEmailRequest request = new SendEmailRequest()
.withDestination(
new Destination().withToAddresses(TO))
.withMessage(new Message()
.withBody(new Body()
.withHtml(new Content()
.withCharset("UTF-8").withData(HTMLBODY))
.withText(new Content()
.withCharset("UTF-8").withData(TEXTBODY)))
.withSubject(new Content()
.withCharset("UTF-8").withData(SUBJECT)))
.withSource(FROM);
// Configuration Setを設定。今回は使用しないのでコメントアウト
// .withConfigurationSetName(CONFIGSET);
client.sendEmail(request);
System.out.println("Email sent!");
} catch (Exception ex) {
System.out.println("The email was not sent. Error message: "
+ ex.getMessage());
}
}
}
おわりに
Amazon SESの日本語ドキュメントがあるため、基本的にはドキュメント通りにやっていけば問題なくメール送信できると思います。