diff --git a/backend/src/main/java/com/happy/friendogly/chatsocket/service/ChatSocketCommandService.java b/backend/src/main/java/com/happy/friendogly/chatsocket/service/ChatSocketCommandService.java index d78812b52..070c692dd 100644 --- a/backend/src/main/java/com/happy/friendogly/chatsocket/service/ChatSocketCommandService.java +++ b/backend/src/main/java/com/happy/friendogly/chatsocket/service/ChatSocketCommandService.java @@ -4,20 +4,20 @@ import static com.happy.friendogly.chatsocket.domain.MessageType.ENTER; import static com.happy.friendogly.chatsocket.domain.MessageType.LEAVE; -import com.happy.friendogly.chatsocket.template.ChatTemplate; import com.happy.friendogly.chatmessage.domain.ChatMessage; +import com.happy.friendogly.chatmessage.repository.ChatMessageRepository; import com.happy.friendogly.chatroom.domain.ChatRoom; +import com.happy.friendogly.chatroom.repository.ChatRoomRepository; import com.happy.friendogly.chatsocket.domain.MessageType; import com.happy.friendogly.chatsocket.dto.request.ChatMessageSocketRequest; import com.happy.friendogly.chatsocket.dto.response.ChatMessageSocketResponse; -import com.happy.friendogly.chatmessage.repository.ChatMessageRepository; -import com.happy.friendogly.chatroom.repository.ChatRoomRepository; +import com.happy.friendogly.chatsocket.template.ChatTemplate; import com.happy.friendogly.club.domain.Club; import com.happy.friendogly.club.repository.ClubRepository; import com.happy.friendogly.exception.FriendoglyException; import com.happy.friendogly.member.domain.Member; import com.happy.friendogly.member.repository.MemberRepository; -import com.happy.friendogly.notification.service.NotificationService; +import com.happy.friendogly.notification.service.ChatNotificationService; import java.time.LocalDateTime; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -32,7 +32,7 @@ public class ChatSocketCommandService { private final ClubRepository clubRepository; private final ChatRoomRepository chatRoomRepository; private final ChatMessageRepository chatMessageRepository; - private final NotificationService notificationService; + private final ChatNotificationService chatNotificationService; private final ChatTemplate template; public ChatSocketCommandService( @@ -40,14 +40,14 @@ public ChatSocketCommandService( ClubRepository clubRepository, ChatRoomRepository chatRoomRepository, ChatMessageRepository chatMessageRepository, - NotificationService notificationService, + ChatNotificationService chatNotificationService, ChatTemplate template ) { this.memberRepository = memberRepository; this.clubRepository = clubRepository; this.chatRoomRepository = chatRoomRepository; this.chatMessageRepository = chatMessageRepository; - this.notificationService = notificationService; + this.chatNotificationService = chatNotificationService; this.template = template; } @@ -79,7 +79,7 @@ private void sendAndSave(MessageType messageType, String content, ChatRoom chatR messageType, content, senderMember, LocalDateTime.now()); Club club = clubRepository.getByChatRoomId(chatRoom.getId()); - notificationService.sendChatNotification(chatRoom.getId(), chat, club); + chatNotificationService.sendChatNotification(chatRoom.getId(), chat, club); template.convertAndSend(chatRoom.getId(), chat); chatMessageRepository.save(new ChatMessage(chatRoom, messageType, senderMember, content)); } diff --git a/backend/src/main/java/com/happy/friendogly/notification/service/ChatNotificationService.java b/backend/src/main/java/com/happy/friendogly/notification/service/ChatNotificationService.java new file mode 100644 index 000000000..04e06eacc --- /dev/null +++ b/backend/src/main/java/com/happy/friendogly/notification/service/ChatNotificationService.java @@ -0,0 +1,44 @@ +package com.happy.friendogly.notification.service; + +import static com.happy.friendogly.notification.domain.NotificationType.CHAT; + +import com.happy.friendogly.chatsocket.dto.response.ChatMessageSocketResponse; +import com.happy.friendogly.club.domain.Club; +import com.happy.friendogly.notification.repository.DeviceTokenRepository; +import java.util.List; +import java.util.Map; +import org.springframework.stereotype.Service; + +@Service +public class ChatNotificationService { + + private final DeviceTokenRepository deviceTokenRepository; + private final NotificationService notificationService; + + public ChatNotificationService( + DeviceTokenRepository deviceTokenRepository, + NotificationService notificationService + ) { + this.deviceTokenRepository = deviceTokenRepository; + this.notificationService = notificationService; + } + + public void sendChatNotification(Long chatRoomId, ChatMessageSocketResponse response, Club club) { + List receiverTokens = deviceTokenRepository + .findAllByChatRoomIdWithoutMine(chatRoomId, response.senderMemberId()); + + Map data = Map.of( + "chatRoomId", chatRoomId.toString(), + "messageType", response.messageType().toString(), + "senderMemberId", response.senderMemberId().toString(), + "senderName", response.senderName(), + "content", response.content(), + "createdAt", response.createdAt().toString(), + "profilePictureUrl", response.profilePictureUrl() == null ? "" : response.profilePictureUrl(), + "clubPictureUrl", club.getImageUrl() == null ? "" : club.getImageUrl(), + "clubTitle", club.getTitle().getValue() + ); + + notificationService.sendNotification("채팅", data, CHAT, receiverTokens); + } +} diff --git a/backend/src/main/java/com/happy/friendogly/notification/service/FakeNotificationService.java b/backend/src/main/java/com/happy/friendogly/notification/service/FakeNotificationService.java index be48016df..2cd47dfe4 100644 --- a/backend/src/main/java/com/happy/friendogly/notification/service/FakeNotificationService.java +++ b/backend/src/main/java/com/happy/friendogly/notification/service/FakeNotificationService.java @@ -1,8 +1,8 @@ package com.happy.friendogly.notification.service; -import com.happy.friendogly.chatsocket.dto.response.ChatMessageSocketResponse; -import com.happy.friendogly.club.domain.Club; +import com.happy.friendogly.notification.domain.NotificationType; import java.util.List; +import java.util.Map; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; @@ -11,22 +11,22 @@ public class FakeNotificationService implements NotificationService { @Override - public void sendFootprintNotification(String title, String content, String receiverToken) { + public void sendNotification( + String title, + String content, + NotificationType notificationType, + List receiverTokens + ) { } @Override - public void sendFootprintNotification(String title, String content, List receiverTokens) { - - } - - @Override - public void sendChatNotification(Long chatRoomId, ChatMessageSocketResponse response, Club club) { - - } - - @Override - public void sendPlaygroundJoinNotification(String title, String content, List receiverTokens) { + public void sendNotification( + String title, + Map contents, + NotificationType notificationType, + List receiverTokens + ) { } } diff --git a/backend/src/main/java/com/happy/friendogly/notification/service/FcmNotificationService.java b/backend/src/main/java/com/happy/friendogly/notification/service/FcmNotificationService.java index 60936079d..2e2df036f 100644 --- a/backend/src/main/java/com/happy/friendogly/notification/service/FcmNotificationService.java +++ b/backend/src/main/java/com/happy/friendogly/notification/service/FcmNotificationService.java @@ -1,19 +1,13 @@ package com.happy.friendogly.notification.service; -import static com.happy.friendogly.notification.domain.NotificationType.CHAT; -import static com.happy.friendogly.notification.domain.NotificationType.FOOTPRINT; -import static com.happy.friendogly.notification.domain.NotificationType.PLAYGROUND; import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; import com.google.firebase.FirebaseApp; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.FirebaseMessagingException; import com.google.firebase.messaging.MulticastMessage; -import com.happy.friendogly.chatsocket.dto.response.ChatMessageSocketResponse; -import com.happy.friendogly.club.domain.Club; import com.happy.friendogly.exception.FriendoglyException; import com.happy.friendogly.notification.domain.NotificationType; -import com.happy.friendogly.notification.repository.DeviceTokenRepository; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; @@ -27,72 +21,31 @@ public class FcmNotificationService implements NotificationService { private final FirebaseMessaging firebaseMessaging; - private final DeviceTokenRepository deviceTokenRepository; - public FcmNotificationService( - @Autowired FirebaseApp firebaseApp, - DeviceTokenRepository deviceTokenRepository - ) { + public FcmNotificationService(@Autowired FirebaseApp firebaseApp) { this.firebaseMessaging = FirebaseMessaging.getInstance(firebaseApp); - this.deviceTokenRepository = deviceTokenRepository; - } - - @Override - public void sendFootprintNotification(String title, String content, String receiverToken) { - Map data = Map.of( - "body", content - ); - - sendNotificationWithType(FOOTPRINT, title, data, List.of(receiverToken)); } @Override - public void sendFootprintNotification(String title, String content, List receiverTokens) { - Map data = Map.of( - "body", content - ); - - sendNotificationWithType(FOOTPRINT, title, data, receiverTokens); - } - - @Override - public void sendChatNotification(Long chatRoomId, ChatMessageSocketResponse response, Club club) { - List receiverTokens = deviceTokenRepository - .findAllByChatRoomIdWithoutMine(chatRoomId, response.senderMemberId()); - - Map data = Map.of( - "chatRoomId", chatRoomId.toString(), - "messageType", response.messageType().toString(), - "senderMemberId", response.senderMemberId().toString(), - "senderName", response.senderName(), - "content", response.content(), - "createdAt", response.createdAt().toString(), - "profilePictureUrl", response.profilePictureUrl(), - "clubPictureUrl", club.getImageUrl(), - "clubTitle", club.getTitle().getValue() - ); - - sendNotificationWithType(CHAT, "채팅", data, receiverTokens); + public void sendNotification( + String title, + String content, + NotificationType notificationType, + List receiverTokens + ) { + sendNotification(title, Map.of("body", content), notificationType, receiverTokens); } @Override - public void sendPlaygroundJoinNotification(String title, String content, List receiverTokens) { - Map data = Map.of( - "body", content - ); - - sendNotificationWithType(PLAYGROUND, title, data, receiverTokens); - } - - private void sendNotificationWithType( - NotificationType notificationType, + public void sendNotification( String title, - Map data, + Map contents, + NotificationType notificationType, List receiverTokens ) { if (!receiverTokens.isEmpty()) { MulticastMessage message = MulticastMessage.builder() - .putAllData(data) + .putAllData(contents) .putData("type", notificationType.toString()) .putData("title", title) .addAllTokens(receiverTokens) diff --git a/backend/src/main/java/com/happy/friendogly/notification/service/FootprintNotificationService.java b/backend/src/main/java/com/happy/friendogly/notification/service/FootprintNotificationService.java index 57dbc688c..bf0166b41 100644 --- a/backend/src/main/java/com/happy/friendogly/notification/service/FootprintNotificationService.java +++ b/backend/src/main/java/com/happy/friendogly/notification/service/FootprintNotificationService.java @@ -3,6 +3,7 @@ import com.happy.friendogly.footprint.domain.Footprint; import com.happy.friendogly.footprint.domain.WalkStatus; import com.happy.friendogly.notification.domain.DeviceToken; +import com.happy.friendogly.notification.domain.NotificationType; import com.happy.friendogly.notification.repository.DeviceTokenRepository; import java.util.List; import java.util.Optional; @@ -11,7 +12,8 @@ @Service public class FootprintNotificationService { - private final String DEFAULT_TITLE = "반갑개"; + private static final String DEFAULT_TITLE = "반갑개"; + private final NotificationService notificationService; private final DeviceTokenRepository deviceTokenRepository; @@ -35,19 +37,21 @@ public void sendWalkNotificationToMe(Long memberId, WalkStatus currentWalkStatus return; } - notificationService.sendFootprintNotification( + notificationService.sendNotification( DEFAULT_TITLE, content, - deviceTokenRepository.getByMemberId(memberId).getDeviceToken() + NotificationType.FOOTPRINT, + List.of(deviceTokenRepository.getByMemberId(memberId).getDeviceToken()) ); } public void sendWalkComingNotification(String comingMemberName, List nearFootprints) { List nearDeviceTokens = toDeviceToken(nearFootprints); - notificationService.sendFootprintNotification( + notificationService.sendNotification( DEFAULT_TITLE, "내 산책 장소에 " + comingMemberName + "님도 산책온대요!", + NotificationType.FOOTPRINT, nearDeviceTokens ); } @@ -55,8 +59,9 @@ public void sendWalkComingNotification(String comingMemberName, List public void sendWalkStartNotificationToNear(String startMemberName, List nearFootprints) { List nearDeviceTokens = toDeviceToken(nearFootprints); - notificationService.sendFootprintNotification(DEFAULT_TITLE, + notificationService.sendNotification(DEFAULT_TITLE, "내 산책장소에 " + startMemberName + "님이 산책을 시작했어요!", + NotificationType.FOOTPRINT, nearDeviceTokens ); } diff --git a/backend/src/main/java/com/happy/friendogly/notification/service/NotificationService.java b/backend/src/main/java/com/happy/friendogly/notification/service/NotificationService.java index d1b053427..8f0b3d121 100644 --- a/backend/src/main/java/com/happy/friendogly/notification/service/NotificationService.java +++ b/backend/src/main/java/com/happy/friendogly/notification/service/NotificationService.java @@ -1,16 +1,22 @@ package com.happy.friendogly.notification.service; -import com.happy.friendogly.chatsocket.dto.response.ChatMessageSocketResponse; -import com.happy.friendogly.club.domain.Club; +import com.happy.friendogly.notification.domain.NotificationType; import java.util.List; +import java.util.Map; public interface NotificationService { - void sendFootprintNotification(String title, String content, String receiverToken); + void sendNotification( + String title, + String content, + NotificationType notificationType, + List receiverTokens + ); - void sendFootprintNotification(String title, String content, List receiverTokens); - - void sendChatNotification(Long chatRoomId, ChatMessageSocketResponse response, Club club); - - void sendPlaygroundJoinNotification(String title, String content, List receiverTokens); + void sendNotification( + String title, + Map contents, + NotificationType notificationType, + List receiverTokens + ); } diff --git a/backend/src/main/java/com/happy/friendogly/notification/service/PlaygroundNotificationService.java b/backend/src/main/java/com/happy/friendogly/notification/service/PlaygroundNotificationService.java index c2a26972c..5791e6732 100644 --- a/backend/src/main/java/com/happy/friendogly/notification/service/PlaygroundNotificationService.java +++ b/backend/src/main/java/com/happy/friendogly/notification/service/PlaygroundNotificationService.java @@ -1,6 +1,7 @@ package com.happy.friendogly.notification.service; import com.happy.friendogly.notification.domain.DeviceToken; +import com.happy.friendogly.notification.domain.NotificationType; import com.happy.friendogly.notification.repository.DeviceTokenRepository; import com.happy.friendogly.playground.domain.PlaygroundMember; import java.util.List; @@ -10,24 +11,30 @@ @Service public class PlaygroundNotificationService { - private final String DEFAULT_TITLE = "반갑개"; + private static final String DEFAULT_TITLE = "반갑개"; private final DeviceTokenRepository deviceTokenRepository; private final NotificationService notificationService; - public PlaygroundNotificationService(DeviceTokenRepository deviceTokenRepository, - NotificationService notificationService) { + public PlaygroundNotificationService( + DeviceTokenRepository deviceTokenRepository, + NotificationService notificationService + ) { this.deviceTokenRepository = deviceTokenRepository; this.notificationService = notificationService; } - public void sendJoinNotification(String newParticipatingMember, - List existingParticipatingMembers) { + public void sendJoinNotification( + String newParticipatingMember, + List existingParticipatingMembers + ) { List deviceTokens = toDeviceToken(existingParticipatingMembers); String content = newParticipatingMember + "님이 놀이터에 참여했습니다"; - notificationService.sendPlaygroundJoinNotification(DEFAULT_TITLE, + notificationService.sendNotification( + DEFAULT_TITLE, content, + NotificationType.PLAYGROUND, deviceTokens ); } diff --git a/backend/src/test/java/com/happy/friendogly/notification/service/FcmNotificationServiceTest.java b/backend/src/test/java/com/happy/friendogly/notification/service/FcmNotificationServiceTest.java index e22f21e37..03de21bc6 100644 --- a/backend/src/test/java/com/happy/friendogly/notification/service/FcmNotificationServiceTest.java +++ b/backend/src/test/java/com/happy/friendogly/notification/service/FcmNotificationServiceTest.java @@ -7,6 +7,7 @@ import com.google.firebase.FirebaseApp; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.FirebaseMessagingException; +import com.happy.friendogly.notification.domain.NotificationType; import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -31,7 +32,7 @@ class FcmNotificationServiceTest { @Test void sendFootprintNotification() throws FirebaseMessagingException { // when - fcmNotificationService.sendFootprintNotification("title", "content", List.of()); + fcmNotificationService.sendNotification("title", "content", NotificationType.FOOTPRINT, List.of()); // then verify(firebaseMessaging, never()).sendEachForMulticast(any());