Skip to content
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

2024-10-18 [Release Note] #192

Merged
merged 7 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 42 additions & 13 deletions src/main/java/com/aliens/backend/board/service/CommentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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<Member> 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);

Expand All @@ -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<Member> writers = List.of(boardWriter, parentWriter);

NotificationRequest request = makeNotificationRequest(board, child, writers);
notificationService.saveNotification(request);

fcmSender.sendBoardNotification(child, writers);
}

private Comment findComment(ChildCommentCreateRequest request) {
Expand Down Expand Up @@ -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));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Service
public class GreatService {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
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;

public record NotificationRequest(BoardCategory boardCategory,
Long boardId,
String content,
List<Long> memberIds) {
List<Member> members) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,29 @@

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;
import java.util.Set;

@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;
Expand All @@ -45,38 +39,33 @@ public FcmSender(MemberRepository memberRepository,
this.objectMapper = objectMapper;
}

public void sendBoardNotification(NotificationRequest request, List<String> tokens) {
MulticastMessage message = makeMessage(request, tokens);
sendMultiFcm(message);
}

private MulticastMessage makeMessage(NotificationRequest request,
List<String> 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<Member> 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);
}
}

Expand Down Expand Up @@ -119,7 +108,7 @@ private void sendSingleFcm(Message message) {
public void sendMatchedNotification(Set<Member> members) {
List<String> 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();

Expand All @@ -131,26 +120,4 @@ public void sendMatchedNotification(Set<Member> 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();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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<String> 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) {
Expand All @@ -125,4 +104,4 @@ public void changeAcceptation(final LoginMember loginMember, final Boolean decis
FcmToken token = getFcmTokenByMember(member);
token.changeAccept(decision);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> 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());
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Loading
Loading