会員がログインパスワードを忘れたとき、登録してあるメールアドレスにメールを送信してその中のリンクを押すとパスワードがリセットされる、というのをやりたかったので、AWS 上のWebアプリにメール送信機能を実装。
メール送信機能は jar ファイルにして部品化。
プログラミングより AWS の設定が面倒臭い気がしました。
#1.環境
VS Code
Java Extension Pack
Spring Boot Extension Pack
#2.SMTP認証情報の習得
以下の URL の内容の通り、AWS のコンソールにログインして「Amazon SES コンソールを使用して Amazon SES SMTP 認証情報を取得する」の1~6を実施してSMTPユーザー名とSMTPパスワードを取得します。
取得するとメールサーバー名とポート番号も表示されます。
#3.Gradle Project の作成
VS Code のコマンドパレットで「Spring Initializr: Generate a Gradle Project」 → 「Java」 → 「任意のGroupId」 → 「任意のArtifactId」 → 「任意のバージョン」 → 「dependenceies は空白」を選択して Gradle Project を作成します。
(別に Spring Boot じゃなくてもいいですけど…)
#4.依存関係の追加とか
Amazon SES SMTP を使用してメールを送信するために必要な javax.mail.jar を取得するため、build.gradle ファイルに依存関係を追加します。
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'com.sun.mail:javax.mail:1.6.2' //←追加★
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
//↓ついでに追加★
bootJar {
enabled = false
}
jar {
enabled = true
baseName = 'aws-ses-send'
version = ''
from configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
#5.実装
AWSのサイトのコードをほぼそのまま使います。
package com.xxx.aws;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class AmazonSES {
// Replace sender@example.com with your "From" address.
// This address must be verified.
static final String FROM = "送信元メールアドレス";
static final String FROMNAME = "送信元名";
// Replace recipient@example.com with a "To" address. If your account
// is still in the sandbox, this address must be verified.
// static final String TO = "recipient@example.com";
// Replace smtp_username with your Amazon SES SMTP user name.
static final String SMTP_USERNAME = "SMTPユーザー名";
// Replace smtp_password with your Amazon SES SMTP password.
static final String SMTP_PASSWORD = "SMTPパスワード";
// The name of the Configuration Set to use for this message.
// If you comment out or remove this variable, you will also need to
// comment out or remove the header below.
// static final String CONFIGSET = "ConfigSet"; //←不要ならコメントアウト★
// Amazon SES SMTP host name. This example uses the 米国西部 (オレゴン) region.
// See https://docs.aws.amazon.com/ses/latest/DeveloperGuide/regions.html#region-endpoints
// for more information.
static final String HOST = "メールサーバー名";
// The port you will connect to on the Amazon SES SMTP endpoint.
static final int PORT = ポート番号;
// 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 void send(String to,
String subject,
String body) throws Exception {
// Create a Properties object to contain connection configuration information.
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");
// Create a Session object to represent a mail session with the specified properties.
Session session = Session.getDefaultInstance(props);
// Create a message with the specified information.
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");
// Add a configuration set header. Comment or delete the
// next line if you are not using a configuration set
// msg.setHeader("X-SES-CONFIGURATION-SET", CONFIGSET);//←不要ならコメントアウト★
// Create a transport.
Transport transport = session.getTransport();
// Send the message.
try
{
System.out.println("Sending...");
// Connect to Amazon SES using the SMTP username and password you specified above.
transport.connect(HOST, SMTP_USERNAME, SMTP_PASSWORD);
// Send the email.
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
{
// Close and terminate the connection.
transport.close();
}
}
}
#6.送信元として有効なメールアドレスをAWSに登録する
以下の URL の内容の通り、AWS のコンソールにログインして「Amazon SES コンソールを使用して E メールアドレスを検証する」の1~7を実施して、送信元として有効なメールアドレスを登録します。
この手順が終わったメールアドレスのみ送信元メールアドレスとして使えます。
#7.送信先の制限を外す
この状態だと、送信先を自由に選択してメールを送ることはできません。
送信先のメールアドレスも送信元同様、送信先としてメールを送信できるか事前に検証してOKになってないる必要があります。
「サンドボックスの中にいる」という状況です。
送信先を自由に選択してメールを送るには「サンドボックスの外に出る」必要があります。
以下の URL の内容の通り、AWS のコンソールにログインして「Amazon SES サンドボックス外への移動」の1~9を実施して、サポートセンターから許可をもらいます。
許可がもらえれば送信先の事前検証は不要になります。
#8.実行
VS Code のターミナルから以下のコマンドを実装して、jar ファイルを作成します。
.\gradlew build
作成した jar ファイルを呼び出し元のプロジェクトに配置して、実装した send メソッドを呼べばメール送信できます。
以上です。