11package devkor .ontime_back .service ;
22
3- import com .google .firebase .messaging .FirebaseMessaging ;
4- import com .google .firebase .messaging .Message ;
53import devkor .ontime_back .entity .NotificationSchedule ;
64import devkor .ontime_back .entity .Schedule ;
7- import devkor .ontime_back .entity .User ;
8- import devkor .ontime_back .entity .UserSetting ;
9- import devkor .ontime_back .repository .NotificationScheduleRepository ;
10- import devkor .ontime_back .repository .UserSettingRepository ;
115import lombok .RequiredArgsConstructor ;
126import lombok .extern .slf4j .Slf4j ;
137import org .springframework .scheduling .TaskScheduler ;
14- import org .springframework .scheduling .annotation .Async ;
15- import org .springframework .scheduling .annotation .EnableAsync ;
168import org .springframework .stereotype .Service ;
17- import org .springframework .transaction .annotation .Transactional ;
189
1910import java .time .LocalDateTime ;
2011import java .time .ZoneId ;
2617@ Slf4j
2718@ Service
2819@ RequiredArgsConstructor
29- @ Transactional (readOnly = true )
3020public class NotificationService {
3121
32- private final UserSettingRepository userSettingRepository ;
33- private final AlarmService alarmService ;
3422 private final TaskScheduler taskScheduler ;
35- private final NotificationScheduleRepository notificationScheduleRepository ;
23+ private final NotificationDispatchService notificationDispatchService ;
24+ private final NotificationDeliveryService notificationDeliveryService ;
3625 private final ConcurrentHashMap <Long , ScheduledFuture <?>> scheduledTasks = new ConcurrentHashMap <>();
3726
3827 public void scheduleReminder (NotificationSchedule notificationSchedule ) {
@@ -43,12 +32,19 @@ public void scheduleReminder(NotificationSchedule notificationSchedule) {
4332 return ;
4433 }
4534
35+ Long notificationId = notificationSchedule .getId ();
36+ if (notificationId == null ) {
37+ throw new IllegalArgumentException ("NotificationSchedule must be persisted before scheduling" );
38+ }
39+
4640 ScheduledFuture <?> future = taskScheduler .schedule (
47- () -> sendReminder (notificationSchedule , "준비 시작해야 합니다.(현재 시각: 약속시각 - (여유시간 + 이동시간 + 총준비시간) )" ),
41+ () -> notificationDispatchService .dispatchReminder (
42+ notificationId ,
43+ "준비 시작해야 합니다.(현재 시각: 약속시각 - (여유시간 + 이동시간 + 총준비시간) )" ),
4844 Date .from (reminderTime .atZone (ZoneId .systemDefault ()).toInstant ())
4945 );
5046
51- scheduledTasks .put (notificationSchedule . getId () , future );
47+ scheduledTasks .put (notificationId , future );
5248
5349 log .info ("스케줄 등록 완료 {} ({})" , notificationSchedule .getSchedule ().getScheduleName (), reminderTime );
5450 }
@@ -62,64 +58,15 @@ public void cancelScheduledNotification(Long notificationId) {
6258 }
6359 }
6460
65- @ Async
66- @ Transactional
6761 public void sendReminder (NotificationSchedule notificationSchedule , String message ) {
68- Long userId = notificationSchedule .getSchedule ().getUser ().getId ();
69-
70- if (userId != null ) {
71- UserSetting userSetting = userSettingRepository .findByUserId (userId )
72- .orElseThrow (() -> new IllegalArgumentException ("No UserSetting found in schedule's user" ));
73- log .debug ("사용자 알림 전송 설정 여부: " + userSetting .getIsNotificationsEnabled ());
74-
75- if (Boolean .TRUE .equals (userSetting .getIsNotificationsEnabled ())) {
76- if (alarmService .shouldSuppressLegacyReminder (
77- userId ,
78- notificationSchedule .getSchedule ().getScheduleId (),
79- notificationSchedule .getNotificationTime ())) {
80- log .info ("현재 기기 로컬 알람 커버리지로 인해 레거시 푸시 알림을 생략합니다. scheduleId={}" ,
81- notificationSchedule .getSchedule ().getScheduleId ());
82- return ;
83- }
84- sendNotificationToUser (notificationSchedule .getSchedule (), message );
85- notificationSchedule .changeStatusToSent ();
86- notificationScheduleRepository .save (notificationSchedule );
87- }
88- }
62+ notificationDeliveryService .sendReminder (notificationSchedule , message );
8963 }
9064
9165 public void sendReminder (List <Schedule > schedules , String message ) {
92- for (Schedule schedule : schedules ) {
93- User user = schedule .getUser ();
94- Long userId = user .getId ();
95-
96- if (userId != null ) {
97- UserSetting userSetting = userSettingRepository .findByUserId (userId )
98- .orElseThrow (() -> new IllegalArgumentException ("No UserSetting found in schedule's user" ));// Repository 메서드 가정
99-
100- if (userSetting != null && userSetting .getIsNotificationsEnabled ()) {
101- sendNotificationToUser (schedule , message );
102- }
103- }
104- }
66+ notificationDeliveryService .sendReminder (schedules , message );
10567 }
10668
107- @ Transactional
10869 public void sendNotificationToUser (Schedule schedule , String message ) {
109- User user = schedule .getUser ();
110- String firebaseToken = user .getFirebaseToken ();
111-
112- Message firebaseMessage = Message .builder ()
113- .putData ("title" , "약속 알림" )
114- .putData ("content" , user .getName () + "님 " + message + "\n 약속명: " + schedule .getScheduleName ())
115- .setToken (firebaseToken )
116- .build ();
117-
118- try {
119- FirebaseMessaging .getInstance ().send (firebaseMessage );
120- log .info ("Firebase에 성공적으로 push notification 요청을 보냈으며, Firebase로부터 적절한 응답을 받았습니다 \n 알림 푸시한 약속:" + schedule .getScheduleName ());
121- } catch (Exception e ) {
122- e .printStackTrace ();
123- }
70+ notificationDeliveryService .sendNotificationToUser (schedule , message );
12471 }
12572}
0 commit comments