diff --git a/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Auth/Repository/AuthRepository.java b/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Auth/Repository/AuthRepository.java index ac4b2bb..05077de 100644 --- a/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Auth/Repository/AuthRepository.java +++ b/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Auth/Repository/AuthRepository.java @@ -18,4 +18,6 @@ public interface AuthRepository extends JpaRepository { // User로 Auth 삭제 void deleteByUser(User user); + + Auth findByKakaoRefreshToken(String token); } \ No newline at end of file diff --git a/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/controller/KakaoController.java b/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/controller/KakaoController.java index 2818820..6afca67 100644 --- a/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/controller/KakaoController.java +++ b/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/controller/KakaoController.java @@ -1,8 +1,12 @@ package Baemin.News_Deliver.Domain.Kakao.controller; +import Baemin.News_Deliver.Domain.Auth.Entity.Auth; +import Baemin.News_Deliver.Domain.Auth.Repository.AuthRepository; +import Baemin.News_Deliver.Domain.Kakao.Exception.KakaoException; import Baemin.News_Deliver.Domain.Kakao.service.KakaoMessageService; import Baemin.News_Deliver.Domain.Kakao.service.KakaoNewsService; import Baemin.News_Deliver.Domain.Kakao.service.KakaoSchedulerService; +import Baemin.News_Deliver.Global.Exception.ErrorCode; import Baemin.News_Deliver.Global.News.ElasticSearch.dto.NewsEsDocument; import Baemin.News_Deliver.Global.ResponseObject.ApiResponseWrapper; import lombok.RequiredArgsConstructor; @@ -10,6 +14,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.util.ArrayList; import java.util.List; @RestController @@ -18,9 +23,12 @@ @RequestMapping("/kakao") public class KakaoController { + + private final KakaoMessageService kakaoMessageService; private final KakaoNewsService newsSearchService; private final KakaoSchedulerService kakaoSchedulerService; + private final AuthRepository authRepository; /** * 카카오톡 나에게 보내기 메시지 전송 메서드 @@ -28,23 +36,51 @@ public class KakaoController { @GetMapping("/send-message") public ResponseEntity> sendMessage() { - try { - boolean success = kakaoMessageService.sendKakaoMessage(); + //전체 유저의 정보를 받아, RefreshToken 가져옴. + List allUsers = authRepository.findAll(); + List allUsersRefreshToken = allUsers.stream() + .map(Auth::getKakaoRefreshToken) + .toList(); + + log.info("유저 RefreshToken 확인" + allUsersRefreshToken); + + + // 1차 전송 실패시 저장되는 토큰 + List failedTokens = new ArrayList<>(); + for (String token : allUsersRefreshToken) { + try { + Auth auth = authRepository.findByKakaoRefreshToken(token); + Long userId = auth.getUser().getId(); + + log.info("유저 정보 확인용!!!!!! "); - if (success) { - return ResponseEntity.ok(new ApiResponseWrapper<>("SUCCESS", "뉴스 메시지 전송 성공")); - } else { - return ResponseEntity.internalServerError() - .body(new ApiResponseWrapper<>(null, "뉴스 메시지 전송 실패")); + kakaoMessageService.sendKakaoMessage(token, userId); + } catch (KakaoException e) { + failedTokens.add(token); } + } + + // 2차 실패 토큰 (2차 시도까지 실패한 경우만) + List finalFailedTokens = new ArrayList<>(); + for (String token : failedTokens) { + try { + Auth auth = authRepository.findByKakaoRefreshToken(token); + Long userId = auth.getUser().getId(); + kakaoMessageService.sendKakaoMessage(token, userId); + } catch (KakaoException e) { + finalFailedTokens.add(token); + } + } - } catch (Exception e) { - log.error("메시지 전송 중 오류 발생: ", e); - return ResponseEntity.internalServerError() - .body(new ApiResponseWrapper<>(null, "메시지 전송 중 오류 발생: " + e.getMessage())); + if (!finalFailedTokens.isEmpty()) { + log.error("카카오 메시지 전송 실패 토큰 : {}", finalFailedTokens); + throw new KakaoException(ErrorCode.MESSAGE_SEND_FAILED); } + + return ResponseEntity.ok(new ApiResponseWrapper<>("SUCCESS", "모든 유저에게 메시지 전송 성공")); } + //테스트용 코드 @GetMapping("/search-news") public ResponseEntity> searchNews() { @@ -56,6 +92,7 @@ public ResponseEntity> searchNews() { @GetMapping("/getcron") public ResponseEntity getcron() { - return ResponseEntity.ok(kakaoSchedulerService.getCron()); + Long userId = 1L; + return ResponseEntity.ok(kakaoSchedulerService.getCron(userId)); } } \ No newline at end of file diff --git a/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoMessageService.java b/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoMessageService.java index 9c0179f..1bcc1bf 100644 --- a/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoMessageService.java +++ b/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoMessageService.java @@ -39,7 +39,6 @@ public class KakaoMessageService { private final RestTemplate restTemplate = new RestTemplate(); private final KakaoNewsService newsService; private final SettingService settingService; - private final UserRepository userRepository; private final NewsRepository newsRepository; private final SettingRepository settingRepository; private final HistoryRepository historyRepository; @@ -55,25 +54,26 @@ public class KakaoMessageService { /** * 현재 로그인한 카카오 유저의 Access Token을 가져옴 */ - public String getKakaoUserAccessToken() { + public String getKakaoUserAccessToken(String refreshAccessToken, Long userId) { + //유저의 accesstoken을 가져 올 것 - String accessToken = provider.refreshAccessToken("4YxBGonTT2Q6OyFlgF4HXDbMZpVSbzCwAAAAAgoNDSEAAAGYDIqbUFIZRy9oVvUS"); + String accessToken = provider.refreshAccessToken(refreshAccessToken); if (accessToken == null || accessToken.isEmpty()) { throw new RuntimeException("Access Token을 가져올 수 없습니다."); } - getNewsEsDocumentList(); + getNewsEsDocumentList(userId); return accessToken; } /** * 메시지 전송 메서드 */ - public boolean sendKakaoMessage() { + public boolean sendKakaoMessage(String refreshAccessToken, Long userId) { try { - String accessToken = getKakaoUserAccessToken(); + String accessToken = getKakaoUserAccessToken(refreshAccessToken, userId); - List newsList = getNewsEsDocumentList(); + List newsList = getNewsEsDocumentList(userId); if (newsList == null) return false; // 헤더 설정 @@ -110,10 +110,9 @@ public boolean sendKakaoMessage() { * * @return NewsEsDocument의 리스트 */ - private List getNewsEsDocumentList() { + private List getNewsEsDocumentList(Long userId) { //유저 정보를 기준으로 Settig값 가져오기 - Long userId = 1L; List settings = settingService.getAllSettingsByUserId(userId); List keywords = new ArrayList<>(); diff --git a/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoSchedulerService.java b/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoSchedulerService.java index 24dfce4..f28336d 100644 --- a/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoSchedulerService.java +++ b/SpringBoot/src/main/java/Baemin/News_Deliver/Domain/Kakao/service/KakaoSchedulerService.java @@ -32,8 +32,7 @@ public class KakaoSchedulerService { 7, "SUN" ); - public List getCron() { - Long userId = 1L; + public List getCron(Long userId) { List settings = settingService.getAllSettingsByUserId(userId); List crons = new ArrayList<>(); diff --git a/SpringBoot/src/main/java/Baemin/News_Deliver/Global/Exception/ErrorCode.java b/SpringBoot/src/main/java/Baemin/News_Deliver/Global/Exception/ErrorCode.java index bdbf8b6..57d2161 100644 --- a/SpringBoot/src/main/java/Baemin/News_Deliver/Global/Exception/ErrorCode.java +++ b/SpringBoot/src/main/java/Baemin/News_Deliver/Global/Exception/ErrorCode.java @@ -43,9 +43,15 @@ public enum ErrorCode { // Setting 관련 - SETTING_NOT_FOUND("SETTING_ERROR_901", "설정을 찾을 수 없습니다", HttpStatus.NOT_FOUND); + SETTING_NOT_FOUND("SETTING_ERROR_901", "설정을 찾을 수 없습니다", HttpStatus.NOT_FOUND), /* HotTopic 예외 : 7xx */ + + + /* Kakao 예외 : 8xx */ + MESSAGE_SEND_FAILED("KAKAO_ERROR_801", "카카오 메시지 전송 실패", HttpStatus.INTERNAL_SERVER_ERROR); + + /* Mypage 예외 : 9xx */ /* SubServices 예외 : 10xx */