Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: FCM 발송방식 수정 #333

Merged
merged 4 commits into from
Apr 8, 2024
Merged
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
6 changes: 6 additions & 0 deletions .github/pr-labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
기능: feature/*
버그: fix/*
리팩터링: refactor/*
문서: docs/*
테스트: test/*
인프라: infra/*
12 changes: 12 additions & 0 deletions .github/workflows/pr-labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: PR Labeler
on:
pull_request:
types: [ opened ]

jobs:
pr-labeler:
runs-on: ubuntu-latest
steps:
- uses: TimonVS/pr-labeler-action@v4
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
package in.koreatech.koin.global.domain.notification.model;

import static jakarta.persistence.EnumType.STRING;
import static jakarta.persistence.FetchType.LAZY;
import static jakarta.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;

import in.koreatech.koin.domain.user.model.User;
import in.koreatech.koin.global.domain.BaseEntity;
import in.koreatech.koin.global.fcm.MobileAppPath;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import static jakarta.persistence.EnumType.STRING;
import jakarta.persistence.Enumerated;
import static jakarta.persistence.FetchType.LAZY;
import jakarta.persistence.GeneratedValue;
import static jakarta.persistence.GenerationType.IDENTITY;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import static lombok.AccessLevel.PROTECTED;
import lombok.Getter;
import lombok.NoArgsConstructor;

Expand All @@ -27,8 +29,9 @@ public class Notification extends BaseEntity {
@GeneratedValue(strategy = IDENTITY)
private Long id;

@Column(name = "url", nullable = false)
private String url;
@Enumerated(STRING)
@Column(name = "app_path", nullable = false)
private MobileAppPath mobileAppPath;

@Column(name = "title", nullable = false)
private String title;
Expand All @@ -51,14 +54,14 @@ public class Notification extends BaseEntity {
private boolean isRead = false;

public Notification(
String url,
MobileAppPath appPath,
String title,
String message,
String imageUrl,
NotificationType type,
User user
) {
this.url = url;
this.mobileAppPath = appPath;
this.title = title;
this.message = message;
this.imageUrl = imageUrl;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
package in.koreatech.koin.global.domain.notification.model;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import in.koreatech.koin.domain.user.model.User;
import in.koreatech.koin.global.fcm.MobileAppPath;

@Component
public class NotificationFactory {

private final String koinAppUrl;

public NotificationFactory(
@Value("${fcm.koin.url}") String koinAppUrl
) {
this.koinAppUrl = koinAppUrl;
}

public Notification generateOwnerNotification(
MobileAppPath path,
String shopName,
User target
) {
return new Notification(
koinAppUrl,
path,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

모바일 path로 변경하셨군요

"새로운 이벤트가 개설되었어요!",
"%s 가게의 이벤트가 오픈되었어요!🎁"
.formatted(shopName),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@

import in.koreatech.koin.domain.user.model.User;
import in.koreatech.koin.domain.user.repository.UserRepository;
import in.koreatech.koin.global.domain.notification.model.NotificationSubscribe;
import in.koreatech.koin.global.domain.notification.dto.NotificationStatusResponse;
import in.koreatech.koin.global.domain.notification.dto.NotificationSubscribePermitRequest;
import in.koreatech.koin.global.domain.notification.model.Notification;
import in.koreatech.koin.global.domain.notification.model.NotificationSubscribe;
import in.koreatech.koin.global.domain.notification.model.NotificationSubscribeType;
import in.koreatech.koin.global.domain.notification.repository.NotificationRepository;
import in.koreatech.koin.global.domain.notification.repository.NotificationSubscribeRepository;
Expand All @@ -34,7 +34,7 @@ public void push(Notification notification) {
notification.getTitle(),
notification.getMessage(),
notification.getImageUrl(),
notification.getUrl(),
notification.getMobileAppPath(),
notification.getType()
);
}
Expand Down
86 changes: 71 additions & 15 deletions src/main/java/in/koreatech/koin/global/fcm/FcmClient.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package in.koreatech.koin.global.fcm;

import static com.google.firebase.messaging.AndroidConfig.Priority.HIGH;

import java.util.Map;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import com.google.firebase.messaging.AndroidConfig;
import com.google.firebase.messaging.AndroidNotification;
import com.google.firebase.messaging.ApnsConfig;
import com.google.firebase.messaging.ApnsFcmOptions;
import com.google.firebase.messaging.Aps;
import com.google.firebase.messaging.ApsAlert;
import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.Message;
import com.google.firebase.messaging.Notification;

import static com.google.firebase.messaging.AndroidConfig.Priority.HIGH;
import lombok.extern.slf4j.Slf4j;

@Slf4j
Expand All @@ -21,32 +28,81 @@ public void sendMessage(
String title,
String content,
String imageUrl,
String url,
MobileAppPath path,
String type
) {
if (targetDeviceToken == null) {
return;
}
log.info("call FcmClient sendMessage: title: {}, content: {}", title, content);
Notification notification = Notification.builder()
.setTitle(title)
.setBody(content)
.setImage(imageUrl)
.build();

AndroidConfig androidConfig = generateAndroidConfig(title, content, imageUrl, path, type);
ApnsConfig apnsConfig = generateAppleConfig(title, content, imageUrl, path, type);

Message message = Message.builder()
.setToken(targetDeviceToken)
.setNotification(notification)
.putData("url", url)
.putData("type", type)
.setAndroidConfig(AndroidConfig.builder()
.setPriority(HIGH)
.build()
).build();
.setApnsConfig(apnsConfig)
.setAndroidConfig(androidConfig).build();
try {
String result = FirebaseMessaging.getInstance().send(message);
log.info("FCM 알림 전송 성공: {}", result);
} catch (Exception e) {
log.warn("FCM 알림 전송 실패", e);
}
}

private ApnsConfig generateAppleConfig(
String title,
String content,
String imageUrl,
MobileAppPath path,
String type
) {
return ApnsConfig.builder()
.setAps(
Aps.builder()
.setAlert(
ApsAlert.builder()
.setTitle(title)
.setBody(content)
.build()
)
.setSound("default")
.setCategory(path.getApple())
.setMutableContent(true)
.build()
)
.setFcmOptions(
ApnsFcmOptions.builder()
.setImage(imageUrl)
.build()
)
.putAllCustomData(
Map.of(
"type", type
)
)
.build();
}

private AndroidConfig generateAndroidConfig(
String title,
String content,
String imageUrl,
MobileAppPath path,
String type
) {
AndroidNotification androidNotification = AndroidNotification.builder()
.setTitle(title)
.setBody(content)
.setImage(imageUrl)
.setClickAction(path.getAndroid())
.build();

return AndroidConfig.builder()
.setNotification(androidNotification)
.putData("type", type)
.setPriority(HIGH)
.build();
}
}
18 changes: 18 additions & 0 deletions src/main/java/in/koreatech/koin/global/fcm/MobileAppPath.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package in.koreatech.koin.global.fcm;

import lombok.Getter;

@Getter
public enum MobileAppPath {
HOME("home", "home"),
LOGIN("login", "login"),
;

private final String android;
private final String apple;

MobileAppPath(String android, String apple) {
this.android = android;
this.apple = apple;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE `notification`
CHANGE COLUMN url app_path VARCHAR(255);
Loading