Skip to content

Commit

Permalink
[FEATURE] 푸시 알림 스케쥴링 구현 (#153)
Browse files Browse the repository at this point in the history
* feat : 푸시알림 스케쥴링 구현 #149

* feat : 푸시알림 스케쥴링 시간대 조정 #149
  • Loading branch information
bongsh0112 authored Jan 20, 2024
1 parent 782e08d commit 2bd25ce
Show file tree
Hide file tree
Showing 16 changed files with 114 additions and 51 deletions.
10 changes: 1 addition & 9 deletions Api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,10 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation ('org.springdoc:springdoc-openapi-ui:1.6.12'){
dependencies {
implementation('com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.4')
implementation('com.fasterxml.jackson.core:jackson-core:2.13.4')
implementation('com.fasterxml.jackson.core:jackson-databind:2.13.4')
implementation('com.fasterxml.jackson.core:jackson-annotations:2.13.4')
}
}
implementation 'org.springdoc:springdoc-openapi-ui:1.6.12'
// implementation 'io.springfox:springfox-boot-starter:3.0.0'
implementation 'org.springframework.boot:spring-boot-starter-security'
// implementation 'com.slack.api:slack-api-client:1.27.2'
implementation 'io.github.jav:expo-server-sdk:1.1.0'
implementation project(':Domain')
implementation project(':Core')
implementation project(':Infrastructure')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.transaction.annotation.Transactional;
import tify.server.api.alarm.model.dto.CreateKnockEventDto;
import tify.server.api.config.security.SecurityUtils;
import tify.server.core.annotation.UseCase;
import tify.server.domain.domains.alarm.dto.CreateKnockEventDto;
import tify.server.domain.domains.question.adaptor.KnockAdaptor;
import tify.server.domain.domains.question.domain.Knock;
import tify.server.domain.domains.question.validator.QuestionValidator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import tify.server.api.alarm.model.dto.AnswerKnockEventDto;
import tify.server.api.config.security.SecurityUtils;
import tify.server.api.question.model.request.PostAnswerRequest;
import tify.server.core.annotation.UseCase;
import tify.server.domain.domains.alarm.dto.AnswerKnockEventDto;
import tify.server.domain.domains.question.domain.Knock;
import tify.server.domain.domains.question.service.DailyQuestionDomainService;
import tify.server.domain.domains.question.validator.QuestionValidator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.transaction.annotation.Transactional;
import tify.server.api.alarm.model.dto.ReceiveApplicationEventDto;
import tify.server.api.config.security.SecurityUtils;
import tify.server.core.annotation.UseCase;
import tify.server.domain.domains.alarm.dto.ReceiveApplicationEventDto;
import tify.server.domain.domains.user.adaptor.NeighborAdaptor;
import tify.server.domain.domains.user.domain.Neighbor;
import tify.server.domain.domains.user.domain.NeighborApplication;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.transaction.annotation.Transactional;
import tify.server.api.alarm.model.dto.SendApplicationEventDto;
import tify.server.api.config.security.SecurityUtils;
import tify.server.core.annotation.UseCase;
import tify.server.domain.domains.alarm.dto.SendApplicationEventDto;
import tify.server.domain.domains.user.adaptor.NeighborAdaptor;
import tify.server.domain.domains.user.adaptor.UserAdaptor;
import tify.server.domain.domains.user.domain.NeighborApplication;
Expand Down
1 change: 1 addition & 0 deletions Domain/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ dependencies {
api 'org.springframework.boot:spring-boot-starter-data-jpa'
api 'org.springframework.boot:spring-boot-starter-validation'
api 'mysql:mysql-connector-java:8.0.32'
implementation 'io.github.jav:expo-server-sdk:1.1.0'
runtimeOnly 'com.h2database:h2'
implementation project(':Core')
implementation project(':Infrastructure')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tify.server.api.utils;
package tify.server.domain.common.util;


import io.github.jav.exposerversdk.ExpoPushMessage;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tify.server.api.alarm.model.dto;
package tify.server.domain.domains.alarm.dto;


import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tify.server.api.alarm.model.dto;
package tify.server.domain.domains.alarm.dto;


import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tify.server.api.alarm.model.dto;
package tify.server.domain.domains.alarm.dto;


import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tify.server.api.alarm.model.dto;
package tify.server.domain.domains.alarm.dto;


import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package tify.server.api.alarm.service;
package tify.server.domain.domains.alarm.service;

import static tify.server.domain.domains.alarm.domain.AlarmType.*;
import static tify.server.domain.domains.alarm.domain.AlarmType.ANNIVERSARY;
import static tify.server.domain.domains.alarm.domain.AlarmType.FAVOR;
import static tify.server.domain.domains.alarm.domain.AlarmType.FRIEND;
import static tify.server.domain.domains.alarm.domain.AlarmType.TODAY;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.TextStyle;
import java.util.HashMap;
import java.util.List;
Expand All @@ -12,26 +13,28 @@
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import tify.server.api.alarm.model.dto.AnswerKnockEventDto;
import tify.server.api.alarm.model.dto.CreateKnockEventDto;
import tify.server.api.alarm.model.dto.ReceiveApplicationEventDto;
import tify.server.api.alarm.model.dto.SendApplicationEventDto;
import tify.server.api.utils.AlarmHistoryUtils;
import tify.server.core.annotation.UseCase;
import tify.server.core.annotation.DomainService;
import tify.server.domain.common.util.AlarmHistoryUtils;
import tify.server.domain.domains.alarm.dto.AnswerKnockEventDto;
import tify.server.domain.domains.alarm.dto.CreateKnockEventDto;
import tify.server.domain.domains.alarm.dto.ReceiveApplicationEventDto;
import tify.server.domain.domains.alarm.dto.SendApplicationEventDto;
import tify.server.domain.domains.question.adaptor.AnswerAdaptor;
import tify.server.domain.domains.question.adaptor.DailyQuestionAdaptor;
import tify.server.domain.domains.question.adaptor.FavorQuestionAdaptor;
import tify.server.domain.domains.question.adaptor.KnockAdaptor;
import tify.server.domain.domains.question.domain.DailyQuestion;
import tify.server.domain.domains.user.adaptor.NeighborAdaptor;
import tify.server.domain.domains.user.adaptor.UserAdaptor;
import tify.server.domain.domains.user.domain.User;

@UseCase
@DomainService
@Transactional
@RequiredArgsConstructor
public class CreateAlarmHistoryUseCase {
public class AlarmHistoryDomainService {

private final UserAdaptor userAdaptor;
private final NeighborAdaptor neighborAdaptor;
private final DailyQuestionAdaptor dailyQuestionAdaptor;
private final AnswerAdaptor answerAdaptor;
private final KnockAdaptor knockAdaptor;
Expand Down Expand Up @@ -137,25 +140,26 @@ public void executeToNotAnsweredQuestionAlarm(Long questionId) {
}

@Async
public void executeToFriendBirthDayAlarm(Long userId) {
LocalDateTime today = LocalDateTime.now(ZoneId.of("Asia/Seoul"));
String monthAndYear =
String.format("%02d%02d", today.getMonth().getValue(), today.getDayOfMonth() + 4);
public void executeToFriendBirthDayAlarm(List<User> expectedBirthdayUserList) {
String content = "취향에 딱 맞는 선물을 받을 확률을 올려보세요!\n티피 프로필 공유하러 가기 >";

List<User> birthDayNeighbors = userAdaptor.queryBirthDayNeighbors(userId, monthAndYear);

birthDayNeighbors.forEach(
expectedBirthdayUserList.forEach(
user -> {
String title =
String.format(
"%s님의 생일이 4일 밖에 안남았대요! ", user.getProfile().getUserName());
if (alarmHistoryUtils.checkUserReceiveAlarm(
user, title, content, ANNIVERSARY)) {
HashMap<String, Object> newMap = new HashMap<>();
newMap.put("neighborUserId", user.getUserId());
alarmHistoryUtils.sendMessage(user, title, content, newMap, ANNIVERSARY);
}
userAdaptor
.queryNeighborsByUserId(user.getId())
.forEach(
neighbor -> {
if (alarmHistoryUtils.checkUserReceiveAlarm(
neighbor, title, content, ANNIVERSARY)) {
HashMap<String, Object> newMap = new HashMap<>();
newMap.put("neighborUserId", neighbor.getUserId());
alarmHistoryUtils.sendMessage(
neighbor, title, content, newMap, ANNIVERSARY);
}
});
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,15 @@ public List<User> queryBirthDayUsers() {
return userRepository.getBirthDayUserList();
}

public List<User> queryBirthDayNeighbors(Long userId, String monthAndYear) {
return userRepository.getBirthDayNeighborList(userId, monthAndYear);
public List<User> queryNeighborsByUserId(Long userId) {
return userRepository.getNeighborListByUserId(userId);
}

public List<User> queryNotTotallyFavorAnsweredUsers(int favorQuestionSize) {
return userRepository.getNotFavorAnsweredUserList(favorQuestionSize);
}

public List<User> queryExpectedBirthdayUsers(String monthAndYear) {
return userRepository.getBirthDayUserListByDate(monthAndYear);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ public interface UserCustomRepository {

List<User> getBirthDayUserList();

List<User> getBirthDayNeighborList(Long userId, String monthAndYear);
List<User> getBirthDayUserListByDate(String monthAndYear);

List<User> getNeighborListByUserId(Long userId);

List<User> getNotFavorAnsweredUserList(int favorQuestionSize);
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,22 @@ public List<User> getBirthDayUserList() {
}

@Override
public List<User> getBirthDayNeighborList(Long userId, String monthAndYear) {
public List<User> getBirthDayUserListByDate(String monthAndYear) {
return jpaQueryFactory
.selectFrom(user)
.where(user.profile.birth.contains(monthAndYear))
.fetch();
}

@Override
public List<User> getNeighborListByUserId(Long userId) {
return jpaQueryFactory
.selectFrom(user)
.join(neighbor)
.on(user.id.eq(neighbor.toUserId))
.leftJoin(userResign)
.on(neighbor.toUserId.eq(userResign.userId))
.where(
neighbor.fromUserId.eq(userId),
user.profile.birth.contains(monthAndYear),
userResign.userId.isNull())
.where(neighbor.fromUserId.eq(userId), userResign.userId.isNull())
.orderBy(neighbor.order.asc())
.fetch();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package tify.server.domain.scheduler.alarm;


import java.time.LocalDate;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import tify.server.domain.domains.alarm.service.AlarmHistoryDomainService;
import tify.server.domain.domains.question.adaptor.DailyQuestionAdaptor;
import tify.server.domain.domains.question.domain.DailyQuestion;
import tify.server.domain.domains.user.adaptor.UserAdaptor;
import tify.server.domain.domains.user.domain.User;

@Component
@RequiredArgsConstructor
public class AlarmScheduler {

private final UserAdaptor userAdaptor;
private final DailyQuestionAdaptor dailyQuestionAdaptor;
private final AlarmHistoryDomainService alarmHistoryDomainService;

@Transactional
@Scheduled(cron = "0 0 17 * * SUN", zone = "Asia/Seoul")
public void executeToNotAnsweredQuestionAlarm() {
LocalDate today = LocalDate.now();
DailyQuestion dailyQuestion = dailyQuestionAdaptor.queryByLoadingDate(today);
alarmHistoryDomainService.executeToNotAnsweredQuestionAlarm(dailyQuestion.getId());
}

@Transactional
@Scheduled(cron = "0 0 21 * *", zone = "Asia/Seoul")
public void executeToFriendBirthDayAlarm() {
LocalDate fourDaysLater = LocalDate.now().plusDays(4);
String monthAndYear =
String.format(
"%02d%02d",
fourDaysLater.getMonth().getValue(), fourDaysLater.getDayOfMonth());
List<User> expectedBirthdayUserList = userAdaptor.queryExpectedBirthdayUsers(monthAndYear);
alarmHistoryDomainService.executeToFriendBirthDayAlarm(expectedBirthdayUserList);
}

@Transactional
@Scheduled(cron = "0 0 10 * *", zone = "Asia/Seoul")
public void executeToBirthDayAlarm() {
alarmHistoryDomainService.executeToBirthDayAlarm();
}

@Transactional
@Scheduled(cron = "0 0 18 7 *", zone = "Asia/Seoul")
public void executeToFavorAlarm() {
alarmHistoryDomainService.executeToFavorAlarm();
}
}

0 comments on commit 2bd25ce

Please sign in to comment.