From d24c156c023ac2b626a3bbabd298cc79224d9f39 Mon Sep 17 00:00:00 2001 From: jjaegii Date: Sun, 6 Oct 2024 22:15:39 +0900 Subject: [PATCH 1/9] =?UTF-8?q?release(application.properties):=20release?= =?UTF-8?q?=EC=9A=A9=20url=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 39b01a86..1e7cb68d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -21,7 +21,7 @@ oauth2.client.provider.google.token-uri=https://oauth2.googleapis.com/token oauth2.client.provider.google.user-info-uri=https://www.googleapis.com/oauth2/v1/userinfo jwt.access.secret-key=${JWT_ACCESS_SECRET_KEY} jwt.access.expiration=1800000 -client.login-success-redirect-uri=http://localhost:3000/main +client.login-success-redirect-uri=https://grassdiary.site/main # aws-s3-config cloud.aws.credentials.accessKey=${S3_ACCESS_PUBLIC_KEY} From 8a3d434e9de2297ecc1a5e86914f742f87bc3f74 Mon Sep 17 00:00:00 2001 From: HongYeseul Date: Tue, 29 Oct 2024 23:50:25 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat(email):=20=EC=9D=B4=EB=A9=94=EC=9D=BC?= =?UTF-8?q?=20=EB=B3=B4=EB=82=B4=EA=B8=B0=20=EC=9C=84=ED=95=9C=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.properties | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1e7cb68d..cbdae857 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -40,3 +40,12 @@ cloud.aws.stack.auto=false # persistence context of JPA remains open until the HTTP request is completed spring.jpa.open-in-view=false + +# email +spring.mail.host=smtp.gmail.com +spring.mail.port=587 +spring.mail.username=${MAIL_USER_ID} +spring.mail.password=${MAIL_USER_PW} +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.starttls.enable=true +spring.mail.default-encoding=UTF-8 \ No newline at end of file From 985d0d1542a11f0fac1d180625ac78f9fbc16171 Mon Sep 17 00:00:00 2001 From: HongYeseul Date: Tue, 29 Oct 2024 23:50:41 +0900 Subject: [PATCH 3/9] =?UTF-8?q?feat(chore):=20=EC=9D=B4=EB=A9=94=EC=9D=BC?= =?UTF-8?q?=20=EB=B3=B4=EB=82=B4=EA=B8=B0=20=EC=9C=84=ED=95=9C=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build.gradle b/build.gradle index b8302dfe..bd6f312d 100644 --- a/build.gradle +++ b/build.gradle @@ -61,6 +61,11 @@ dependencies { // 모니터링을 위한 패키지 implementation 'org.springframework.boot:spring-boot-starter-actuator' + + // 이메일 알림 전송용 + implementation 'org.springframework.boot:spring-boot-starter-mail' + implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' + implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect' } compileJava { From c6dc7e7278410ae2d8bd29ad48c9d4a29f37a54b Mon Sep 17 00:00:00 2001 From: HongYeseul Date: Tue, 29 Oct 2024 23:52:16 +0900 Subject: [PATCH 4/9] =?UTF-8?q?refactor(comment):=20=ED=95=84=EC=9A=94?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../grassdiary/domain/comment/controller/CommentController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/chzzk/grassdiary/domain/comment/controller/CommentController.java b/src/main/java/chzzk/grassdiary/domain/comment/controller/CommentController.java index e7e644dc..29046f11 100644 --- a/src/main/java/chzzk/grassdiary/domain/comment/controller/CommentController.java +++ b/src/main/java/chzzk/grassdiary/domain/comment/controller/CommentController.java @@ -11,7 +11,6 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; From caca239e17635829fb29e4667322b8bb599a35af Mon Sep 17 00:00:00 2001 From: HongYeseul Date: Tue, 29 Oct 2024 23:52:49 +0900 Subject: [PATCH 5/9] =?UTF-8?q?feat(email-logo):=20=EC=9D=B4=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=20=EC=A0=84=EC=86=A1=EC=9A=A9=20=EB=A1=9C=EA=B3=A0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/static/images/grass-diary-logo.png | Bin 0 -> 2970 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/resources/static/images/grass-diary-logo.png diff --git a/src/main/resources/static/images/grass-diary-logo.png b/src/main/resources/static/images/grass-diary-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..04c9b1152352462d7f043a2cdce699a14992ab70 GIT binary patch literal 2970 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 Q2mk;807*qoM6N<$f{T{8`v3p{ literal 0 HcmV?d00001 From 1b8fff2b1fb777f817be968c829e40b6a4afde51 Mon Sep 17 00:00:00 2001 From: HongYeseul Date: Tue, 29 Oct 2024 23:53:32 +0900 Subject: [PATCH 6/9] =?UTF-8?q?feat(email):=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20=EC=A0=84?= =?UTF-8?q?=EC=86=A1=EC=9A=A9=20=ED=85=9C=ED=94=8C=EB=A6=BF=20html=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/comment-notification.html | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/main/resources/templates/comment-notification.html diff --git a/src/main/resources/templates/comment-notification.html b/src/main/resources/templates/comment-notification.html new file mode 100644 index 00000000..cdff2e05 --- /dev/null +++ b/src/main/resources/templates/comment-notification.html @@ -0,0 +1,108 @@ + + + + + 새로운 댓글 알림 + + + + + + \ No newline at end of file From fdf9313a71208619be0f5855c692769dedb8844d Mon Sep 17 00:00:00 2001 From: HongYeseul Date: Tue, 29 Oct 2024 23:54:17 +0900 Subject: [PATCH 7/9] =?UTF-8?q?feat(email):=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=EC=99=80=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=EB=84=88=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notification/CommentCreatedEvent.java | 38 +++++++++++++++++++ .../EmailNotificationListener.java | 19 ++++++++++ 2 files changed, 57 insertions(+) create mode 100644 src/main/java/chzzk/grassdiary/domain/notification/CommentCreatedEvent.java create mode 100644 src/main/java/chzzk/grassdiary/domain/notification/EmailNotificationListener.java diff --git a/src/main/java/chzzk/grassdiary/domain/notification/CommentCreatedEvent.java b/src/main/java/chzzk/grassdiary/domain/notification/CommentCreatedEvent.java new file mode 100644 index 00000000..a117c9e1 --- /dev/null +++ b/src/main/java/chzzk/grassdiary/domain/notification/CommentCreatedEvent.java @@ -0,0 +1,38 @@ +package chzzk.grassdiary.domain.notification; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationEvent; + +import java.time.LocalDateTime; + +@Getter +@Slf4j +public class CommentCreatedEvent extends ApplicationEvent { + private final Long diaryId; + private final String authorName; + private final String diaryAuthorEmail; + private final String commentContent; + private final LocalDateTime diaryCreatedAt; + private final String commentCreatedBy; + private final LocalDateTime commentCreatedAt; + + public CommentCreatedEvent(Object source, + Long diaryId, + String authorName, + String diaryAuthorEmail, + String commentContent, + LocalDateTime diaryCreatedAt, + String commentCreatedBy, + LocalDateTime commentCreatedAt + ) { + super(source); + this.diaryId = diaryId; + this.authorName = authorName; + this.diaryAuthorEmail = diaryAuthorEmail; + this.commentContent = commentContent; + this.diaryCreatedAt = diaryCreatedAt; + this.commentCreatedBy = commentCreatedBy; + this.commentCreatedAt = commentCreatedAt; + } +} diff --git a/src/main/java/chzzk/grassdiary/domain/notification/EmailNotificationListener.java b/src/main/java/chzzk/grassdiary/domain/notification/EmailNotificationListener.java new file mode 100644 index 00000000..3fa63bbf --- /dev/null +++ b/src/main/java/chzzk/grassdiary/domain/notification/EmailNotificationListener.java @@ -0,0 +1,19 @@ +package chzzk.grassdiary.domain.notification; + +import jakarta.mail.MessagingException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.transaction.event.TransactionPhase; +import org.springframework.transaction.event.TransactionalEventListener; + +@Component +@RequiredArgsConstructor +public class EmailNotificationListener { + + private final EmailService emailService; + + @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) + public void handleCommentCreatedEvent(CommentCreatedEvent event) throws MessagingException { + emailService.sendCommentNotification(event); + } +} \ No newline at end of file From cd078c5847921b86de3d44432d4ba72c932e7cb1 Mon Sep 17 00:00:00 2001 From: HongYeseul Date: Tue, 29 Oct 2024 23:54:48 +0900 Subject: [PATCH 8/9] =?UTF-8?q?feat(email):=20=EC=9D=B4=EB=A9=94=EC=9D=BC?= =?UTF-8?q?=20=EC=A0=84=EC=86=A1=EC=9A=A9=20EmailService=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/notification/EmailService.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/main/java/chzzk/grassdiary/domain/notification/EmailService.java diff --git a/src/main/java/chzzk/grassdiary/domain/notification/EmailService.java b/src/main/java/chzzk/grassdiary/domain/notification/EmailService.java new file mode 100644 index 00000000..67565292 --- /dev/null +++ b/src/main/java/chzzk/grassdiary/domain/notification/EmailService.java @@ -0,0 +1,54 @@ +package chzzk.grassdiary.domain.notification; + +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.thymeleaf.spring6.SpringTemplateEngine; +import org.springframework.core.io.ClassPathResource; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.stereotype.Service; +import org.thymeleaf.context.Context; + +@Slf4j +@Service +@RequiredArgsConstructor +public class EmailService { + + private final JavaMailSender mailSender; + + private final SpringTemplateEngine templateEngine; + + public void sendCommentNotification(CommentCreatedEvent event) { + try { + log.info("Sending comment notification for comment {}", event); + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); + + Context context = new Context(); + context.setVariable("recipientName", event.getAuthorName()); + context.setVariable("diaryDate", event.getDiaryCreatedAt()); + context.setVariable("commenterName", event.getCommentCreatedBy()); + context.setVariable("commentDate", event.getCommentCreatedAt()); + context.setVariable("commentContent", event.getCommentContent()); + context.setVariable("diaryUrl", "https://grassdiary.site/diary/" + event.getDiaryId()); +// context.setVariable("unsubscribeUrl", "http://your-domain.com/unsubscribe"); + + String htmlContent = templateEngine.process("comment-notification", context); + + helper.setTo(event.getDiaryAuthorEmail()); + helper.setSubject("[잔디 일기] 새로운 댓글 알림"); + helper.setText(htmlContent, true); + + ClassPathResource imageResource = new ClassPathResource("static/images/grass-diary-logo.png"); + helper.addInline("headerImage", imageResource); + + mailSender.send(message); + log.info("{}님께 [댓글 알림] 이메일을 보냈습니다.", event.getAuthorName()); + + } catch (MessagingException e) { + throw new RuntimeException("댓글 이메일 보내기가 실패했습니다.", e); + } + } +} From ea57ab324be9065dc9662a2036df13c47d241f55 Mon Sep 17 00:00:00 2001 From: HongYeseul Date: Tue, 29 Oct 2024 23:55:10 +0900 Subject: [PATCH 9/9] =?UTF-8?q?feat(CommentService):=20=EC=9D=B4=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=20=EC=A0=84=EC=86=A1=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/service/CommentService.java | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/main/java/chzzk/grassdiary/domain/comment/service/CommentService.java b/src/main/java/chzzk/grassdiary/domain/comment/service/CommentService.java index 3552c02a..e4d6212e 100644 --- a/src/main/java/chzzk/grassdiary/domain/comment/service/CommentService.java +++ b/src/main/java/chzzk/grassdiary/domain/comment/service/CommentService.java @@ -10,6 +10,7 @@ import chzzk.grassdiary.domain.comment.dto.CommentResponseDTO; import chzzk.grassdiary.domain.member.entity.Member; import chzzk.grassdiary.domain.member.entity.MemberDAO; +import chzzk.grassdiary.domain.notification.CommentCreatedEvent; import chzzk.grassdiary.global.common.error.exception.SystemException; import chzzk.grassdiary.global.common.response.ClientErrorCode; import java.util.ArrayList; @@ -18,20 +19,29 @@ import java.util.Map; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor public class CommentService { + + private static final int MAX_LENGTH = 70; + private static final String ELLIPSIS = "..."; + private static final Logger log = LoggerFactory.getLogger(CommentService.class); + private final CommentDAO commentDAO; private final DiaryDAO diaryDAO; private final MemberDAO memberDAO; + private final ApplicationEventPublisher eventPublisher; + @Transactional - public CommentResponseDTO save(Long diaryId, CommentSaveRequestDTO requestDTO, Long logInMemberId) { + public CommentResponseDTO save(Long diaryId, CommentSaveRequestDTO requestDTO, final Long logInMemberId) { Member member = getMemberById(logInMemberId); Diary diary = getDiaryById(diaryId); Comment parentComment = getParentCommentById(requestDTO.parentCommentId()); @@ -41,9 +51,36 @@ public CommentResponseDTO save(Long diaryId, CommentSaveRequestDTO requestDTO, L Comment comment = requestDTO.toEntity(member, diary, parentComment, commentDepth); commentDAO.save(comment); + // 댓글에 대한 이메일 알람 + Member diaryAuthor = diary.getMember(); + if (!logInMemberId.equals(diaryAuthor.getId())) { + log.info("댓글 알람 시작: {}", diaryAuthor); + String commentContent = truncateContent(comment.getContent()); + + CommentCreatedEvent event = new CommentCreatedEvent(this, + diaryId, + diaryAuthor.getNickname(), + diaryAuthor.getEmail(), + commentContent, + diary.getCreatedAt(), + member.getNickname(), + comment.getCreatedAt() + ); + eventPublisher.publishEvent(event); + } + return CommentResponseDTO.from(comment); } + private String truncateContent(String content) { + if (content == null) { + return ""; + } + return content.length() > MAX_LENGTH + ? content.substring(0, MAX_LENGTH) + ELLIPSIS + : content; + } + @Transactional public CommentResponseDTO update(Long commentId, CommentUpdateRequestDTO requestDTO, Long logInMemberId) { Member member = getMemberById(logInMemberId);