본문 바로가기
Backend 개발자/AWS

Aws ses(Amazon SImple Email Service)를 이용한 Spring Boot Email 발송 기능 Java Source

by by 앵과장 2021. 9. 2.
반응형

안녕하세요
앵과장입니다.

오늘은 Aws ses를 이용해서 JAVA Springboot 기반 email 발송 기능을 만들어보겠습니다.
회사에서 진행하는 서비스플랫폼에서 사용할 기능을 개발하고 있는중입니다.
(ps 어라 왜 서비스플랫폼에 메일발송이 없는지 의아해 할수 있는데....좀 안타까운곳에 이직해서 멘탈깨지는중입니다)

라떼는 언제냐 KTH가 파란포탈을 만들어서 광고 할때 기억에 메일마다 2기가인가 4기가 준다니 너도나도 사람들이 파란포탈에서 제공하는 메일을쓰려고 가입하고 그랬던 기억이 있네요
그때 파란포탈 이메일 개발팀에 대략 4~5명정도 였고 PHP로 개발되어있었습니다. 그분들 그때 밤세고 장애처리하고 엄청 복잡했었는데 이제는 이렇게 AWS에서 제공하는 SES로 간단하게 사용이 가능합니다.


단계정리

1.AWS SES 설정 및 권한 설정
2.AWS에서 제공하는 언어별 샘플로 테스트코드 작성
3.이메일 템플릿 사용하기

 


아마존 서비스에서 ses 검색하시면 Amazon Simple Email Service 를 확인할수 있습니다. 클릭하세요

Amazon SES Dashboard 확인이 가능하며 sendbox 형태로 메일테스트 가능합니다.

amazon aws ses dashboard

Amazon SES계정 설정시 현재 리전에 위치와 sandbox 에 대한 부분 꼭 인지하셔야합니다.

 

Sanxbox 유형

설명 : Sandbox는 기본으로 제공하는 메일발송 유형

전송제한 : 24시간당 200개 이메일까지 가능하며 1초당 1개 이메일 전송만 가능합니다.

 

Sendbox 보다 많은 양을 사용하기 위해서는 해제 하셔야합니다.

해당내용 비용이 발생할수 있으며 클릭하고 들어가면 아래 정보 확인이 가능합니다.

번역해보면 아래 내용이기 때문에 기입하시고 submit request 하시면됩니다.

 

 

 

Amazon SES API

사용하기 위해서 identities 를 생성해야합니다.

선행조건으로 메일 발송을 위해서는 권한을 획득한 도메인, 이메일만 가능합니다.

 

Create identity 클릭

Domain 또는 Email address 를 선택후 생성

 

생성된 메일 활성화 및 access-key, secret-key 다운로드 

 

 

 

Springboot JAVA 기반

Email Source Sample

 

build.gradle

compile group: 'com.amazonaws', name: 'aws-java-sdk-ses', version: '1.11.847'   //aws ses

 

application.yml

아래 value는 테스트로 넣은정보이기 때문에 Aws ses에서 참고하여 넣어주시기 바랍니다.

aws:
  ses:
    credentials:
      access-key: QBBECLARSEHTDFSGJ3HR
      secret-key: Z0utfj9vTvYxoA7R47n3bFiv1pZz993yOEoSPaSf
    veritied:
      email: renzo@email.com
      
mail:
  recipient: a@email.com,b@email.com,c@email.com
  dummy: dummyA@email.com,dummyB@email.com,dummyC@email.com

aws ses enable configuration

package com.renzo.config;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AwsSesConfig{

    @Value("${aws.ses.credentials.access-key}")
    private String accessKey;

    @Value("${aws.ses.credentials.secret-key}")
    private String secretKey;

    @Bean
    public AmazonSimpleEmailService amazonSimpleEmailService() {
        BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKey, secretKey);
        AWSStaticCredentialsProvider awsStaticCredentialsProvider = new AWSStaticCredentialsProvider(basicAWSCredentials);
        System.out.println(accessKey);
        System.out.println();
        return AmazonSimpleEmailServiceClientBuilder.standard()
                .withCredentials(awsStaticCredentialsProvider)
                .withRegion("ap-northeast-2") // 인증받은 리전에서 수행해야한다. 등록한 리전이 endpoint 가 됨 => https://email.AP_NORTHEAST_2.amazonaws.com,
                .build();
    }
}

메일 DTO

package com.renzo.domain;

import com.amazonaws.services.simpleemail.model.*;
import lombok.Builder;
import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

@Getter
public class SenderDto {
    private String from;
    private List<String> to = new ArrayList<>();
    private String subject;
    private String content;


    @Builder
    public SenderDto(String from, List<String> to, String subject, String content) {
        this.from = from;
        this.to = to;
        this.subject = subject;
        this.content = content;
    }

    public SendEmailRequest toSendRequestDto() {
        Destination destination = new Destination()
                .withToAddresses(this.to);

        Message message = new Message()
                .withSubject(createContent(this.subject))
                .withBody(new Body().withHtml(createContent(this.content)));

        return new SendEmailRequest()
                .withSource(this.from)
                .withDestination(destination)
                .withMessage(message);
    }

    private Content createContent(String text) {
        return new Content()
                .withCharset("UTF-8")
                .withData(text);
    }
}

메일발송 Sender

package com.renzo.service

import com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
import com.amazonaws.services.simpleemail.model.SendEmailResult;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.renzo.domain.SenderDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.util.List;

@Slf4j
@Component
@RequiredArgsConstructor
public class Sender {
    private final AmazonSimpleEmailService amazonSimpleEmailService;

    @Value("${aws.ses.veritied.email}")
    private String from;

    /**
     * 이메일 전송
     */
    public void send(String subject, String content, List<String> receivers) {
        if(receivers.size() == 0) {
            return;
        }

        SenderDto senderDto = SenderDto.builder()
                .from(from)
                .to(receivers)
                .subject(subject)
                .content(content)
                .build();

        SendEmailResult sendEmailResult = amazonSimpleEmailService.sendEmail(senderDto.toSendRequestDto());

        if(sendEmailResult.getSdkHttpMetadata().getHttpStatusCode() == 200) {
            log.info("[AWS SES] 메일전송완료 => " + senderDto.getTo());
        }else {
            log.error("[AWS SES] 메일전송 중 에러가 발생했습니다: {}", sendEmailResult.getSdkResponseMetadata().toString());
            log.error("발송실패 대상자: " + senderDto.getTo() + " / subject: " + senderDto.getSubject());
        }
    }

    public static String getHtmlContent(String path)throws IOException{
        return Files.toString(new File(path), Charsets.UTF_8);
    }



}

메일발송 Service

@Autowired
private Sender sender;

@Value("${mail.dummy}")
private List<String> mailRecipients;

public void sendRevenueAggregationMail(){
        List<String> to = new ArrayList();
        for (String item: mailRecipients) {
            to.add(item);
        }

        String subject = "[매출 집계] 일별 매출 실적 현황 (".concat(CURRENT_DAY).concat(")");

        StringBuilder html = new StringBuilder();
        html.append("<!DOCTYPE html>\n" +
                "<html lang=\"en\" xmlns:th=\"http://www.w3.org/1999/xhtml\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <title>메일 발송</title>\n" +
                "</head>\n" +
                "<body>\n" +
                "<h1>일매출</h1>\n" +
                "<div>\n" +
                "    <span>매출 엑셀 링크 : <a href='https://domain/aggregation/download/excel'>다운로드</a></span>\n" +
                "    <br/>\n" +
                "    <br/>\n" +
                "    <span>"+CURRENT_DAY+" 매출 공유드립니다.</span>\n" +
                "    <br/>\n" +
                "    <span>항상 감사드립니다.</span>\n" +
                "</div>\n" +
                "</body>\n" +
                "</html>");

        sender.send(subject, html.toString(), to);

    }

 

 

메일발송 Controller

package com.renzo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MailController {
    
    @Autowired
    private MailService mailService;
    
    @GetMapping("/sendmail")
    public void sendMail(){
        mailService.sendRevenueAggregationMail();
    }
}