-
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.
Merge pull request #26 from VOM-Project/feature/webpush
feat: FCM push message API
- Loading branch information
Showing
14 changed files
with
457 additions
and
1 deletion.
There are no files selected for viewing
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
46 changes: 46 additions & 0 deletions
46
src/main/java/vom/spring/domain/webpush/ApiResponseWrapper.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,46 @@ | ||
package vom.spring.domain.webpush; | ||
|
||
import lombok.Getter; | ||
|
||
@Getter | ||
public class ApiResponseWrapper<T> { | ||
private int resultCode; | ||
private String resultMsg; | ||
private T result; | ||
|
||
// Builder 클래스를 사용하여 객체를 더 쉽게 생성할 수 있도록 합니다 | ||
public static <T> Builder<T> builder() { | ||
return new Builder<>(); | ||
} | ||
|
||
public static class Builder<T> { | ||
private int resultCode; | ||
private String resultMsg; | ||
private T result; | ||
|
||
public Builder<T> resultCode(int resultCode) { | ||
this.resultCode = resultCode; | ||
return this; | ||
} | ||
|
||
public Builder<T> resultMsg(String resultMsg) { | ||
this.resultMsg = resultMsg; | ||
return this; | ||
} | ||
|
||
public Builder<T> result(T result) { | ||
this.result = result; | ||
return this; | ||
} | ||
|
||
public ApiResponseWrapper<T> build() { | ||
ApiResponseWrapper<T> response = new ApiResponseWrapper<>(); | ||
response.resultCode = this.resultCode; | ||
response.resultMsg = this.resultMsg; | ||
response.result = this.result; | ||
return response; | ||
} | ||
} | ||
|
||
// Getter 및 Setter 메소드는 필요에 따라 추가합니다. | ||
} |
37 changes: 37 additions & 0 deletions
37
src/main/java/vom/spring/domain/webpush/FcmController.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,37 @@ | ||
package vom.spring.domain.webpush; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.validation.annotation.Validated; | ||
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 java.io.IOException; | ||
|
||
@Slf4j | ||
@RestController | ||
@RequestMapping("/api/v1/fcm") | ||
public class FcmController { | ||
private final FcmService fcmService; | ||
|
||
public FcmController(FcmService fcmService) { | ||
this.fcmService = fcmService; | ||
} | ||
|
||
@PostMapping("/send") | ||
public ResponseEntity<ApiResponseWrapper<Object>> pushMessage(@RequestBody @Validated FcmSendDto fcmSendDto) throws IOException, IOException { | ||
log.debug("[+] 푸시 메시지를 전송합니다. "); | ||
int result = fcmService.sendMessageTo(fcmSendDto); | ||
|
||
ApiResponseWrapper<Object> arw = ApiResponseWrapper | ||
.builder() | ||
.result(result) | ||
.resultCode(SuccessCode.SELECT_SUCCESS.getStatus()) | ||
.resultMsg(SuccessCode.SELECT_SUCCESS.getMessage()) | ||
.build(); | ||
return new ResponseEntity<>(arw, HttpStatus.OK); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
src/main/java/vom/spring/domain/webpush/FcmMessageDto.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,29 @@ | ||
package vom.spring.domain.webpush; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@Builder | ||
public class FcmMessageDto { | ||
private boolean validateOnly; | ||
private FcmMessageDto.Message message; | ||
|
||
@Builder | ||
@AllArgsConstructor | ||
@Getter | ||
public static class Message { | ||
private FcmMessageDto.Notification notification; | ||
private String token; | ||
} | ||
|
||
@Builder | ||
@AllArgsConstructor | ||
@Getter | ||
public static class Notification { | ||
private String title; | ||
private String body; | ||
private String image; | ||
} | ||
} |
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,21 @@ | ||
package vom.spring.domain.webpush; | ||
|
||
import lombok.*; | ||
|
||
@Getter | ||
@ToString | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class FcmSendDto { | ||
private String token; | ||
|
||
private String title; | ||
|
||
private String body; | ||
|
||
@Builder(toBuilder = true) | ||
public FcmSendDto(String token, String title, String body) { | ||
this.token = token; | ||
this.title = title; | ||
this.body = body; | ||
} | ||
} |
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,12 @@ | ||
package vom.spring.domain.webpush; | ||
|
||
import org.springframework.stereotype.Service; | ||
|
||
import java.io.IOException; | ||
|
||
@Service | ||
public class FcmService { | ||
int sendMessageTo(FcmSendDto fcmSendDto) throws IOException { | ||
return 0; | ||
} | ||
} |
82 changes: 82 additions & 0 deletions
82
src/main/java/vom/spring/domain/webpush/FcmServiceImpl.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 vom.spring.domain.webpush; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.google.auth.oauth2.GoogleCredentials; | ||
import org.springframework.core.io.ClassPathResource; | ||
import org.springframework.http.*; | ||
import org.springframework.web.client.RestTemplate; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
|
||
public class FcmServiceImpl extends FcmService { | ||
/** | ||
* 푸시 메시지 처리를 수행하는 비즈니스 로직 | ||
* | ||
* @param fcmSendDto 모바일에서 전달받은 Object | ||
* @return 성공(1), 실패(0) | ||
*/ | ||
@Override | ||
public int sendMessageTo(FcmSendDto fcmSendDto) throws IOException { | ||
|
||
String message = makeMessage(fcmSendDto); | ||
RestTemplate restTemplate = new RestTemplate(); | ||
|
||
HttpHeaders headers = new HttpHeaders(); | ||
headers.set("Content-Type", "application/json"); | ||
headers.set("Authorization", "Bearer " + getAccessToken()); | ||
|
||
HttpEntity entity = new HttpEntity<>(message, headers); | ||
|
||
String API_URL = "https://fcm.googleapis.com/v1/projects/vomvom-fd09b/messages:send"; | ||
// String API_URL = "https://fcm.googleapis.com/fcm/send"; | ||
|
||
ResponseEntity response = restTemplate.exchange(API_URL, HttpMethod.POST, entity, String.class); | ||
|
||
return response.getStatusCode() == HttpStatus.OK ? 1 : 0; | ||
} | ||
|
||
/** | ||
* Firebase Admin SDK의 비공개 키를 참조하여 Bearer 토큰을 발급 받습니다. | ||
* | ||
* playground에서 발급받은 토큰 | ||
* | ||
* @return Bearer token | ||
*/ | ||
private String getAccessToken() throws IOException { | ||
String firebaseConfigPath = "firebase/vomvom-fd09b-firebase-adminsdk-ghtjs-0070b39a4e.json"; | ||
|
||
GoogleCredentials googleCredentials = GoogleCredentials | ||
.fromStream(new ClassPathResource(firebaseConfigPath).getInputStream()) | ||
.createScoped(List.of("https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/firebase.messaging")); | ||
|
||
googleCredentials.refreshIfExpired(); | ||
|
||
System.out.println(googleCredentials.getAccessToken()); | ||
|
||
return googleCredentials.getAccessToken().getTokenValue(); | ||
} | ||
|
||
/** | ||
* FCM 전송 정보를 기반으로 메시지를 구성합니다. (Object -> String) | ||
* | ||
* @param fcmSendDto FcmSendDto | ||
* @return String | ||
*/ | ||
private String makeMessage(FcmSendDto fcmSendDto) throws JsonProcessingException { | ||
|
||
ObjectMapper om = new ObjectMapper(); | ||
FcmMessageDto fcmMessageDto = FcmMessageDto.builder() | ||
.message(FcmMessageDto.Message.builder() | ||
.token(fcmSendDto.getToken()) | ||
.notification(FcmMessageDto.Notification.builder() | ||
.title(fcmSendDto.getTitle()) | ||
.body(fcmSendDto.getBody()) | ||
.image(null) | ||
.build() | ||
).build()).validateOnly(false).build(); | ||
|
||
return om.writeValueAsString(fcmMessageDto); | ||
} | ||
} |
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,23 @@ | ||
package vom.spring.domain.webpush; | ||
|
||
public enum SuccessCode { | ||
SELECT_SUCCESS(200, "데이터 조회 성공"), | ||
UPDATE_SUCCESS(200, "데이터 업데이트 성공"), | ||
CREATE_SUCCESS(201, "데이터 생성 성공"); | ||
|
||
private final int status; | ||
private final String message; | ||
|
||
SuccessCode(int status, String message) { | ||
this.status = status; | ||
this.message = message; | ||
} | ||
|
||
public int getStatus() { | ||
return status; | ||
} | ||
|
||
public String getMessage() { | ||
return message; | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
src/main/java/vom/spring/domain/webpush/controller/WebpushController.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,48 @@ | ||
package vom.spring.domain.webpush.controller; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import vom.spring.domain.webpush.dto.WebpushDto; | ||
import vom.spring.domain.webpush.service.WebpushService; | ||
|
||
import java.util.List; | ||
|
||
@RestController | ||
@Controller | ||
public class WebpushController { | ||
private WebpushService webpushService; | ||
@Autowired | ||
public WebpushController(WebpushService webpushService) { | ||
this.webpushService = webpushService; | ||
} | ||
|
||
@GetMapping(value = "/api/webpush/{member-id}") | ||
public ResponseEntity<List<WebpushDto>> getWebpushes( | ||
@PathVariable("member-id") Long memberId | ||
) { | ||
return new ResponseEntity<>(webpushService.getWebpushes(memberId), HttpStatus.OK); | ||
} | ||
|
||
// @PostMapping("/api/webpush/send") | ||
// public String sendNotification( | ||
// @RequestBody NotificationRequest request) | ||
// { | ||
// webpushService.sendNotification(request.getTargetToken(), request.getTitle(), request.getBody()); | ||
// return "Notification sent successfully!"; | ||
// } | ||
// | ||
// @Getter | ||
// public static class NotificationRequest { | ||
// private String targetToken; | ||
// private String title; | ||
// private String body; | ||
// | ||
// // Getters and Setters | ||
// } | ||
|
||
} |
38 changes: 38 additions & 0 deletions
38
src/main/java/vom/spring/domain/webpush/domain/Webpush.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,38 @@ | ||
package vom.spring.domain.webpush.domain; | ||
|
||
import jakarta.persistence.*; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import vom.spring.domain.member.domain.Member; | ||
import vom.spring.domain.webcam.domain.Status; | ||
import vom.spring.domain.webcam.domain.Webcam; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
@Getter | ||
@Builder | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Entity | ||
public class Webpush { | ||
|
||
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
@Column(nullable = false) | ||
private LocalDateTime createdAt; | ||
|
||
@ManyToOne | ||
@JoinColumn(referencedColumnName = "id", name = "from_member_id", nullable = false) | ||
private Member fromMember; | ||
|
||
@ManyToOne | ||
@JoinColumn(referencedColumnName = "id", name = "to_member_id", nullable = false) | ||
private Member toMember; | ||
|
||
// @OneToOne | ||
// @JoinColumn(referencedColumnName = "id", name = "webcam_id", nullable = false) | ||
// private Webcam webcam; | ||
} |
18 changes: 18 additions & 0 deletions
18
src/main/java/vom/spring/domain/webpush/dto/WebpushDto.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,18 @@ | ||
package vom.spring.domain.webpush.dto; | ||
|
||
import lombok.Getter; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
@Getter | ||
public class WebpushDto { | ||
private Long fromMemberId; | ||
private LocalDateTime createdAt; | ||
// private Long webcamId; | ||
|
||
public WebpushDto(Long fromMemberId, LocalDateTime createdAt) { | ||
this.fromMemberId = fromMemberId; | ||
this.createdAt = createdAt; | ||
// this.webcamId = webcamId; | ||
} | ||
} |
Oops, something went wrong.