Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import org.jenga.dantong.friend.service.FriendService;
import org.jenga.dantong.global.auth.jwt.AppAuthentication;
import org.jenga.dantong.global.base.UserAuth;
import org.jenga.dantong.notification.service.FcmService;
import org.jenga.dantong.survey.model.dto.response.TicketResponse;
import org.jenga.dantong.user.exception.UserNotFoundException;
import org.jenga.dantong.user.repository.UserRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
Expand All @@ -26,12 +28,16 @@
public class FriendController {
private final UserRepository userRepository;
private final FriendService friendService;
private final FcmService fcmService;

@UserAuth
@PostMapping("/send/{studentId}")
@Operation(summary = "친구 요청 보내기", description = "학번으로 친구 요청 보내기")
public void sendRequest(@Valid @PathVariable("studentId") String studentId, AppAuthentication auth) {
userRepository.findByStudentId(studentId)
.orElseThrow(UserNotFoundException::new);
friendService.sendRequest(studentId, auth.getUserId());
fcmService.sendFriendNotification(studentId);
}

@UserAuth
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.jenga.dantong.notification.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

@Configuration
@EnableScheduling
class SchedulerConfig {
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(3);
scheduler.setThreadNamePrefix("my-scheduler-task");
scheduler.initialize();
return scheduler;
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
package org.jenga.dantong.notification.controller;

import com.google.firebase.messaging.FirebaseMessagingException;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jenga.dantong.global.auth.jwt.AppAuthentication;
import org.jenga.dantong.global.base.UserAuth;
import org.jenga.dantong.notification.model.dto.request.NotificationGlobalRequest;
import org.jenga.dantong.notification.model.dto.request.NotificationRequest;
import org.jenga.dantong.notification.model.dto.request.TokenRegisterRequest;
import org.jenga.dantong.notification.model.dto.response.NotificationResponse;
import org.jenga.dantong.notification.service.FcmService;
import org.jenga.dantong.user.exception.UserNotFoundException;
import org.jenga.dantong.user.model.entity.User;
import org.jenga.dantong.user.repository.UserRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RequestMapping("/notification")
Expand All @@ -28,17 +31,33 @@ public class NotificationController {
@UserAuth
@PostMapping("/register")
@Operation(summary = "FCM 토큰 등록하기", description = "리액트에서 발급받은 토큰 입력")
public void register(@RequestBody NotificationRequest request, AppAuthentication auth) {
public void register(@RequestBody TokenRegisterRequest request, AppAuthentication auth) {
fcmService.register(request);
}

@UserAuth
@PostMapping("/send")
@Operation(summary = "백그라운드 알림 테스트")
public void send(AppAuthentication auth) {
public void send(@RequestBody NotificationRequest request, AppAuthentication auth) {
User user = userRepository.findById(auth.getUserId())
.orElseThrow(UserNotFoundException::new);
fcmService.sendSubmitNotification(user.getStudentId());
fcmService.sendNotification(request);
}

@UserAuth
@PostMapping("/sendGlobal")
@Operation(summary = "전체 알림 테스트")
public void sendGlobal(@RequestBody NotificationGlobalRequest request, AppAuthentication auth) throws FirebaseMessagingException {
userRepository.findById(auth.getUserId())
.orElseThrow(UserNotFoundException::new);
fcmService.sendGlobalNotification(request);
}

@UserAuth
@GetMapping("/getNotification")
@Operation(summary = "로그인 된 사용자에게 보내진 알림 내역 확인하기")
public ResponseEntity<Page<NotificationResponse>> getNotification(AppAuthentication auth, Pageable pageable) {
return ResponseEntity.ok(fcmService.getNotifications(auth.getUserId(), pageable));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.jenga.dantong.notification.model.dto.request;

import lombok.*;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class NotificationGlobalRequest {
private String title;
private String body;
private String url;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
package org.jenga.dantong.notification.model.dto.request;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.*;

import java.time.LocalDateTime;

@Getter
@Setter
@NoArgsConstructor
@Builder
public class NotificationRequest {
private String studentId;
private String token;
private String title;
private String body;
private String url;

public NotificationRequest(String studentId, String title, String body, String url) {
this.studentId = studentId;
this.title = title;
this.body = body;
this.url = url;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.jenga.dantong.notification.model.dto.request;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalDateTime;

@Getter
@Builder
public class NotificationScheduleRequest {
private String studentId;
private String title;
private String body;
@Setter
private LocalDateTime sentAt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.jenga.dantong.notification.model.dto.request;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class TokenRegisterRequest {
private String studentId;
private String token;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.jenga.dantong.notification.model.dto.response;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class NotificationResponse {
String title;
String body;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.jenga.dantong.notification.model.entity;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.jenga.dantong.global.base.BaseEntity;
import org.jenga.dantong.user.model.entity.User;

@Entity
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class FcmNotification extends BaseEntity {

@Id
@GeneratedValue
private Long id;

@ManyToOne
@JoinColumn(name = "user_id")
private User user;

private String title;
private String body;
private String url;

public FcmNotification(User user, String title, String body, String url) {
this.user = user;
this.title = title;
this.body = body;
this.url = url;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.jenga.dantong.notification.repository;

import org.jenga.dantong.notification.model.entity.FcmNotification;
import org.jenga.dantong.user.model.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface FcmNotificationRepository extends JpaRepository<FcmNotification, Long> {
Page<FcmNotification> findByUser(User user, Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
package org.jenga.dantong.notification.repository;

import lombok.RequiredArgsConstructor;
import org.jenga.dantong.notification.model.dto.request.NotificationRequest;
import org.jenga.dantong.user.model.dto.request.LoginRequest;
import org.jenga.dantong.notification.model.dto.request.TokenRegisterRequest;
import org.jenga.dantong.user.repository.UserRepository;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Objects;

@Repository
@RequiredArgsConstructor
public class FcmRepository {

private final StringRedisTemplate tokenRedisTemplate;
private final UserRepository userRepository;

public void saveToken(NotificationRequest request) {
public void saveToken(TokenRegisterRequest request) {
tokenRedisTemplate.opsForValue()
.set(request.getStudentId(), request.getToken());
}
Expand All @@ -28,4 +32,13 @@ public void deleteToken(String studentId) {
public boolean hasKey(String studentId) {
return tokenRedisTemplate.hasKey(studentId);
}

public List<String> getAllTokens() {

return userRepository.findAll()
.stream()
.filter(user -> getToken(user.getStudentId()) != null)
.map(user -> getToken(user.getStudentId()))
.toList();
}
}
Loading