-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
#333 fcmUtils, 알림 비동기 처리
- Loading branch information
Showing
4 changed files
with
112 additions
and
69 deletions.
There are no files selected for viewing
74 changes: 19 additions & 55 deletions
74
src/main/java/com/example/icebutler_server/alarm/service/NotificationServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,88 +1,52 @@ | ||
package com.example.icebutler_server.alarm.service; | ||
|
||
import com.example.icebutler_server.alarm.dto.FcmMessage; | ||
import com.example.icebutler_server.alarm.entity.PushNotification; | ||
import com.example.icebutler_server.alarm.repository.PushNotificationRepository; | ||
import com.example.icebutler_server.global.util.Constant; | ||
import com.example.icebutler_server.global.util.FcmUtils; | ||
import com.example.icebutler_server.user.entity.User; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.google.auth.oauth2.GoogleCredentials; | ||
import lombok.RequiredArgsConstructor; | ||
import okhttp3.*; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.springframework.boot.json.JsonParseException; | ||
import org.springframework.core.io.ClassPathResource; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
@Transactional(readOnly = true) | ||
public class NotificationServiceImpl implements NotificationService { | ||
private final String API_URL = "https://fcm.googleapis.com/v1/projects/icebutler-46914/messages:send"; | ||
private final ObjectMapper objectMapper; | ||
|
||
private final PushNotificationRepository notificationRepository; | ||
private final FcmUtils fcmUtils; | ||
|
||
|
||
// TODO 냉장고 유저 탈퇴 로직 리팩 후 호출 | ||
@Transactional | ||
@Override | ||
public void sendWithdrawalAlarm(User user, String fridgeName) throws JsonParseException, IOException { | ||
String messageBody = fridgeName+"에서 탈퇴되었습니다."; | ||
if(user.getFcmToken()!=null){ | ||
FcmMessage message = FcmMessage.makeMessage(user.getFcmToken(), Constant.PushNotification.FRIDGE, messageBody); | ||
Response response = sendMessage(objectMapper.writeValueAsString(message)); | ||
this.notificationRepository.save(PushNotification.toEntity(Constant.PushNotification.FRIDGE, messageBody, user)); | ||
public void sendWithdrawalAlarm(User user, String fridgeName) { | ||
String messageBody = fridgeName + "에서 탈퇴되었습니다."; | ||
if (user.getFcmToken() != null) { | ||
fcmUtils.sendMessage((user.getFcmToken()), Constant.PushNotification.FRIDGE, messageBody); | ||
} | ||
this.notificationRepository.save(PushNotification.toEntity(Constant.PushNotification.FRIDGE, messageBody, user)); | ||
} | ||
// TODO 냉장고 유저 초대 리펙 후 호출 | ||
|
||
@Transactional | ||
@Override | ||
public void sendJoinFridgeAlarm(User user, String fridgeName) throws IOException { | ||
String messageBody = fridgeName+"에서 초대되었습니다."; | ||
if(user.getFcmToken()!=null) { | ||
FcmMessage message = FcmMessage.makeMessage(user.getFcmToken(), Constant.PushNotification.FRIDGE, messageBody); | ||
Response response = sendMessage(objectMapper.writeValueAsString(message)); | ||
this.notificationRepository.save(PushNotification.toEntity(Constant.PushNotification.FRIDGE, messageBody, user)); | ||
public void sendJoinFridgeAlarm(User user, String fridgeName) { | ||
String messageBody = fridgeName + "에서 초대되었습니다."; | ||
if (user.getFcmToken() != null) { | ||
fcmUtils.sendMessage((user.getFcmToken()), Constant.PushNotification.FRIDGE, messageBody); | ||
} | ||
this.notificationRepository.save(PushNotification.toEntity(Constant.PushNotification.FRIDGE, messageBody, user)); | ||
} | ||
|
||
@Transactional | ||
@Override | ||
public void sendShelfLifeAlarm(User user, String fridgeName, String foodName) throws IOException { | ||
String messageBody = foodName+" 소비기한이 임박해요!"; | ||
if(user.getFcmToken()!=null) { | ||
FcmMessage message = FcmMessage.makeMessage(user.getFcmToken(), fridgeName, messageBody); | ||
Response response = sendMessage(objectMapper.writeValueAsString(message)); | ||
this.notificationRepository.save(PushNotification.toEntity(fridgeName, messageBody, user)); | ||
String messageBody = foodName + " 소비기한이 임박해요!"; | ||
if (user.getFcmToken() != null) { | ||
fcmUtils.sendMessage((user.getFcmToken()), fridgeName, messageBody); | ||
} | ||
} | ||
|
||
|
||
@NotNull | ||
private Response sendMessage(String message) throws IOException { | ||
OkHttpClient client = new OkHttpClient(); | ||
RequestBody requestBody = RequestBody.create(message, | ||
MediaType.get("application/json; charset=utf-8")); | ||
Request request = new Request.Builder() | ||
.url(API_URL) | ||
.post(requestBody) | ||
.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + getAccessToken()) | ||
.addHeader(HttpHeaders.CONTENT_TYPE, "application/json; UTF-8") | ||
.build(); | ||
|
||
return client.newCall(request).execute(); | ||
} | ||
|
||
private String getAccessToken() throws IOException { | ||
String firebaseConfigPath = "firebase/firebase_service_key.json"; | ||
GoogleCredentials googleCredentials = GoogleCredentials | ||
.fromStream(new ClassPathResource(firebaseConfigPath).getInputStream()) | ||
.createScoped(List.of("https://www.googleapis.com/auth/cloud-platform")); | ||
googleCredentials.refreshIfExpired(); | ||
return googleCredentials.getAccessToken().getTokenValue(); | ||
this.notificationRepository.save(PushNotification.toEntity(fridgeName, messageBody, user)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
src/main/java/com/example/icebutler_server/global/util/FcmUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package com.example.icebutler_server.global.util; | ||
|
||
import com.example.icebutler_server.alarm.dto.FcmMessage; | ||
import com.example.icebutler_server.global.exception.BaseException; | ||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.google.auth.oauth2.GoogleCredentials; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import okhttp3.*; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.springframework.core.io.ClassPathResource; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
|
||
import static com.example.icebutler_server.global.exception.ReturnCode.FIREBASE_SERVER_ERROR; | ||
|
||
@Slf4j | ||
@Component | ||
@RequiredArgsConstructor | ||
public class FcmUtils { | ||
public static final String FIREBASE_CONFIG_PATH = "firebase/firebase_service_key.json"; | ||
public static final String NOTIFICATION_SCOPE = "https://www.googleapis.com/auth/cloud-platform"; | ||
public static final String MEDIA_TYPE_JSON_UTF_8 = "application/json; charset=utf-8"; | ||
public static final String CONTENT_TYPE_JSON_UTF_8 = "application/json; UTF-8"; | ||
private static final String API_URL = "https://fcm.googleapis.com/v1/projects/icebutler-46914/messages:send"; | ||
public static final String BEARER = "Bearer "; | ||
|
||
private final ObjectMapper objectMapper; | ||
|
||
public void sendMessage(String targetToken, String title, String body) { | ||
String message = makeMessage(targetToken, title, body); | ||
|
||
OkHttpClient client = new OkHttpClient(); | ||
RequestBody requestBody = RequestBody.create(message, MediaType.get(MEDIA_TYPE_JSON_UTF_8)); | ||
Request request = new Request.Builder() | ||
.url(API_URL) | ||
.post(requestBody) | ||
.addHeader(HttpHeaders.AUTHORIZATION, BEARER + getAccessToken()) | ||
.addHeader(HttpHeaders.CONTENT_TYPE, CONTENT_TYPE_JSON_UTF_8) | ||
.build(); | ||
|
||
client.newCall(request).enqueue(new Callback() { | ||
@Override | ||
public void onFailure(@NotNull Call call, @NotNull IOException e) { | ||
log.info("알림 실패: ", e.toString()); | ||
throw new BaseException(FIREBASE_SERVER_ERROR); | ||
} | ||
|
||
@Override | ||
public void onResponse(@NotNull Call call, @NotNull Response response) { | ||
log.info("알림 성공: ", response.body().toString()); | ||
} | ||
}); | ||
|
||
} | ||
|
||
public String makeMessage(String targetToken, String title, String body) { | ||
try { | ||
FcmMessage message = FcmMessage.makeMessage(targetToken, title, body); | ||
return objectMapper.writeValueAsString(message); | ||
} catch (JsonProcessingException e) { | ||
throw new BaseException(FIREBASE_SERVER_ERROR); | ||
} | ||
} | ||
|
||
private String getAccessToken() { | ||
try { | ||
GoogleCredentials googleCredentials = GoogleCredentials | ||
.fromStream(new ClassPathResource(FIREBASE_CONFIG_PATH).getInputStream()) | ||
.createScoped(List.of(NOTIFICATION_SCOPE)); | ||
googleCredentials.refreshIfExpired(); | ||
return googleCredentials.getAccessToken().getTokenValue(); | ||
} catch (IOException e) { | ||
throw new BaseException(FIREBASE_SERVER_ERROR); | ||
} | ||
} | ||
|
||
} |