From 8c3dac25ec1c01662d67063915d64f91e3048240 Mon Sep 17 00:00:00 2001 From: chahyunsoo Date: Sat, 17 Aug 2024 03:41:42 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[feat]=20=EC=98=A8=EB=B3=B4=EB=94=A9=20?= =?UTF-8?q?=EC=8B=A4=ED=8C=A8=20=EC=8B=9C=20=EB=AC=B8=EC=9D=98=20=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=20api=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/OnBoardingController.java | 9 +++- .../user/service/OnBoardingService.java | 27 ++++++++++ .../dto/request/OnBoardingEmailRequest.java | 16 ++++++ .../OnBoardingMessagingException.java | 11 +++++ .../homepage/global/config/MailConfig.java | 49 +++++++++++++++++++ .../global/error/status/ErrorStatus.java | 1 + 6 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ussum/homepage/application/user/service/dto/request/OnBoardingEmailRequest.java create mode 100644 src/main/java/ussum/homepage/domain/user/exception/OnBoardingMessagingException.java create mode 100644 src/main/java/ussum/homepage/global/config/MailConfig.java diff --git a/src/main/java/ussum/homepage/application/user/controller/OnBoardingController.java b/src/main/java/ussum/homepage/application/user/controller/OnBoardingController.java index 47d94e86..8a48eaee 100644 --- a/src/main/java/ussum/homepage/application/user/controller/OnBoardingController.java +++ b/src/main/java/ussum/homepage/application/user/controller/OnBoardingController.java @@ -5,6 +5,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import ussum.homepage.application.user.service.OnBoardingService; +import ussum.homepage.application.user.service.dto.request.OnBoardingEmailRequest; import ussum.homepage.application.user.service.dto.request.OnBoardingRequest; import ussum.homepage.application.user.service.dto.request.UserRequest; import ussum.homepage.application.user.service.dto.response.UserResponse; @@ -19,9 +20,15 @@ public class OnBoardingController { @PostMapping("/academy-information") public ResponseEntity> createUserOnBoarding(@UserId Long userId, - @RequestBody OnBoardingRequest request){ + @RequestBody OnBoardingRequest request) { onBoardingService.saveUserOnBoarding(userId, request); return ApiResponse.success(null); } + @PostMapping("/mail") + public ResponseEntity> sendEmail(@RequestBody OnBoardingEmailRequest onBoardingEmailRequest) { + onBoardingService.sendEmail(onBoardingEmailRequest); + return ApiResponse.success(null); + } + } diff --git a/src/main/java/ussum/homepage/application/user/service/OnBoardingService.java b/src/main/java/ussum/homepage/application/user/service/OnBoardingService.java index e63e4137..6b6bdf6c 100644 --- a/src/main/java/ussum/homepage/application/user/service/OnBoardingService.java +++ b/src/main/java/ussum/homepage/application/user/service/OnBoardingService.java @@ -1,16 +1,24 @@ package ussum.homepage.application.user.service; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import ussum.homepage.application.user.service.dto.request.OnBoardingEmailRequest; import ussum.homepage.application.user.service.dto.request.OnBoardingRequest; import ussum.homepage.domain.csv_user.StudentCsv; import ussum.homepage.domain.csv_user.service.StudentCsvReader; import ussum.homepage.domain.user.User; +import ussum.homepage.domain.user.exception.OnBoardingMessagingException; import ussum.homepage.domain.user.service.UserModifier; import ussum.homepage.domain.user.service.UserReader; import ussum.homepage.global.error.exception.GeneralException; +import static ussum.homepage.global.error.status.ErrorStatus.ONBOARDING_FAIL_MAIL_ERROR; import static ussum.homepage.global.error.status.ErrorStatus.USER_NOT_FOUND; @Service @@ -20,6 +28,10 @@ public class OnBoardingService { private final UserModifier userModifier; private final UserReader userReader; private final StudentCsvReader studentCsvReader; + private final JavaMailSender javaMailSender; + + @Value("${spring.mail.username}") + private String SENDER_EMAIL_ADDRESS; public void saveUserOnBoarding(Long userId, OnBoardingRequest request){ User user = userReader.getUserWithId(userId); @@ -33,4 +45,19 @@ public void saveUserOnBoarding(Long userId, OnBoardingRequest request){ user.updateOnBoardingUser(request); // 이 메소드 수정 필요 userModifier.save(user); } + + public void sendEmail(OnBoardingEmailRequest onBoardingEmailRequest) { + try { + MimeMessage mimeMessage = javaMailSender.createMimeMessage(); + MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage); + mimeMessageHelper.setTo(SENDER_EMAIL_ADDRESS); + mimeMessageHelper.setFrom(onBoardingEmailRequest.email()); + mimeMessageHelper.setSubject(onBoardingEmailRequest.toString(onBoardingEmailRequest)); + mimeMessageHelper.setText(onBoardingEmailRequest.content()); + + javaMailSender.send(mimeMessage); + } catch (MessagingException | OnBoardingMessagingException onBoardingMessagingException) { + throw new OnBoardingMessagingException(ONBOARDING_FAIL_MAIL_ERROR); + } + } } \ No newline at end of file diff --git a/src/main/java/ussum/homepage/application/user/service/dto/request/OnBoardingEmailRequest.java b/src/main/java/ussum/homepage/application/user/service/dto/request/OnBoardingEmailRequest.java new file mode 100644 index 00000000..4b485c06 --- /dev/null +++ b/src/main/java/ussum/homepage/application/user/service/dto/request/OnBoardingEmailRequest.java @@ -0,0 +1,16 @@ +package ussum.homepage.application.user.service.dto.request; + + +public record OnBoardingEmailRequest( + String name, + Long studentId, + String email, + String content +) { + public String toString(OnBoardingEmailRequest onBoardingEmailRequest) { + return onBoardingEmailRequest.studentId + "학번과 " + + onBoardingEmailRequest.email + " 라는 이메일을 가진 " + + onBoardingEmailRequest.name + "님이 " + + "메일을 보냈습니다."; + } +} diff --git a/src/main/java/ussum/homepage/domain/user/exception/OnBoardingMessagingException.java b/src/main/java/ussum/homepage/domain/user/exception/OnBoardingMessagingException.java new file mode 100644 index 00000000..d9836208 --- /dev/null +++ b/src/main/java/ussum/homepage/domain/user/exception/OnBoardingMessagingException.java @@ -0,0 +1,11 @@ +package ussum.homepage.domain.user.exception; + +import ussum.homepage.global.error.code.BaseErrorCode; +import ussum.homepage.global.error.exception.GeneralException; + +public class OnBoardingMessagingException extends GeneralException { + private BaseErrorCode baseErrorCode; + public OnBoardingMessagingException(BaseErrorCode baseErrorCode) { + super(baseErrorCode); + } +} diff --git a/src/main/java/ussum/homepage/global/config/MailConfig.java b/src/main/java/ussum/homepage/global/config/MailConfig.java new file mode 100644 index 00000000..fb64a6f4 --- /dev/null +++ b/src/main/java/ussum/homepage/global/config/MailConfig.java @@ -0,0 +1,49 @@ +package ussum.homepage.global.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; + +import java.util.Properties; + +@Configuration +public class MailConfig { + @Value("${spring.mail.host}") + private String MAIL_HOST; + + @Value("${spring.mail.username}") + private String MAIL_ADDRESS; + + @Value("${spring.mail.password}") + private String MAIL_PASSWORD; + + @Bean + public JavaMailSender javaMailService() { + JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); + + // SMTP 서버 주소를 'smtp.gmail.com'으로 변경 + javaMailSender.setHost(MAIL_HOST); + javaMailSender.setUsername(MAIL_ADDRESS); // 사용자 이메일 주소 + javaMailSender.setPassword(MAIL_PASSWORD); // 앱 비밀번호 또는 사용자 비밀번호 + + // TLS를 사용하는 587 포트 설정 + javaMailSender.setPort(587); + javaMailSender.setJavaMailProperties(getMailProperties()); + + return javaMailSender; + } + + private Properties getMailProperties() { + Properties properties = new Properties(); + properties.setProperty("mail.transport.protocol", "smtp"); + properties.setProperty("mail.smtp.auth", "true"); + properties.setProperty("mail.smtp.starttls.enable", "true"); // TLS 활성화 + properties.setProperty("mail.debug", "true"); + + // 'smtp.gmail.com'으로 변경 + properties.setProperty("mail.smtp.ssl.trust", "smtp.gmail.com"); + return properties; + } +} diff --git a/src/main/java/ussum/homepage/global/error/status/ErrorStatus.java b/src/main/java/ussum/homepage/global/error/status/ErrorStatus.java index 8b3049db..10dfc443 100644 --- a/src/main/java/ussum/homepage/global/error/status/ErrorStatus.java +++ b/src/main/java/ussum/homepage/global/error/status/ErrorStatus.java @@ -88,6 +88,7 @@ public enum ErrorStatus implements BaseErrorCode { //온보딩에러 INVALID_ONBOARDING_REQUEST(HttpStatus.BAD_REQUEST,"ONBOARDING_001","온보딩 정보가 올바르지 않습니다."), + ONBOARDING_FAIL_MAIL_ERROR(HttpStatus.BAD_REQUEST, "ONBOARDING_002","메일이 정상적으로 보내지지 않았습니다."), //S3에러 S3_ERROR(HttpStatus.INTERNAL_SERVER_ERROR,"S3_001","S3에 파일 저장이 실패했습니다."), From e0adf3ab900f754984ef097385268f1198bb4bab Mon Sep 17 00:00:00 2001 From: chahyunsoo Date: Sat, 17 Aug 2024 03:48:33 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[chore]=20mail=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=A3=BC=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index 003bc515..e1e09a47 100644 --- a/build.gradle +++ b/build.gradle @@ -65,6 +65,9 @@ dependencies { //swagger implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2' + //mail + implementation 'org.springframework.boot:spring-boot-starter-mail' + testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test'