Skip to content

Commit

Permalink
Merge pull request #311 from Modagbul/main
Browse files Browse the repository at this point in the history
업데이트 리마인드 푸시알림 컨트롤러로 생성
  • Loading branch information
seungueonn authored Sep 11, 2024
2 parents fd62732 + 5b3dc87 commit 5a1ae45
Show file tree
Hide file tree
Showing 16 changed files with 98 additions and 58 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/CD-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ jobs:

steps:
# 소스 코드 체크아웃
- uses: actions/checkout@v2
- uses: actions/checkout@v4

# JDK 11 설정
- name: Set up JDK 11
uses: actions/setup-java@v2
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'adopt'

# Gradle 패키지 캐시
- name: Cache Gradle packages
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
Expand All @@ -49,17 +49,17 @@ jobs:
echo "${{env.APPLE_KEY}}" > ./apple-key.p8
# 설정 파일을 작업공간에 저장
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: application.yml
path: ./src/main/resources/application.yml

- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: firebase-key.json
path: ./src/main/resources/firebase-key.json

- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: apple-key.p8
path: ./src/main/resources/apple-key.p8
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/CD-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:

steps:
# 소스 코드 체크아웃
- uses: actions/checkout@v2
- uses: actions/checkout@v4

# JDK 11 설정
- name: Set up JDK 11
Expand All @@ -29,7 +29,7 @@ jobs:

# Gradle 패키지 캐시
- name: Cache Gradle packages
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
Expand All @@ -49,17 +49,17 @@ jobs:
echo "${{env.APPLE_KEY}}" > ./apple-key.p8
# 설정 파일을 작업공간에 저장
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: application.yml
path: ./src/main/resources/application.yml

- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: firebase-key.json
path: ./src/main/resources/firebase-key.json

- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: apple-key.p8
path: ./src/main/resources/apple-key.p8
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/CI-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ jobs:

steps:
# 소스 코드 체크아웃
- uses: actions/checkout@v2
- uses: actions/checkout@v4

# JDK 11 설정
- name: Set up JDK 11
uses: actions/setup-java@v2
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'adopt'

# Gradle 패키지 캐시
- name: Cache Gradle packages
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
Expand All @@ -50,17 +50,17 @@ jobs:
echo "${{env.APPLE_KEY}}" > ./apple-key.p8
# 설정 파일을 작업공간에 저장
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: application.yml
path: ./src/main/resources/application.yml

- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: firebase-key.json
path: ./src/main/resources/firebase-key.json

- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: apple-key.p8
path: ./src/main/resources/apple-key.p8
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/CI-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ jobs:

steps:
# 소스 코드 체크아웃
- uses: actions/checkout@v2
- uses: actions/checkout@v4

# JDK 11 설정
- name: Set up JDK 11
uses: actions/setup-java@v2
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'adopt'

# Gradle 패키지 캐시
- name: Cache Gradle packages
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
Expand All @@ -50,17 +50,17 @@ jobs:
echo "${{env.APPLE_KEY}}" > ./apple-key.p8
# 설정 파일을 작업공간에 저장
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: application.yml
path: ./src/main/resources/application.yml

- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: firebase-key.json
path: ./src/main/resources/firebase-key.json

- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: apple-key.p8
path: ./src/main/resources/apple-key.p8
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ dependencies {
implementation 'com.google.code.gson:gson:2.8.7'

// Push Alarm
implementation 'com.google.firebase:firebase-admin:8.2.0'
implementation 'com.google.firebase:firebase-admin:9.2.0'
implementation 'com.google.firebase:firebase-messaging:23.0.0'

// RestDocs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class AlarmHistoryController {

private final GetAlarmHistoryUseCase getAlarmHistoryUseCase;
private final ReadAlarmHistoryUseCase readAlarmHistoryUseCase;

/**
* 알림 전체 조회
* [GET] api/history/alarm
Expand Down Expand Up @@ -52,4 +53,6 @@ public ResponseEntity<SuccessResponse> readAlarmHistory(@AuthenticationPrincipal
public ResponseEntity<SuccessResponse<GetAlarmCountResponse>> getUnreadAlarmCount(@AuthenticationPrincipal User user) {
return ResponseEntity.ok(SuccessResponse.create(GET_UNREAD_ALARM_HISTORY.getMessage(), getAlarmHistoryUseCase.getUnreadAlarmCount(user.getSocialId())));
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -38,41 +38,30 @@ public class UpdateRemindAlarmUseCase {
String REMIND_NAME = "미션 리마인드";


public Boolean sendUpdateAppPushAlarm() {
public void sendUpdateAppPushAlarm(String title, String message) {

String title = "MOING 업데이트 소식";
String message = "이제 사진 인증에 설명을 추가할 수 있어요. 지금 업데이트하고 다른 소식도 확인해보세요!";
// String title = "MOING 업데이트 소식";
// String message = "이제 누구나 미션을 만들 수 있어요. 지금 업데이트하고 다른 소식도 확인해보세요!";

List<Member> allMemberOfPushAlarm = memberGetService.getAllMemberOfPushAlarm();
long count = memberGetService.getAllMemberOfPushAlarm(0L, Long.MAX_VALUE).size();

// TODO : 500명 단위 배치처리
for (Long offset = 0L; offset < count; offset += 499) {

// FCM 제한으로 500명씩 나눠서 보내기 (0~498)
List<Member> firstMembers = allMemberOfPushAlarm.subList(0, 498);
Long limit = offset+499;

Optional<List<MemberIdAndToken>> memberIdAndTokens = mapToMemberAndToken(firstMembers);
Optional<List<MemberIdAndToken>> pushMemberIdAndToken = isPushMemberIdAndToken(firstMembers);
List<Member> allMemberOfPushAlarm = memberGetService.getAllMemberOfPushAlarm(offset, limit);

if (pushMemberIdAndToken.isPresent() && !pushMemberIdAndToken.get().isEmpty()) {
multiMessageSender.send(new MultiRequest(pushMemberIdAndToken.get(), title, message, "", REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue()));
}
if (memberIdAndTokens.isPresent() && !memberIdAndTokens.get().isEmpty()) {
saveMultiAlarmHistoryUseCase.saveAlarmHistories(AlarmHistoryMapper.getMemberIds(memberIdAndTokens.get()), "", title, message, REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue());
}

// FCM 제한으로 500명씩 나눠서 보내기 (498~)
List<Member> remainMembers = allMemberOfPushAlarm.subList(499, allMemberOfPushAlarm.size());
Optional<List<MemberIdAndToken>> memberIdAndTokens = mapToMemberAndToken(allMemberOfPushAlarm);
Optional<List<MemberIdAndToken>> pushMemberIdAndToken = isPushMemberIdAndToken(allMemberOfPushAlarm);

Optional<List<MemberIdAndToken>> memberIdAndTokens2 = mapToMemberAndToken(remainMembers);
Optional<List<MemberIdAndToken>> pushMemberIdAndToken2 = isPushMemberIdAndToken(remainMembers);

if (pushMemberIdAndToken2.isPresent() && !pushMemberIdAndToken2.get().isEmpty()) {
multiMessageSender.send(new MultiRequest(pushMemberIdAndToken2.get(), title, message, "", REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue()));
}
if (memberIdAndTokens2.isPresent() && !memberIdAndTokens2.get().isEmpty()) {
saveMultiAlarmHistoryUseCase.saveAlarmHistories(AlarmHistoryMapper.getMemberIds(memberIdAndTokens2.get()), "", title, message, REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue());
if (pushMemberIdAndToken.isPresent() && !pushMemberIdAndToken.get().isEmpty()) {
multiMessageSender.send(new MultiRequest(pushMemberIdAndToken.get(), title, message, "", REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue()));
}
if (memberIdAndTokens.isPresent() && !memberIdAndTokens.get().isEmpty()) {
saveMultiAlarmHistoryUseCase.saveAlarmHistories(AlarmHistoryMapper.getMemberIds(memberIdAndTokens.get()), "", title, message, REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue());
}
}
return true;


}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ public interface MemberCustomRepository {
Optional<Member> findNotDeletedByMemberId(Long id);
Long getTodayNewMembers();
Long getYesterdayNewMembers();
Optional<List<Member>> findAllMemberOnPushAlarm();

Optional<List<Member>> findAllMemberOnPushAlarm(Long offset, Long limit);
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,16 @@ public Long getYesterdayNewMembers() {
}

@Override
public Optional<List<Member>> findAllMemberOnPushAlarm() {
public Optional<List<Member>> findAllMemberOnPushAlarm(Long offset, Long limit) {
return Optional.ofNullable(
queryFactory.selectFrom(member)
.where(
member.isDeleted.eq(false),
member.isRemindPush.eq(true),
member.isSignOut.eq(false)
)
.offset(offset)
.limit(limit)
.fetch()
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@

import com.moing.backend.domain.member.domain.entity.Member;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MemberRepository extends JpaRepository<Member, Long>, MemberCustomRepository {

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public Long getYesterdayNewMembers(){
}


public List<Member> getAllMemberOfPushAlarm() {
return memberRepository.findAllMemberOnPushAlarm().orElseThrow(NotFoundRemindAlarmException::new);
public List<Member> getAllMemberOfPushAlarm(Long offset, Long limit) {
return memberRepository.findAllMemberOnPushAlarm(offset,limit).orElseThrow(NotFoundRemindAlarmException::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.moing.backend.domain.member.dto.request;

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

@Getter
@AllArgsConstructor
@NoArgsConstructor
public class PostUpdatePushAlarm {

private String title;
private String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.moing.backend.domain.member.presentation;

import com.moing.backend.domain.member.application.service.UpdateRemindAlarmUseCase;
import com.moing.backend.domain.member.dto.request.PostUpdatePushAlarm;
import com.moing.backend.global.config.security.dto.User;
import com.moing.backend.global.response.SuccessResponse;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
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;

@RestController
@AllArgsConstructor
@RequestMapping("/api/remind/alarm")
public class RemindAlarmController {

private final UpdateRemindAlarmUseCase updateRemindAlarmUseCase;


@PostMapping("/update")
public ResponseEntity<SuccessResponse<Void>> postUpdateRemindAlarm(@AuthenticationPrincipal User user , @RequestBody PostUpdatePushAlarm postUpdatePushAlarm) {
updateRemindAlarmUseCase.sendUpdateAppPushAlarm(postUpdatePushAlarm.getTitle(), postUpdatePushAlarm.getMessage());
return ResponseEntity.ok(SuccessResponse.create("remindAlarm Done"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ public class MissionScheduleUseCase {

private final MissionRemindAlarmUseCase missionRemindAlarmUseCase;
private final MissionUpdateUseCase missionUpdateUseCase;
private final UpdateRemindAlarmUseCase updateRemindAlarmUseCase;

/**
* 단일 미션 마감
Expand All @@ -43,5 +42,4 @@ public void singleMissionEndRoutine() {
public void MissionRemindAlarm() {
missionRemindAlarmUseCase.sendRemindMissionAlarm();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public static NotificationException handleFirebaseMessagingException(FirebaseMes
case "UNAVAILABLE":
return new NotificationException("서비스를 사용할 수 없습니다: " + errorMessage);
default:
e.printStackTrace();
return new NotificationException("메시지 전송에 실패했습니다: " + errorMessage);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ public void send(MultiRequest request) {
.build();

try {
BatchResponse response = firebaseMessaging.sendMulticast(message);
// BatchResponse response = firebaseMessaging.sendMulticast(message);
BatchResponse response = firebaseMessaging.sendEachForMulticast(message);


List<String> failedTokens = new ArrayList<>();
Expand Down

0 comments on commit 5a1ae45

Please sign in to comment.