diff --git a/src/main/java/org/terning/fcm/api/PushNotificationController.java b/src/main/java/org/terning/fcm/api/PushNotificationController.java new file mode 100644 index 0000000..b01b70a --- /dev/null +++ b/src/main/java/org/terning/fcm/api/PushNotificationController.java @@ -0,0 +1,22 @@ +package org.terning.fcm.api; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.terning.fcm.application.PushNotificationService; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/push-notifications") +public class PushNotificationController { + + private final PushNotificationService pushNotificationService; + + @PostMapping("/send-all") + public ResponseEntity sendAllPushNotifications(){ + pushNotificationService.sendAllPendingNotifications(); + return ResponseEntity.ok().build(); + } +} diff --git a/src/main/java/org/terning/fcm/application/FcmPushSender.java b/src/main/java/org/terning/fcm/application/FcmPushSender.java new file mode 100644 index 0000000..eaa4355 --- /dev/null +++ b/src/main/java/org/terning/fcm/application/FcmPushSender.java @@ -0,0 +1,8 @@ +package org.terning.fcm.application; + +import org.terning.notification.domain.Notification; + +public interface FcmPushSender { + + boolean send(Notification notification); +} diff --git a/src/main/java/org/terning/fcm/application/FcmPushSenderImpl.java b/src/main/java/org/terning/fcm/application/FcmPushSenderImpl.java new file mode 100644 index 0000000..068369a --- /dev/null +++ b/src/main/java/org/terning/fcm/application/FcmPushSenderImpl.java @@ -0,0 +1,37 @@ +package org.terning.fcm.application; + +import com.google.firebase.messaging.FirebaseMessaging; +import com.google.firebase.messaging.FirebaseMessagingException; +import com.google.firebase.messaging.Message; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.terning.notification.domain.Notification; +import org.terning.user.domain.User; + +@Service +@Slf4j +@RequiredArgsConstructor +public class FcmPushSenderImpl implements FcmPushSender { + + @Override + public boolean send(Notification notification) { + try { + User user = notification.getUser(); + String token = user.getToken().value(); + + Message fcmMessage = Message.builder() + .setToken(token) + .putData("title", notification.getMessage().getMain()) + .putData("body", notification.getMessage().getSub()) + .build(); + + String response = FirebaseMessaging.getInstance().send(fcmMessage); + log.info("FCM 메세지 전송 성공, 응답 ID: {}", response); + return true; + } catch (FirebaseMessagingException e) { + log.error("FCM 메세지 전송 실패: {}", e.getMessage(), e); + return false; + } + } +} diff --git a/src/main/java/org/terning/fcm/application/PushNotificationService.java b/src/main/java/org/terning/fcm/application/PushNotificationService.java new file mode 100644 index 0000000..482178f --- /dev/null +++ b/src/main/java/org/terning/fcm/application/PushNotificationService.java @@ -0,0 +1,34 @@ +package org.terning.fcm.application; + +import java.time.LocalDateTime; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.terning.notification.domain.Notification; +import org.terning.notification.domain.NotificationsRepository; + +@Service +@RequiredArgsConstructor +public class PushNotificationService { + + private final NotificationsRepository notificationsRepository; + private final FcmPushSender fcmPushSender; + + @Transactional + public void sendAllPendingNotifications() { + List pendingNotifications = notificationsRepository.findAll().stream() + .filter(notification -> !notification.isSent() && + notification.isDue(LocalDateTime.now())) + .toList(); + + for (Notification notification : pendingNotifications) { + boolean sent = fcmPushSender.send(notification); + if (sent) { + notification.markSent(); + } + //TODO : 실패한 경우 예외처리 추가 + } + notificationsRepository.saveAll(pendingNotifications); + } +} diff --git a/src/main/java/org/terning/user/application/UserService.java b/src/main/java/org/terning/user/application/UserService.java index 23ea508..16f665d 100644 --- a/src/main/java/org/terning/user/application/UserService.java +++ b/src/main/java/org/terning/user/application/UserService.java @@ -36,6 +36,7 @@ public void updateFcmToken(Long userId, UpdateFcmTokenRequest request) { fcmTokenUpdateService.updateFcmToken(userId, request.newToken()); } + @Transactional public void createUser(CreateUserRequest request) { PushNotificationStatus pushStatus = PushNotificationStatus.from(request.pushStatus()); AccountStatus accountStatus = AccountStatus.from(request.accountStatus());