-
Notifications
You must be signed in to change notification settings - Fork 0
[refactor] 이메일 발송 비동기식으로 전환 #91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
974bd32
refactor: 이메일 전송 비동기 처리 (DASOMBE-13)
hodoon 75608bf
refactor: 이메일 전송 오류시 로그 저장 DB생성, 이메일 템플릿 분기처리 (DASOMBE-13)
hodoon 937e5f5
refactor: 이메일 로그 builder 패턴으로 인스턴스 초기화 완료 (DASOMBE-13)
hodoon 51fd724
refactor: 성공여부도 저장 가능하게 수정 (DASOMBE-13)
hodoon 5562c21
refactor: 빌더 패턴 EmailLog엔티티 안으로 이동, 에러메시지 저장 로직 try-catch문 밖으로 이동 (DA…
hodoon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
src/main/java/dmu/dasom/api/domain/google/entity/EmailLog.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| package dmu.dasom.api.domain.google.entity; | ||
|
|
||
| import dmu.dasom.api.domain.google.enums.MailSendStatus; | ||
| import jakarta.persistence.*; | ||
| import lombok.*; | ||
| import org.hibernate.annotations.CreationTimestamp; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| @Entity | ||
| @Getter | ||
| @Builder | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| @AllArgsConstructor | ||
| public class EmailLog { | ||
|
|
||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| private Long id; | ||
|
|
||
| @Column(nullable = false) | ||
| private String recipientEmail; | ||
|
|
||
| @Enumerated(EnumType.STRING) | ||
| @Column(nullable = false) | ||
| private MailSendStatus status; | ||
|
|
||
| private String errorMessage; | ||
|
|
||
| @CreationTimestamp | ||
| private LocalDateTime sentAt; | ||
| } |
6 changes: 6 additions & 0 deletions
6
src/main/java/dmu/dasom/api/domain/google/enums/MailSendStatus.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| package dmu.dasom.api.domain.google.enums; | ||
|
|
||
| public enum MailSendStatus { | ||
| SUCCESS, | ||
| FAILURE | ||
| } |
26 changes: 26 additions & 0 deletions
26
src/main/java/dmu/dasom/api/domain/google/enums/MailTemplate.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package dmu.dasom.api.domain.google.enums; | ||
|
|
||
| import dmu.dasom.api.domain.common.exception.CustomException; | ||
| import dmu.dasom.api.domain.common.exception.ErrorCode; | ||
| import lombok.Getter; | ||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| import java.util.Arrays; | ||
|
|
||
| @Getter | ||
| @RequiredArgsConstructor | ||
| public enum MailTemplate { | ||
| DOCUMENT_RESULT(MailType.DOCUMENT_RESULT, "동양미래대학교 컴퓨터소프트웨어공학과 전공 동아리 DASOM 서류 결과 안내", "document-result-email"), | ||
| FINAL_RESULT(MailType.FINAL_RESULT, "동양미래대학교 컴퓨터소프트웨어공학과 전공 동아리 DASOM 최종 면접 결과 안내", "final-result-email"); | ||
|
|
||
| private final MailType mailType; | ||
| private final String subject; | ||
| private final String templateName; | ||
|
|
||
| public static MailTemplate getMailType(MailType mailType) { | ||
| return Arrays.stream(values()) | ||
| .filter(template -> template.getMailType() == mailType) | ||
| .findFirst() | ||
| .orElseThrow(() -> new CustomException(ErrorCode.MAIL_TYPE_NOT_VALID)); | ||
| } | ||
| } |
7 changes: 7 additions & 0 deletions
7
src/main/java/dmu/dasom/api/domain/google/repository/EmailLogRepository.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package dmu.dasom.api.domain.google.repository; | ||
|
|
||
| import dmu.dasom.api.domain.google.entity.EmailLog; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
|
|
||
| public interface EmailLogRepository extends JpaRepository<EmailLog, Long> { | ||
| } |
25 changes: 25 additions & 0 deletions
25
src/main/java/dmu/dasom/api/domain/google/service/EmailLogService.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| package dmu.dasom.api.domain.google.service; | ||
|
|
||
| import dmu.dasom.api.domain.google.entity.EmailLog; | ||
| import dmu.dasom.api.domain.google.enums.MailSendStatus; | ||
| import dmu.dasom.api.domain.google.repository.EmailLogRepository; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.scheduling.annotation.Async; | ||
| import org.springframework.stereotype.Service; | ||
|
|
||
| @Service | ||
| @RequiredArgsConstructor | ||
| public class EmailLogService { | ||
|
|
||
| private final EmailLogRepository emailLogRepository; | ||
|
|
||
| @Async | ||
| public void logEmailSending(String recipientEmail, MailSendStatus status, String errorMessage) { | ||
| EmailLog emailLog = EmailLog.builder() | ||
| .recipientEmail(recipientEmail) | ||
| .status(status) | ||
| .errorMessage(errorMessage) | ||
| .build(); | ||
| emailLogRepository.save(emailLog); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,79 +2,74 @@ | |
|
|
||
| import dmu.dasom.api.domain.common.exception.CustomException; | ||
| import dmu.dasom.api.domain.common.exception.ErrorCode; | ||
| import dmu.dasom.api.domain.google.enums.MailSendStatus; | ||
| import dmu.dasom.api.domain.google.enums.MailTemplate; | ||
| import dmu.dasom.api.domain.google.enums.MailType; | ||
| import jakarta.mail.MessagingException; | ||
| import jakarta.mail.internet.MimeMessage; | ||
| import lombok.RequiredArgsConstructor; | ||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.springframework.beans.factory.annotation.Value; | ||
| import org.springframework.mail.javamail.JavaMailSender; | ||
| import org.springframework.mail.javamail.MimeMessageHelper; | ||
| import org.springframework.scheduling.annotation.Async; | ||
| import org.springframework.stereotype.Service; | ||
| import org.thymeleaf.TemplateEngine; | ||
| import org.thymeleaf.context.Context; | ||
|
|
||
| @Slf4j | ||
| @RequiredArgsConstructor | ||
| @Service | ||
| public class EmailService { | ||
|
|
||
| private final TemplateEngine templateEngine; | ||
| private final JavaMailSender javaMailSender; | ||
| private final EmailLogService emailLogService; | ||
|
|
||
| @Value("${spring.mail.username}") | ||
| private String from; | ||
|
|
||
| public void sendEmail(String to, String name, MailType mailType) throws MessagingException { | ||
| if (mailType == null){ | ||
| throw new CustomException(ErrorCode.MAIL_TYPE_NOT_VALID); | ||
| } | ||
| @Async | ||
| public void sendEmail(String to, String name, MailType mailType) { | ||
| try { | ||
| if (mailType == null) { | ||
| throw new CustomException(ErrorCode.MAIL_TYPE_NOT_VALID); | ||
| } | ||
|
|
||
| // 메일 제목 및 템플릿 설정 | ||
| String subject; | ||
| String emailContent; | ||
| String buttonUrl = "https://dmu-dasom.or.kr/recruit/result"; | ||
| String buttonText; | ||
| // 메일 템플릿 조회 | ||
| MailTemplate mailTemplate = MailTemplate.getMailType(mailType); | ||
| String buttonUrl = "https://dmu-dasom.or.kr/recruit/result"; | ||
|
|
||
| switch (mailType) { | ||
| case DOCUMENT_RESULT -> { | ||
| subject = "동양미래대학교 컴퓨터소프트웨어공학과 전공 동아리 DASOM 서류 결과 안내"; | ||
| emailContent = "먼저 다솜 34기에 많은 관심을 두고 지원해 주셔서 감사드리며,<br>" + | ||
| "내부 서류 평가 결과 및 추후 일정에 관해 안내해드리고자 이메일을 발송하게 되었습니다.<br>" + | ||
| "서류 전형 결과는 아래 버튼 혹은 홈페이지를 통해 확인이 가능합니다."; | ||
| buttonText = "서류 결과 확인하기"; | ||
| } | ||
| case FINAL_RESULT -> { | ||
| subject = "동양미래대학교 컴퓨터소프트웨어공학과 전공 동아리 DASOM 최종 면접 결과 안내"; | ||
| emailContent = "먼저 다솜 34기에 많은 관심을 두고 지원해 주셔서 감사드리며,<br>" + | ||
| "최종 면접 결과 및 추후 일정에 관해 안내해드리고자 이메일을 발송하게 되었습니다.<br>" + | ||
| "최종 면접 결과는 아래 버튼 혹은 홈페이지를 통해 확인이 가능합니다."; | ||
| buttonText = "최종 결과 확인하기"; | ||
| } | ||
| default -> throw new IllegalStateException("Unexpected value: " + mailType); | ||
| } | ||
| // HTML 템플릿에 전달할 데이터 설정 | ||
| Context context = new Context(); | ||
| context.setVariable("name", name); // 지원자 이름 전달 | ||
| context.setVariable("buttonUrl", buttonUrl); // 버튼 링크 전달 | ||
|
|
||
| // HTML 템플릿에 전달할 데이터 설정 | ||
| Context context = new Context(); | ||
| context.setVariable("name", name); // 지원자 이름 전달 | ||
| context.setVariable("emailContent", emailContent); // 이메일 내용 전달 | ||
| context.setVariable("buttonUrl", buttonUrl); // 버튼 링크 전달 | ||
| context.setVariable("buttonText", buttonText); | ||
|
|
||
| // HTML 템플릿 처리 | ||
| String htmlBody = templateEngine.process("email-template", context); | ||
| // HTML 템플릿 처리 | ||
| String htmlBody = templateEngine.process(mailTemplate.getTemplateName(), context); | ||
|
|
||
| // 이메일 생성 및 전송 | ||
| MimeMessage message = javaMailSender.createMimeMessage(); | ||
| MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); | ||
| // 이메일 생성 및 전송 | ||
| MimeMessage message = javaMailSender.createMimeMessage(); | ||
| MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); | ||
|
|
||
| helper.setTo(to); | ||
| helper.setSubject(subject); | ||
| helper.setText(htmlBody, true); | ||
| helper.setFrom((from != null && !from.isEmpty()) ? from : "[email protected]"); | ||
| helper.setTo(to); | ||
| helper.setSubject(mailTemplate.getSubject()); | ||
| helper.setText(htmlBody, true); | ||
| helper.setFrom((from != null && !from.isEmpty()) ? from : "[email protected]"); | ||
|
|
||
| // Content-Type을 명시적으로 설정 | ||
| message.setContent(htmlBody, "text/html; charset=utf-8"); | ||
| // Content-Type을 명시적으로 설정 | ||
| message.setContent(htmlBody, "text/html; charset=utf-8"); | ||
|
|
||
| javaMailSender.send(message); | ||
| javaMailSender.send(message); | ||
| log.info("Email sent successfull {}", to); | ||
| emailLogService.logEmailSending(to, MailSendStatus.SUCCESS, null); | ||
| } catch (MessagingException e) { | ||
| log.error("Failed to send email to {}: {}", to, e.getMessage()); | ||
| emailLogService.logEmailSending(to, MailSendStatus.FAILURE, e.getMessage()); | ||
| } catch (CustomException e) { | ||
| log.error("Email sending error for {}: {}", to, e.getMessage()); | ||
| emailLogService.logEmailSending(to, MailSendStatus.FAILURE, e.getMessage()); | ||
| } | ||
| } | ||
|
|
||
| } | ||
122 changes: 122 additions & 0 deletions
122
src/main/resources/templates/document-result-email.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="ko"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <meta name="color-scheme" content="light dark"> | ||
| <meta name="supported-color-schemes" content="light dark"> | ||
| <title>이메일 안내</title> | ||
| </head> | ||
| <body style=" | ||
| background-color: #17171B; | ||
| color: white !important; | ||
| font-family: 'Pretendard', sans-serif; | ||
| display: flex; | ||
| justify-content: center; | ||
| align-items: center; | ||
| height: 100vh; | ||
| margin: 0;"> | ||
| <div style=" | ||
| width: 740px; | ||
| height: 680px; | ||
| background: #17171B; | ||
| padding: 30px; | ||
| position: relative;"> | ||
| <div style=" | ||
| display: flex; | ||
| justify-content: center; | ||
| position: relative; | ||
| margin-bottom: 20px;"> | ||
| <div style=" | ||
| width: 100%; | ||
| display: flex; | ||
| justify-content: space-between; | ||
| align-items: center;"> | ||
| <div style=" | ||
| flex: 1; | ||
| border-top: 1px solid #00B493; | ||
| margin: 0 10px;"> | ||
|
|
||
| </div> | ||
| <img src="https://dmu-dasom.or.kr/static/media/dasomLogo.c82d220d8093c3cb8d7fc0b148cafcd1.svg" alt="로고" style=" | ||
| width: 21px; | ||
| height: 24px; | ||
| border-radius: 3px;"> | ||
| <div style=" | ||
| flex: 1; | ||
| border-top: 1px solid #00B493; | ||
| margin: 0 10px;"> | ||
| </div> | ||
| </div> | ||
| </div> | ||
|
|
||
| <div style=" | ||
| font-size: 48px; | ||
| font-weight: 900; | ||
| color: #00B493; | ||
| margin-bottom: 30px;"> | ||
| DASOM | ||
| </div> | ||
| <div style=" | ||
| font-size: 20px; | ||
| font-weight: 600; | ||
| margin-bottom: 5px; | ||
| color: white !important;" | ||
| th:text="${name} + '님 안녕하세요.'"> | ||
| </div> | ||
| <div style=" | ||
| font-size: 20px; | ||
| font-weight: 600; | ||
| margin-bottom: 5px; | ||
| color: white !important;"> | ||
| 컴퓨터공학부 전공동아리 다솜입니다. | ||
| </div> | ||
|
|
||
| <div style=" | ||
| font-size: 16px; | ||
| font-weight: 400; | ||
| line-height: 2.5; | ||
| text-align: right; | ||
| margin-bottom: 40px; | ||
| color: white !important;"> | ||
| 먼저 다솜 35기에 많은 관심을 두고 지원해 주셔서 감사드리며,<br> | ||
| 내부 서류 평가 결과 및 추후 일정에 관해 안내해드리고자 이메일을 발송하게 되었습니다.<br> | ||
| 서류 전형 결과는 아래 버튼 혹은 홈페이지를 통해 확인이 가능합니다. | ||
| </div> | ||
|
|
||
| <div style="display: flex; | ||
| justify-content: flex-end; | ||
| margin-bottom: 40px;"> | ||
| <a th:href="${buttonUrl}" | ||
| style=" | ||
| background: #00B493; | ||
| color: white !important; | ||
| font-size: 16px; | ||
| font-weight: 400; | ||
| padding: 10px 20px; | ||
| border-radius: 5px; | ||
| display: flex; | ||
| align-items: center; | ||
| text-decoration: none;"> | ||
| <span>서류 결과 확인하기</span> | ||
| <span style=" | ||
| border: solid white; | ||
| border-width: 0 2px 2px 0; | ||
| display: inline-block; | ||
| padding: 5px; | ||
| transform: rotate(-45deg); | ||
| margin-left: 10px;"> | ||
| </span> | ||
| </a> | ||
| </div> | ||
|
|
||
| <div style="font-size: 16px; | ||
| font-weight: 400; | ||
| line-height: 1.5; | ||
| color: white !important;"> | ||
| 또한, 문의 사항은 본 메일에 회신 또는 아래 번호로 편하게 연락 부탁드립니다.<br> | ||
| 010-6361-3481 | ||
| </div> | ||
| </div> | ||
| </body> | ||
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.