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

[요양보호사/보호자] coolSMS API를 사용하여 SMS 알림 기능 구현하기 #87

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
48bc923
refactor : 알림 예약 수정 부분 삭제하기
pykido Nov 4, 2024
d34723b
feat : 알림 전용 테이블 만들기
pykido Nov 5, 2024
33eb197
feat : 리뷰 반영
pykido Nov 5, 2024
b09029d
feat : sqs 서비스 붙이고 테스트하기
pykido Nov 5, 2024
f25b867
feat : sqs 서비스 통일화
pykido Nov 6, 2024
2be078b
Merge branch 'refs/heads/Week10' into #48-알림-서비스-고도화
pykido Nov 6, 2024
cd7338b
feat : 관리자 페이지에서 요양보호사 추가할 때 알람 테이블도 추가하기
pykido Nov 6, 2024
b877e08
refactor : 스케쥴러 코드 수정하기
pykido Nov 6, 2024
76bb71c
feat : 요양보호사 성공!!!
pykido Nov 6, 2024
cc5d5a1
feat : 다음 근무일에 보낼 알림 메시지 작성
pykido Nov 6, 2024
a30faa6
feat : 요양보호사 로직 완성
pykido Nov 6, 2024
f04006e
refactor : 디렉토리 위치 변경
pykido Nov 6, 2024
b445829
feat : coolsms 의존성 추가
pykido Nov 7, 2024
7ad1d15
feat : sms 문자 메시지 api 연결 완료
pykido Nov 7, 2024
a88e1e1
refactor : 간단한 수정
pykido Nov 8, 2024
a3dfb3d
refactor : excel 폴더 위치 변경
pykido Nov 12, 2024
20f0649
Merge branch 'refs/heads/Week10' into #80-SMS-알림-서비스-구현
pykido Nov 12, 2024
b314286
refactor : update 수정
pykido Nov 12, 2024
f2c22ee
feat : line url 경로 열어두기
pykido Nov 12, 2024
2eeaceb
refactor : 알람 테이블 또한 수정하기
pykido Nov 12, 2024
cc18d2f
feat : Line messaging 기능 완성하였음
pykido Nov 12, 2024
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
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ dependencies {
// Redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

// SQS
// Amazon SQS
implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.0.1")
implementation 'io.awspring.cloud:spring-cloud-aws-starter-sqs'

Expand Down
10 changes: 5 additions & 5 deletions src/main/java/dbdr/domain/careworker/entity/Careworker.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,11 @@ public void updateAlertTime(LocalTime alertTime) {
this.alertTime = alertTime;
}

public void updateInstitution(Institution institution) {
this.institution = institution;
}

// 요일 설정 및 조회 메서드
public void addWorkDay(DayOfWeek day) {
this.workDays |= day.getValue();
}

// 다음 근무일 찾기
public DayOfWeek getNextWorkingDay(DayOfWeek currentDay) {
for (int i = 1; i <= 7; i++) { // 최대 7일을 순환하여 다음 근무일 찾기
Expand All @@ -124,4 +120,8 @@ public DayOfWeek getNextWorkingDay(DayOfWeek currentDay) {
public boolean isWorkingOn(DayOfWeek day) {
return (this.workDays & (1 << (day.getValue() - 1))) != 0;
}

public void updateInstitution(Institution institution) {
this.institution = institution;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ public CareworkerMyPageResponse updateWorkingDaysAndAlertTime(Long careworkerId,

careworker.updateWorkingDays(request.getWorkingDays());
careworker.updateAlertTime(request.getAlertTime());
alarmService.updateAlarmByLocalTime(request.getAlertTime(), careworker.getPhone());

return toMyPageResponseDTO(careworker);
}
Expand Down Expand Up @@ -189,6 +190,15 @@ public Careworker findByPhone(String phoneNumber) {
return careworkerRepository.findByPhone(phoneNumber).orElse(null);
}

@Transactional
public void updateLineUserId(String userId, String phoneNumber) {
Careworker careworker = findByPhone(phoneNumber);
careworker.updateLineUserId(userId);
careworkerRepository.save(careworker);
}



private CareworkerMyPageResponse toMyPageResponseDTO(Careworker careworker) {
return new CareworkerMyPageResponse(
careworker.getName(),
Expand All @@ -198,13 +208,4 @@ private CareworkerMyPageResponse toMyPageResponseDTO(Careworker careworker) {
careworker.getWorkingDays()
);
}

@Transactional
public void updateLineUserId(String userId, String phoneNumber) {
Careworker careworker = findByPhone(phoneNumber);
careworker.updateLineUserId(userId);
careworkerRepository.save(careworker);
}


}
8 changes: 7 additions & 1 deletion src/main/java/dbdr/domain/chart/service/ChartService.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import dbdr.domain.chart.dto.response.ChartOverviewResponse;
import dbdr.domain.chart.entity.Chart;
import dbdr.domain.chart.repository.ChartRepository;
import dbdr.domain.core.alarm.service.AlarmService;
import dbdr.global.exception.ApplicationError;
import dbdr.global.exception.ApplicationException;
import java.util.List;
Expand Down Expand Up @@ -40,6 +41,7 @@
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
Expand All @@ -50,6 +52,7 @@ public class ChartService {
private final ChartMapper chartMapper;
private final SummaryRepository summaryRepository;
private final OpenAiSummarizationConfig summarizationConfig;
private final AlarmService alarmService;

@Value("${openai.chat-completions}")
private String chatUrl;
Expand Down Expand Up @@ -77,6 +80,7 @@ public void deleteChart(Long chartId) {
chartRepository.deleteById(chartId);
}

@Transactional
public ChartDetailResponse saveChart(ChartDetailRequest request) {
Chart chart = chartMapper.toEntity(request);
Chart savedChart = chartRepository.save(chart);
Expand All @@ -87,7 +91,9 @@ public ChartDetailResponse saveChart(ChartDetailRequest request) {
summaryResponse.bodyManagement(), summaryResponse.recoveryTraining(),
summaryResponse.conditionDisease(), summaryResponse.nursingManagement(),
tagResponse.tag1(), tagResponse.tag2(), tagResponse.tag3()));
return chartMapper.toResponse(savedChart);
ChartDetailResponse chartDetailResponse = chartMapper.toResponse(savedChart);
alarmService.updateGuardianAlarmMessage(chartDetailResponse);
return chartDetailResponse;
}

public ChartDetailResponse updateChart(Long chartId, ChartDetailRequest request) {
Expand Down
40 changes: 40 additions & 0 deletions src/main/java/dbdr/domain/core/alarm/service/AlarmService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.springframework.transaction.annotation.Transactional;

import dbdr.domain.careworker.entity.Careworker;
import dbdr.domain.chart.dto.response.ChartDetailResponse;
import dbdr.domain.core.alarm.entity.Alarm;
import dbdr.domain.core.messaging.MessageChannel;
import dbdr.domain.core.messaging.MessageTemplate;
Expand All @@ -17,6 +18,10 @@
import dbdr.domain.core.alarm.repository.AlarmRepository;
import dbdr.domain.core.messaging.service.CallSqsService;
import dbdr.domain.guardian.entity.Guardian;
import dbdr.domain.recipient.dto.response.RecipientResponse;
import dbdr.domain.recipient.entity.Recipient;
import dbdr.domain.recipient.repository.RecipientRepository;
import dbdr.domain.recipient.service.RecipientService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

Expand All @@ -26,6 +31,7 @@
public class AlarmService {
private final AlarmRepository alarmRepository;
private final CallSqsService callSqsService;
private final RecipientRepository recipientRepository;

@Transactional
public void createCareworkerAlarm(Careworker careworker) {
Expand Down Expand Up @@ -129,4 +135,38 @@ public void updateNewLineUser(String phone, String lineUserId) {
alarmRepository.save(alarm);
}
}

@Transactional
public void updateAlarmByLocalTime(LocalTime localTime, String phone) {
Alarm alarm = alarmRepository.findByPhone(phone).orElse(null);
if (alarm != null && !alarm.isSend()) {
alarm.setAlertTime(localTime.atDate(alarm.getAlertTime().toLocalDate()));
alarmRepository.save(alarm);
}
}

@Transactional
public void updateGuardianAlarmMessage(ChartDetailResponse chartDetailResponse) {
Recipient recipient = recipientRepository.findById(chartDetailResponse.recipientId()).orElse(null);
Alarm alarm = alarmRepository.findByPhone(recipient.getGuardian().getPhone()).orElse(null);

if (alarm != null && !alarm.isSend() && alarm.getAlertTime().isAfter(LocalDateTime.now())) {
// ChartDetailResponse의 데이터를 사용해 알림 메시지 생성
String message = MessageTemplate.CHART_UPDATED_MESSAGE.format(
recipient.getGuardian().getName(),
chartDetailResponse.conditionDisease(),
chartDetailResponse.bodyManagement().wash() ? "예" : "아니오",
chartDetailResponse.bodyManagement().bath() ? "예" : "아니오",
chartDetailResponse.bodyManagement().mealType(),
chartDetailResponse.nursingManagement().systolic(),
chartDetailResponse.nursingManagement().diastolic(),
chartDetailResponse.nursingManagement().healthTemperature(),
chartDetailResponse.cognitiveManagement().cognitiveHelp() ? "예" : "아니오",
chartDetailResponse.recoveryTraining().recoveryProgram()
);

alarm.setMessage(message);
alarmRepository.save(alarm);
}
}
}
10 changes: 8 additions & 2 deletions src/main/java/dbdr/domain/core/messaging/MessageTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@ public enum MessageTemplate {
CAREWORKER_WELCOME_MESSAGE("%s 요양보호사님, 안녕하세요! 🌸\n 최고의 요양원 서비스 돌봄다리입니다. 🤗\n 저희와 함께 해주셔서 정말 감사합니다! 🙏\n 기본적인 알림 시간은 매일 오후 5시로 설정되어있습니다. 😄\n 돌봄다리 서비스의 마이페이지에서 알림 시간을 수정할 수 있습니다."),
GUARDIAN_WELCOME_MESSAGE("%s 보호자님, 안녕하세요! 🌸\n 최고의 요양원 서비스 돌봄다리입니다. 🤗\n 저희와 함께 해주셔서 정말 감사합니다! 🙏\n 새롭게 작성된 일지 내용을 원하시는 시간에 맞춰 알려드릴 수 있어요. ⏰\n 기본적인 알림 시간은 매일 오전 9시로 설정되어있습니다. 😄\n 돌봄다리 서비스의 마이페이지에서 알림 시간을 수정할 수 있습니다.\""),
NO_CHART_MESSAGE("새롭게 작성된 차트 내용이 없습니다! 😅"),
CAREWORKER_ALARM_MESSAGE("%s 요양보호사님, 오늘 하루는 어떠셨나요? 😊\n이제 차트를 작성하실 시간입니다. 잊지 마시고 차트 작성 부탁드립니다! 📝");

CAREWORKER_ALARM_MESSAGE("%s 요양보호사님, 오늘 하루는 어떠셨나요? 😊\n이제 차트를 작성하실 시간입니다. 잊지 마시고 차트 작성 부탁드립니다! 📝"),
CHART_UPDATED_MESSAGE("%s님, 안녕하세요! 😊 새로운 차트 정보가 업데이트되었습니다. 📋\n" +
"- 상태/질환: %s\n" +
"- 신체 관리: 세수 - %s, 목욕 - %s, 식사 - %s\n" +
"- 간호 관리: 혈압 - %s/%s, 체온 - %s도\n" +
"- 인지 관리: 인지 도움 제공 - %s\n" +
"- 회복 훈련 프로그램: %s\n\n" +
"더 자세한 내용은 돌봄다리에서 확인하세요. 감사합니다! 🙏");
private final String template;

MessageTemplate(String template) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,28 @@ public void sendChartUpdate() {
LocalDateTime alertTime = LocalDateTime.of(LocalDate.now(), currentTime);
Alarm alarm = alarmService.getAlarmByPhoneAndAlertTime(phone, alertTime);
String name = guardian.getName();

// (1) Line 채널 알림 보내기
if (alarm != null && alarm.getChannel().equals(MessageChannel.LINE)) {
log.info("알림 보낼 보호자 : {}", name);
alarmService.sendAlarmToSqs(alarm, alarm.getChannelId(), name);
alarmService.createGuardianNextDayAlarm(guardian);
}
// (2) SMS 알림 보내기
}

// 요양보호사에게 알람 메시지를 SQS로 전송합니다.
for (Careworker careworker : careworkers) {
String phone = careworker.getPhone();
Alarm alarm = alarmService.getAlarmByPhoneAndAlertTime(phone, currentDateTime);
String name = careworker.getName();
// (1) Line 채널 알림 보내기
if (alarm != null && alarm.getChannel().equals(MessageChannel.LINE) && !alarm.isSend()) {
log.info("알림 보낼 요양보호사 : {}", name);
alarmService.sendAlarmToSqs(alarm, alarm.getChannelId(), name);
alarmService.createCareworkerNextWorkingdayAlarm(careworker);
}
// (2) SMS 알림 보내기
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "[보호자]", description = "보호자 정보 조회, 수정")
@Tag(name = "[보호자] 마이페이지", description = "보호자 본인의 정보 조회, 수정")
@RestController
@RequestMapping("/${spring.app.version}/guardian")
@RequiredArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import java.time.LocalTime;

public record GuardianAlertTimeRequest(@Schema(description = "보호자의 이름", example = "박준협")
@NotBlank(message = "이름은 필수 항목입니다.")
String name,
@Schema(description = "보호자의 휴대폰 번호", example = "01012341234")
@NotBlank(message = "휴대폰 번호는 필수 항목입니다.")
@Pattern(regexp = "010\\d{8}", message = "010XXXXXXXX형식으로 입력해주세요.")
String phone,
@Schema(description = "보호자의 알림 시간", example = "18:00:00")
@NotBlank(message = "알람 시간은 필수 항목입니다.")
LocalTime alertTime) {
public record GuardianAlertTimeRequest(
@Schema(description = "보호자의 이름", example = "박준협")
@NotBlank(message = "이름은 필수 항목입니다.")
String name,

@Schema(description = "보호자의 휴대폰 번호", example = "01012341234")
@NotBlank(message = "휴대폰 번호는 필수 항목입니다.")
@Pattern(regexp = "010\\d{8}", message = "010XXXXXXXX 형식으로 입력해주세요.")
String phone,

@Schema(description = "보호자의 알림 시간", example = "18:00:00")
@NotNull(message = "알람 시간은 필수 항목입니다.")
LocalTime alertTime
) {
}
2 changes: 1 addition & 1 deletion src/main/java/dbdr/domain/guardian/entity/Guardian.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public class Guardian extends BaseEntity {
private String lineUserId;

@Column(nullable = true)
private LocalTime alertTime = LocalTime.of(18, 0); // 오후 6시로 초기화
private LocalTime alertTime = LocalTime.of(9, 0); // 오전 9시로 초기화

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "institution_id")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dbdr.domain.guardian.service;

import dbdr.domain.core.alarm.service.AlarmService;
import dbdr.domain.core.alarm.service.AlarmService;
import dbdr.domain.guardian.dto.request.GuardianAlertTimeRequest;
import dbdr.domain.guardian.dto.request.GuardianUpdateRequest;
Expand Down Expand Up @@ -45,12 +46,14 @@ public GuardianMyPageResponse getMyPageGuardianInfo(Long guardianId) {
guardian.getAlertTime());
}

@Transactional
public GuardianMyPageResponse updateAlertTime(Long guardianId,
GuardianAlertTimeRequest request) {
ensureUniquePhoneButNotId(request.phone(), guardianId);
Guardian guardian = findGuardianById(guardianId);
guardian.updateAlertTime(request.name(), request.phone(), request.alertTime());
guardianRepository.save(guardian);
alarmService.updateAlarmByLocalTime(request.alertTime(), request.phone());
return new GuardianMyPageResponse(guardian.getName(), guardian.getPhone(),
guardian.getAlertTime());
}
Expand Down
17 changes: 0 additions & 17 deletions src/main/java/dbdr/global/configuration/WebConfig.java

This file was deleted.

Loading