SES SMTP 사용

최준호·2022년 9월 5일
0

AWS

목록 보기
9/10
post-thumbnail

👏 AWS SES SMTP 사용하기

이전에 AWS SES(Simple Email Service) Java 사용법을 통해 AWS의 SES를 Spring에서 적용시켜 보았다. 이번엔 SMTP 서버를 이용하여 메일을 전송해보려고 한다.

📗 SES SMTP 환경 만들기

📄 AWS 설정하기

SES에서 SMTP settings -> Create SMTP credentials 순서로 클릭한다. 그 후 SMTP credentials를 생성해준다.

그럼 다음과 같이 새로운 access-id와 secret-key를 발급받을 수 있다.

요청할 SMTP host와 port의 정보는 다음에 적혀있다.

📄 테스트

해당 내용의 코드를 진행하기 위해서는 javax.mail의 의존성 추가가 필요합니다.

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-mail:2.7.3'
}
public class SesServiceTest {

    ...

    @Test
    @DisplayName("java mail로 전송에 성공한다.")
    void javaMailSend() throws UnsupportedEncodingException, MessagingException {
        // Replace sender@example.com with your "From" address.
        // This address must be verified.
        final String FROM = "{보내는 email}";
        final String FROMNAME = "{보내는 email 별명}";

        // Replace recipient@example.com with a "To" address. If your account
        // is still in the sandbox, this address must be verified.
        final String TO = "{받을 email}";

        // Replace smtp_username with your Amazon SES SMTP user name.
        final String SMTP_USERNAME = "{SMTP user name}";

        // Replace smtp_password with your Amazon SES SMTP password.
        final String SMTP_PASSWORD = "{SMTP password}";

        // 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.
        final String CONFIGSET = "ConfigSet";

        // Amazon SES SMTP host name. This example uses the US West (Oregon) region.
        // See https://docs.aws.amazon.com/ses/latest/DeveloperGuide/regions.html#region-endpoints
        // for more information.AP_NORTHEAST_2
        final String HOST = "email-smtp.ap-northeast-2.amazonaws.com";

        // The port you will connect to on the Amazon SES SMTP endpoint.
        final int PORT = 587;

        final String SUBJECT = "Amazon SES test (SMTP interface accessed using Java)";

        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>."
        );

        // 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, StandardCharsets.UTF_8.name());
        msg.setText(BODY, StandardCharsets.UTF_8.name(), "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());
            fail();
        }
        finally
        {
            // Close and terminate the connection.
            transport.close();
        }
    }
}

AWS 공식 홈페이지의 코드를 참고하여 테스트 코드를 작성하였다. 이렇게 만들어서 코드를 실행시키면

정상 실행되었고

html도 정상적으로 적용되었고 보낸 사람의 별명도 정상적으로 적용되어진 것을 확인할 수 있다.

📗 사용할 수 있는 코드로 리팩토링

테스트 코드로는 작성해서 테스트를 해봤으니 이제 공통적으로 사용할 코드를 분리해보자.

📄 공통 처리 부분으로 만들기

aws:
  ses:
    host: {smtp region}
    port: {smtp port}
    access-id: {smtp username}
    secret-key: {smtp password}
@Slf4j
@RequiredArgsConstructor
public class Sender {
    private final Environment env;

    public boolean send(String from, String fromName, String to, String subject, String content){
        log.info("Sender send() start ...");
        String host = env.getProperty("aws.ses.host");
        String port = env.getProperty("aws.ses.port");
        String userName = env.getProperty("aws.ses.access-id");
        String password = env.getProperty("aws.ses.secret-key");

        Properties props = System.getProperties();
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.port", Integer.parseInt(port));
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.auth", "true");

        Session session = Session.getDefaultInstance(props);

        MimeMessage msg = new MimeMessage(session);
        try {
            msg.setFrom(new InternetAddress(from, fromName));
            msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
            msg.setSubject(subject, StandardCharsets.UTF_8.name());
            msg.setText(content, StandardCharsets.UTF_8.name(), "html");
            //메일 전송
            log.info("mail send start ...");
            Transport transport = session.getTransport();
            transport.connect(host, userName, password);
            transport.sendMessage(msg, msg.getAllRecipients());
            log.info("mail send complete ...");
        } catch (UnsupportedEncodingException e) {
            // InternetAddress 만들 때 Exception
            e.printStackTrace();
            return false;
        } catch (MessagingException e) {
            // setForm 할 때 Exception
            e.printStackTrace();
            return false;
        }
        return true;
    }
}

다음과 같이 작성하고

@SpringBootTest
public class SesServiceTest {
    @Autowired
    private Environment env;

    @Test
    @DisplayName("SMTP 메일 전송에 성공한다.")
    void smtpSend(){
        // given
        Sender sender = new Sender(env);

        // when
        boolean result =
                sender.send("{보낼 메일}", "{보낼 메일 별명}", "{받을 메일 List}", "{메일 제목}", "{메일 내용}");
        //then
        assertTrue(result);
    }
}

테스트를 진행하면 정상적으로 메일을 받아볼 수 있다!

profile
코딩을 깔끔하게 하고 싶어하는 초보 개발자 (편하게 글을 쓰기위해 반말체를 사용하고 있습니다! 양해 부탁드려요!) 현재 KakaoVX 근무중입니다!

0개의 댓글