diff --git a/src/main/java/com/aliens/backend/board/service/CommentService.java b/src/main/java/com/aliens/backend/board/service/CommentService.java index 8ed2c8b4..8bf77eb4 100644 --- a/src/main/java/com/aliens/backend/board/service/CommentService.java +++ b/src/main/java/com/aliens/backend/board/service/CommentService.java @@ -15,13 +15,16 @@ import com.aliens.backend.global.exception.RestApiException; import com.aliens.backend.global.response.error.BoardError; import com.aliens.backend.global.response.error.MemberError; +import com.aliens.backend.notification.controller.dto.NotificationRequest; import com.aliens.backend.notification.service.FcmSender; +import com.aliens.backend.notification.service.NotificationService; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; +import java.util.Objects; @Service public class CommentService { @@ -30,48 +33,62 @@ public class CommentService { private final BoardRepository boardRepository; private final CommentCustomRepository commentCustomRepository; private final FcmSender fcmSender; + private final NotificationService notificationService; public CommentService(final CommentRepository commentRepository, final MemberRepository memberRepository, final BoardRepository boardRepository, final CommentCustomRepository commentCustomRepository, - FcmSender fcmSender) { + final FcmSender fcmSender, NotificationService notificationService) { this.commentRepository = commentRepository; this.memberRepository = memberRepository; this.boardRepository = boardRepository; this.commentCustomRepository = commentCustomRepository; this.fcmSender = fcmSender; + this.notificationService = notificationService; } @Transactional public void postParentComment(final ParentCommentCreateRequest request, final LoginMember loginMember) { - Member member = getMember(loginMember); + Member member = getMember(loginMember.memberId()); Board board = findBoard(request.boardId()); Comment comment = Comment.parentOf(request.content(), board, member); board.addComment(comment); commentRepository.save(comment); -// -// if(!comment.isWriter(board.getWriterId())) { -// fcmSender.sendParentCommentNotification(board,request); -// } + sendNotification(comment, board); + } + + private void sendNotification(Comment comment, Board board) { + if(comment.isWriter(board.getWriterId())) return; + + Member writer = getMember(board.getWriterId()); + + NotificationRequest request = makeNotificationRequest(board, comment, List.of(writer)); + notificationService.saveNotification(request); + + fcmSender.sendBoardNotification(comment, writer); + } + + private NotificationRequest makeNotificationRequest(Board board, Comment comment, List members) { + return new NotificationRequest(board.getCategory(),board.getId(),comment.getContent(), members); } private Board findBoard(final Long boardId) { return boardRepository.findById(boardId).orElseThrow(() -> new RestApiException(BoardError.INVALID_BOARD_ID)); } - private Member getMember(final LoginMember loginMember) { - return memberRepository.findById(loginMember.memberId()).orElseThrow(() -> new RestApiException(MemberError.NULL_MEMBER)); + private Member getMember(final Long memberId) { + return memberRepository.findById(memberId).orElseThrow(() -> new RestApiException(MemberError.NULL_MEMBER)); } @Transactional public void postChildComment(final ChildCommentCreateRequest request, final LoginMember loginMember) { - Member member = getMember(loginMember); + Member member = getMember(loginMember.memberId()); Board board = findBoard(request.boardId()); Comment parentComment = findComment(request); @@ -80,9 +97,21 @@ public void postChildComment(final ChildCommentCreateRequest request, commentRepository.save(childComment); -// if(!parentComment.isWriter(member.getId())) { -// fcmSender.sendChildCommentNotification(board, request, parentComment.getWriterId()); -// } + sendNotification(childComment, board, parentComment); + } + + private void sendNotification(Comment child, Board board, Comment parent) { + if(child.isWriter(board.getWriterId())) return; + if(Objects.equals(parent.getWriterId(), child.getWriterId())) return; + + Member boardWriter = getMember(board.getWriterId()); + Member parentWriter = getMember(parent.getWriterId()); + List writers = List.of(boardWriter, parentWriter); + + NotificationRequest request = makeNotificationRequest(board, child, writers); + notificationService.saveNotification(request); + + fcmSender.sendBoardNotification(child, writers); } private Comment findComment(ChildCommentCreateRequest request) { @@ -141,4 +170,4 @@ public void deleteComment(final LoginMember loginMember, final Long commentId) { private Comment getComment(final Long commentId) { return commentRepository.findById(commentId).orElseThrow(() -> new RestApiException(BoardError.INVALID_COMMENT_ID)); } -} +} \ No newline at end of file diff --git a/src/main/java/com/aliens/backend/board/service/GreatService.java b/src/main/java/com/aliens/backend/board/service/GreatService.java index 2986443a..27e95370 100644 --- a/src/main/java/com/aliens/backend/board/service/GreatService.java +++ b/src/main/java/com/aliens/backend/board/service/GreatService.java @@ -17,7 +17,6 @@ import org.springframework.transaction.annotation.Transactional; import java.util.List; -import java.util.Optional; @Service public class GreatService { diff --git a/src/main/java/com/aliens/backend/notification/controller/dto/NotificationRequest.java b/src/main/java/com/aliens/backend/notification/controller/dto/NotificationRequest.java index beb3ccdc..15e81b65 100644 --- a/src/main/java/com/aliens/backend/notification/controller/dto/NotificationRequest.java +++ b/src/main/java/com/aliens/backend/notification/controller/dto/NotificationRequest.java @@ -1,5 +1,6 @@ package com.aliens.backend.notification.controller.dto; +import com.aliens.backend.auth.domain.Member; import com.aliens.backend.board.domain.enums.BoardCategory; import java.util.List; @@ -7,5 +8,5 @@ public record NotificationRequest(BoardCategory boardCategory, Long boardId, String content, - List memberIds) { + List members) { } diff --git a/src/main/java/com/aliens/backend/notification/service/FcmSender.java b/src/main/java/com/aliens/backend/notification/service/FcmSender.java index 362d616e..c3d29c40 100644 --- a/src/main/java/com/aliens/backend/notification/service/FcmSender.java +++ b/src/main/java/com/aliens/backend/notification/service/FcmSender.java @@ -2,25 +2,19 @@ import com.aliens.backend.auth.domain.Member; import com.aliens.backend.auth.domain.repository.MemberRepository; -import com.aliens.backend.board.controller.dto.request.ChildCommentCreateRequest; -import com.aliens.backend.board.controller.dto.request.ParentCommentCreateRequest; -import com.aliens.backend.board.domain.Board; +import com.aliens.backend.board.domain.Comment; import com.aliens.backend.global.response.error.CommonError; import com.aliens.backend.global.exception.RestApiException; import com.aliens.backend.global.response.error.MemberError; -import com.aliens.backend.notification.controller.dto.NotificationRequest; import com.aliens.backend.notification.domain.repository.FcmTokenRepository; import com.google.firebase.messaging.*; import com.aliens.backend.global.response.log.InfoLogResponse; import com.aliens.backend.global.response.success.NotificationSuccess; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.Message; -import com.google.firebase.messaging.MulticastMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; import java.util.List; @@ -28,9 +22,9 @@ @Component public class FcmSender { - private final static String MATCHING_SUCCESS_MESSAGE_TITLE = "매칭이 완료되었습니다!"; - private final static String MATCHING_SUCCESS_MESSAGE_BODY = "파트너를 확인해보세요!"; - private final static String PARENT_COMMENT_MESSAGE = "댓글이 달렸어요!"; + private final static String COMMENT_BODY = "새로운 댓글이 달렸어요 : "; + private final static String FRIENDSHIP_TITLE = "Friendship"; + private final static String MATCHING_SUCCESS_MESSAGE_BODY = "Friendship 매칭이 완료되었습니다. 파트너를 확인해보세요!"; private final MemberRepository memberRepository; private final FcmTokenRepository fcmTokenRepository; private final ObjectMapper objectMapper; @@ -45,38 +39,33 @@ public FcmSender(MemberRepository memberRepository, this.objectMapper = objectMapper; } - public void sendBoardNotification(NotificationRequest request, List tokens) { - MulticastMessage message = makeMessage(request, tokens); - sendMultiFcm(message); - } - - private MulticastMessage makeMessage(NotificationRequest request, - List tokens) { - var notification = com.google.firebase.messaging.Notification.builder() - .setTitle(String.valueOf(request.boardCategory())) - .setBody(request.content()). - build(); + public void sendBoardNotification(Comment comment, Member writer) { + Notification notification = Notification.builder() + .setTitle(FRIENDSHIP_TITLE) + .setBody(COMMENT_BODY + comment.getContent()) + .build(); - return MulticastMessage.builder() + String token = findFcmTokenByMember(writer); + Message message = Message.builder() + .setToken(token) .setNotification(notification) - .addAllTokens(tokens) .build(); - + sendSingleFcm(message); } - private void sendMultiFcm(MulticastMessage message) { - try { - FirebaseMessaging.getInstance().sendMulticastAsync(message); - InfoLogResponse response = InfoLogResponse.from(NotificationSuccess.SEND_MULTI_NOTIFICATION_SUCCESS); - log.info(objectMapper.writeValueAsString(response)); - } catch (Exception e) { - InfoLogResponse response = InfoLogResponse.from(CommonError.FCM_MESSAGING_ERROR); - try { - log.error(objectMapper.writeValueAsString(response)); - } catch (JsonProcessingException ex) { - throw new RuntimeException(ex); - } - throw new RestApiException(CommonError.FCM_MESSAGING_ERROR); + public void sendBoardNotification(Comment comment, List writers) { + Notification notification = Notification.builder() + .setTitle(FRIENDSHIP_TITLE) + .setBody(COMMENT_BODY + comment.getContent()) + .build(); + + for(Member writer : writers) { + String token = findFcmTokenByMember(writer); + Message message = Message.builder() + .setToken(token) + .setNotification(notification) + .build(); + sendSingleFcm(message); } } @@ -119,7 +108,7 @@ private void sendSingleFcm(Message message) { public void sendMatchedNotification(Set members) { List tokens = members.stream().map(this::findFcmTokenByMember).toList(); Notification notification = Notification.builder() - .setTitle(MATCHING_SUCCESS_MESSAGE_TITLE) + .setTitle(FRIENDSHIP_TITLE) .setBody(MATCHING_SUCCESS_MESSAGE_BODY) .build(); @@ -131,26 +120,4 @@ public void sendMatchedNotification(Set members) { sendSingleFcm(message); }); } - - public void sendChildCommentNotification(Board board, ChildCommentCreateRequest request, Long writerId) { - Message message = createParentCommentMessage(board,request.content()); - sendSingleFcm(message); - } - - public void sendParentCommentNotification(Board board, ParentCommentCreateRequest request) { - Message message = createParentCommentMessage(board,request.content()); - sendSingleFcm(message); - } - - private Message createParentCommentMessage(Board board, String content) { - Member boardWriter = getMember(board.getWriterId()); - - return com.google.firebase.messaging.Message.builder() - .setNotification(com.google.firebase.messaging.Notification.builder() - .setTitle(PARENT_COMMENT_MESSAGE) - .setBody(content) - .build()) - .setToken(findFcmTokenByMember(boardWriter)) - .build(); - } -} +} \ No newline at end of file diff --git a/src/main/java/com/aliens/backend/notification/service/NotificationService.java b/src/main/java/com/aliens/backend/notification/service/NotificationService.java index 5b9dcfd7..70ce0d91 100644 --- a/src/main/java/com/aliens/backend/notification/service/NotificationService.java +++ b/src/main/java/com/aliens/backend/notification/service/NotificationService.java @@ -7,22 +7,15 @@ import com.aliens.backend.global.response.error.CommonError; import com.aliens.backend.global.response.error.MemberError; import com.aliens.backend.global.response.error.NotificationError; -import com.aliens.backend.global.response.error.TokenError; -import com.aliens.backend.notification.domain.NotificationType; import com.aliens.backend.notification.domain.repository.NotificationRepository; import com.aliens.backend.notification.controller.dto.NotificationRequest; import com.aliens.backend.notification.controller.dto.NotificationResponse; import com.aliens.backend.notification.domain.FcmToken; import com.aliens.backend.notification.domain.repository.FcmTokenRepository; import com.aliens.backend.notification.domain.Notification; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -31,16 +24,14 @@ public class NotificationService { private final NotificationRepository notificationRepository; private final FcmTokenRepository fcmTokenRepository; private final MemberRepository memberRepository; - private final FcmSender fcmSender; public NotificationService(final NotificationRepository notificationRepository, final FcmTokenRepository fcmTokenRepository, - final MemberRepository memberRepository, FcmSender fcmSender) { + final MemberRepository memberRepository) { this.notificationRepository = notificationRepository; this.fcmTokenRepository = fcmTokenRepository; this.memberRepository = memberRepository; - this.fcmSender = fcmSender; } @Transactional @@ -60,7 +51,7 @@ public void registerFcmToken(final LoginMember loginMember, final String fcmToke } private String parseFcmToken(final String fcmToken) { - return fcmToken.substring(15, fcmToken.length()-2); + return fcmToken.substring(13, fcmToken.length()-2); } @Transactional(readOnly = true) @@ -88,24 +79,12 @@ private Member getMember(final Long memberId) { return memberRepository.findById(memberId).orElseThrow(() -> new RestApiException(MemberError.NULL_MEMBER)); } - @EventListener + @Transactional public void saveNotification(NotificationRequest request) { - List tokens = new ArrayList<>(); - - for(Long memberId : request.memberIds()) { - Member member = getMember(memberId); + for(Member member : request.members()) { Notification notification = Notification.of(request, member); - notificationRepository.save(notification); - - FcmToken fcmToken = getFcmTokenByMember(member); - - if(fcmToken.isAccepted()) { - tokens.add(fcmToken.getToken()); - } } - - fcmSender.sendBoardNotification(request,tokens); } private FcmToken getFcmTokenByMember(final Member member) { @@ -125,4 +104,4 @@ public void changeAcceptation(final LoginMember loginMember, final Boolean decis FcmToken token = getFcmTokenByMember(member); token.changeAccept(decision); } -} +} \ No newline at end of file diff --git a/src/test/java/com/aliens/backend/docs/MemberRestDocsTest.java b/src/test/java/com/aliens/backend/docs/MemberRestDocsTest.java index 8bdc847c..fc7da5c1 100644 --- a/src/test/java/com/aliens/backend/docs/MemberRestDocsTest.java +++ b/src/test/java/com/aliens/backend/docs/MemberRestDocsTest.java @@ -35,11 +35,8 @@ class MemberRestDocsTest extends BaseRestDocsTest { void signUp() throws Exception { final SignUpRequest request = createSampleSignUpRequest(); - final String message = MemberResponse.SIGN_UP_SUCCESS.getMessage(); - SuccessResponse response = SuccessResponse.of(MemberSuccess.SIGN_UP_SUCCESS, message); MockMultipartFile multipartFile = createMultipartFile(); - - final MockMultipartFile requestMultipartFile = new MockMultipartFile("request", + MockMultipartFile requestMultipartFile = new MockMultipartFile("request", null, "application/json", objectMapper.writeValueAsString(request).getBytes(StandardCharsets.UTF_8)); dummyGenerator.authenticateEmail(request.email()); diff --git a/src/test/java/com/aliens/backend/global/BaseIntegrationTest.java b/src/test/java/com/aliens/backend/global/BaseIntegrationTest.java index 810d55e6..9d426161 100644 --- a/src/test/java/com/aliens/backend/global/BaseIntegrationTest.java +++ b/src/test/java/com/aliens/backend/global/BaseIntegrationTest.java @@ -1,5 +1,6 @@ package com.aliens.backend.global; +import com.aliens.backend.auth.domain.Member; import com.aliens.backend.chat.controller.ChatController; import com.aliens.backend.chat.domain.repository.MessageRepository; import com.aliens.backend.chat.service.model.ChatAuthValidator; @@ -49,7 +50,7 @@ void setUpSpy() { //FCM doNothing().when(fcmSender).sendChatMessage(any()); doNothing().when(fcmSender).sendMatchedNotification(any()); - doNothing().when(fcmSender).sendBoardNotification(any(),any()); + doNothing().when(fcmSender).sendBoardNotification(any(), (Member)any()); //AWS S3File tmpFile = new S3File(DummyGenerator.GIVEN_FILE_NAME, DummyGenerator.GIVEN_FILE_URL); diff --git a/src/test/java/com/aliens/backend/global/DummyGenerator.java b/src/test/java/com/aliens/backend/global/DummyGenerator.java index 32888c06..46779f61 100644 --- a/src/test/java/com/aliens/backend/global/DummyGenerator.java +++ b/src/test/java/com/aliens/backend/global/DummyGenerator.java @@ -291,14 +291,15 @@ private BoardImage makeBoardImage(Board board) { public void generateNotificationWithCount(final Member member, final int count) { for(int i = 0; i < count; i++) { - NotificationRequest request = new NotificationRequest(BoardCategory.ALL, 1L, GIVEN_COMMENT_CONTENT,List.of(1L)); + NotificationRequest request = new NotificationRequest(BoardCategory.ALL, 1L, GIVEN_COMMENT_CONTENT,List.of(generateSingleMember())); Notification notification = Notification.of(request,member); notificationRepository.save(notification); } } - public Notification generateSingleNotification(final Member member) { - NotificationRequest request = new NotificationRequest(BoardCategory.ALL, 1L, GIVEN_COMMENT_CONTENT,List.of(1L)); + public Notification generateSingleNotification(Member member) { + Member opposite = generateSingleMember(); + NotificationRequest request = new NotificationRequest(BoardCategory.ALL, 1L, GIVEN_COMMENT_CONTENT,List.of(opposite)); Notification notification = Notification.of(request,member); return notificationRepository.save(notification); } diff --git a/src/test/java/com/aliens/backend/notification/NotificationServiceTest.java b/src/test/java/com/aliens/backend/notification/NotificationServiceTest.java index f3a4e838..69a4e6e5 100644 --- a/src/test/java/com/aliens/backend/notification/NotificationServiceTest.java +++ b/src/test/java/com/aliens/backend/notification/NotificationServiceTest.java @@ -42,7 +42,7 @@ void setUp() { @DisplayName("fcm토큰 저장") void registerFcmTokenTest() { //Given - String givenToken = "{\"fcmToken\" : \"fcmTokenExample\"}"; + String givenToken = "{\"fcmToken\":\"fcmTokenExample\"}"; String expectedToken = "fcmTokenExample"; //When notificationService.registerFcmToken(loginMember, givenToken); @@ -84,7 +84,7 @@ void readNotificationTest() { @DisplayName("알림 저장") void saveNotificationTest() { //Given - NotificationRequest request = new NotificationRequest(BoardCategory.ALL, 1L, DummyGenerator.GIVEN_COMMENT_CONTENT, List.of(1L)); + NotificationRequest request = new NotificationRequest(BoardCategory.ALL, 1L, DummyGenerator.GIVEN_COMMENT_CONTENT, List.of(dummyGenerator.generateSingleMember())); //When notificationService.saveNotification(request); @@ -93,4 +93,4 @@ void saveNotificationTest() { List result = notificationRepository.findAll(); Assertions.assertEquals(result.size(), 1); } -} +} \ No newline at end of file