이번 포스팅은 AWS에서 제공하는 이메일 발송 서비스인 SES를 Springboot에서 사용해보겠습니다.
해당 포스트는 서울 리전(ap-northeast-2) 기준으로 작성되었습니다.
[사전 조건]
SandBox 상태 해제
이메일 주소 등록
도메인 등록
dependencies {
...
compile 'com.amazonaws:aws-java-sdk-ses:1.12.3'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}
yml 파일 및 properites 파일에 접근키와 비밀키를 입력합니다.
aws:
ses:
access-key: ADGRCXVB # 액세스 키 ID
secret-key: dslkfmldfan # 보안 액세스 키
@Configuration
public class AwsSesConfig {
@Value("${aws.ses.access-key}")
private String accessKey;
@Value("${aws.ses.secret-key}")
private String secretKey;
@Bean
public AmazonSimpleEmailService amazonSimpleEmailService() {
final BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKey, secretKey);
final AWSStaticCredentialsProvider awsStaticCredentialsProvider = new AWSStaticCredentialsProvider(
basicAWSCredentials);
return AmazonSimpleEmailServiceClientBuilder.standard()
.withCredentials(awsStaticCredentialsProvider)
.withRegion("ap-northeast-2")
.build();
}
}
Config 파일을 통해 AWS SES에 접근할 수 있게 권한 설정 및 리전 설정을 합니다.
@Getter
public class AwsSesDto {
public static final String FROM_EMAIL = "abc@velog.co.kr"; // 보내는 사람
private final List<String> to; // 받는 사람
private final String subject; // 제목
private final String content; // 본문
@Builder
public AwsSesDto(final List<String> to, final String subject,
final String content) {
this.to = to;
this.subject = subject;
this.content = content;
}
public SendEmailRequest toSendRequestDto() {
final Destination destination = new Destination()
.withToAddresses(this.to);
final Message message = new Message()
.withSubject(createContent(this.subject))
.withBody(new Body()
.withHtml(createContent(this.content)));
return new SendEmailRequest()
.withSource(FROM_EMAIL)
.withDestination(destination)
.withMessage(message);
}
private Content createContent(final String text) {
return new Content()
.withCharset("UTF-8")
.withData(text);
}
}
이메일 전용 DTO를 생성해서, 외부에서는 생성자를 통해 송신자, 수신자 리스트, 제목, 내용을 입력받고, AmazonawsService를 통해 메일을 보낼 때 필요한 정보가 담겨있는 객체인 SendEmailRequest를 반환합니다.
@Slf4j
@Service
@RequiredArgsConstructor
public class AwsSesService {
private final AmazonSimpleEmailService amazonSimpleEmailService;
private void send(final String subject, final String content, final List<String> receivers) {
try {
final AwsSesDto awsSesDto = AwsSesDto.builder()
.to(receivers)
.subject(subject)
.content(content)
.build();
final SendEmailResult sendEmailResult = amazonSimpleEmailService
.sendEmail(awsSesDto.toSendRequestDto());
System.out.println("Email sent!");
} catch (Exception e) {
System.out.println("Email Failed");
System.err.println("Error message: " + e.getMessage());
e.printStackTrace();
}
}
}
전달 받은 제목, 내용, 수신자를 생성자를 통해 AwsSesDto를 만들어줍니다.
AmazonSimpleEmailService에서 제공하는 sendEmail()을 호출하며 메일 발송을 시도 합니다.
public class AwsSesServiceFile {
@Autowired
private final AmazonSimpleEmailService amazonSimpleEmailService;
void fileSend() throws MessagingException {
final String SUBJECT = "제목";
final String SENDER = "보내는사람";
final String RECIPIENT = "받는사람";
final String BODY_TEXT = "내용";
final String BODY_HTML = "<h1>내용</h1>";
final String ATTACHMENT = "D:\\file\\test.png";
//final String CONFIGURATION_SET = "ConfigSet";
Session session = Session.getDefaultInstance(new Properties());
// Create a new MimeMessage object.
MimeMessage message = new MimeMessage(session);
// Add subject, from and to lines.
message.setSubject(SUBJECT, "UTF-8");
message.setFrom(new InternetAddress(SENDER));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(RECIPIENT));
// Create a multipart/alternative child container.
MimeMultipart msg_body = new MimeMultipart("alternative");
// Create a wrapper for the HTML and text parts.
MimeBodyPart wrap = new MimeBodyPart();
// Define the text part.
MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent(BODY_TEXT, "text/plain; charset=UTF-8");
// Define the HTML part.
MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(BODY_HTML,"text/html; charset=UTF-8");
// Add the text and HTML parts to the child container.
msg_body.addBodyPart(textPart);
msg_body.addBodyPart(htmlPart);
// Add the child container to the wrapper object.
wrap.setContent(msg_body);
// Create a multipart/mixed parent container.
MimeMultipart msg = new MimeMultipart("mixed");
// Add the parent container to the message.
message.setContent(msg);
// Add the multipart/alternative part to the message.
msg.addBodyPart(wrap);
// Define the attachment
MimeBodyPart att = new MimeBodyPart();
DataSource fds = new FileDataSource(ATTACHMENT);
att.setDataHandler(new DataHandler(fds));
att.setFileName(fds.getName());
// Add the attachment to the message.
msg.addBodyPart(att);
// Try to send the email.
try {
System.out.println("Attempting to send an email through Amazon SES "
+"using the AWS SDK for Java...");
// Print the raw email content on the console
PrintStream out = System.out;
message.writeTo(out);
// Send the email.
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
message.writeTo(outputStream);
RawMessage rawMessage =
new RawMessage(ByteBuffer.wrap(outputStream.toByteArray()));
SendRawEmailRequest rawEmailRequest =
new SendRawEmailRequest(rawMessage);
// .withConfigurationSetName(CONFIGURATION_SET);
amazonSimpleEmailService.sendRawEmail(rawEmailRequest);
System.out.println("Email sent!");
// Display an error if something goes wrong.
} catch (Exception ex) {
System.out.println("Email Failed");
System.err.println("Error message: " + ex.getMessage());
ex.printStackTrace();
}
}
}