diff --git a/src/main/java/com/pictalk/global/config/RestTemplateConfig.java b/src/main/java/com/pictalk/global/config/RestTemplateConfig.java new file mode 100644 index 0000000..034ccf5 --- /dev/null +++ b/src/main/java/com/pictalk/global/config/RestTemplateConfig.java @@ -0,0 +1,14 @@ +package com.pictalk.global.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } +} diff --git a/src/main/java/com/pictalk/global/jwt/JwtService.java b/src/main/java/com/pictalk/global/jwt/JwtService.java index 0442160..5f2ab3f 100644 --- a/src/main/java/com/pictalk/global/jwt/JwtService.java +++ b/src/main/java/com/pictalk/global/jwt/JwtService.java @@ -69,7 +69,7 @@ public String createRefreshToken() { .compact(); } -// saveAndFlush 사용으로 @Transactional은 없어도 될 듯 + // saveAndFlush 사용으로 @Transactional은 없어도 될 듯 public String reIssueRefreshToken(User user) { String reIssuedRefreshToken = createRefreshToken(); user.updateRefreshToken(reIssuedRefreshToken); @@ -122,4 +122,4 @@ public Optional decodeAccessToken(String accessToken) { return Optional.empty(); // 유효하지 않은 경우 빈 값 반환 } } -} +} \ No newline at end of file diff --git a/src/main/java/com/pictalk/message/controller/MessageController.java b/src/main/java/com/pictalk/message/controller/MessageController.java index b074d90..16845d0 100644 --- a/src/main/java/com/pictalk/message/controller/MessageController.java +++ b/src/main/java/com/pictalk/message/controller/MessageController.java @@ -1,11 +1,12 @@ package com.pictalk.message.controller; -import static com.pictalk.message.service.MessageService.getReceiversAsString; - import com.pictalk.global.payload.response.CommonResponse; import com.pictalk.message.domain.Message; import com.pictalk.message.domain.MessageImage; +import com.pictalk.message.domain.Receiver; +import com.pictalk.message.dto.MessageRequestDto; import com.pictalk.message.dto.MessageRequestDto.SendMessageRequest; +import com.pictalk.message.dto.MessageResponseDto; import com.pictalk.message.dto.MessageResponseDto.CancelMessageResponse; import com.pictalk.message.dto.MessageResponseDto.MessageResponse; import com.pictalk.message.dto.MessageResponseDto.SendMessageResponse; @@ -36,12 +37,13 @@ public class MessageController { public CommonResponse sendMessage(@AuthenticationPrincipal UserDetails authenticatedPrincipal, @Valid @RequestBody SendMessageRequest request) { String userEmail = authenticatedPrincipal.getUsername(); - SendMessageResponse response = messageService.sendMessage(request, userEmail); + MessageResponseDto.SendMessageResponse response = messageService.sendMessage(request, userEmail); return CommonResponse.onSuccess(response); } @GetMapping - public CommonResponse> getMessages(@AuthenticationPrincipal UserDetails authenticatedPrincipal) { + public CommonResponse> getMessages( + @AuthenticationPrincipal UserDetails authenticatedPrincipal) { String userEmail = authenticatedPrincipal.getUsername(); List messages = messageService.getMessages(userEmail); @@ -53,7 +55,7 @@ public CommonResponse> getMessages(@AuthenticationPrincipa .messageImages(getImageUrls(message.getMessageImages())) .status(message.getStatus().toString()) .build() - ).collect(Collectors.toList()); + ).toList(); return CommonResponse.onSuccess(messageResponses); } @@ -61,20 +63,32 @@ public CommonResponse> getMessages(@AuthenticationPrincipa private List getImageUrls(List messageImages) { return messageImages.stream() .map(messageImage -> messageImage.getImage().getImageUrl()) - .collect(Collectors.toList()); + .toList(); } @GetMapping("/{message-id}") public CommonResponse getMessage(@AuthenticationPrincipal UserDetails authenticatedPrincipal, @PathVariable("message-id") Long messageId) { String userEmail = authenticatedPrincipal.getUsername(); - MessageResponse response = messageService.getMessage(messageId, userEmail); + Message message = messageService.getMessage(messageId, userEmail); + + MessageResponse response = MessageResponse.builder() + .messageId(message.getId()) + .content(message.getContent()) + .to(getReceiversAsString(message.getReceivers())) + .sendTime(message.getSentAt() != null ? message.getSentAt().toString() : null) + .status(message.getStatus().toString()) + .messageImages(message.getMessageImages().stream() + .map(messageImage -> messageImage.getImage().getImageUrl()) + .collect(Collectors.toList())) + .build(); return CommonResponse.onSuccess(response); } @PatchMapping("/{message-id}") - public CommonResponse cancelScheduledMessage(@AuthenticationPrincipal UserDetails authenticatedPrincipal, - @PathVariable("message-id") Long messageId) { + public CommonResponse cancelScheduledMessage( + @AuthenticationPrincipal UserDetails authenticatedPrincipal, + @PathVariable("message-id") Long messageId) { String userEmail = authenticatedPrincipal.getUsername(); CancelMessageResponse response = messageService.cancelScheduledMessage(messageId, userEmail); return CommonResponse.onSuccess(response); @@ -87,4 +101,19 @@ public CommonResponse deleteMessage(@AuthenticationPrincipal UserDetails a messageService.deleteMessage(messageId, userEmail); return CommonResponse.onSuccess(null); } + + @PostMapping("/temp") + public CommonResponse saveTempMessage( + @AuthenticationPrincipal UserDetails authenticatedPrincipal, + @Valid @RequestBody MessageRequestDto.TempMessageRequest request) { + String userEmail = authenticatedPrincipal.getUsername(); + MessageResponseDto.TempMessageResponse response = messageService.saveTempMessage(request, userEmail); + return CommonResponse.onSuccess(response); + } + + private String getReceiversAsString(List receivers) { + return receivers.stream() + .map(Receiver::getPhoneNumber) + .collect(Collectors.joining(", ")); + } } diff --git a/src/main/java/com/pictalk/message/domain/Message.java b/src/main/java/com/pictalk/message/domain/Message.java index a27ad2a..3f4e93c 100644 --- a/src/main/java/com/pictalk/message/domain/Message.java +++ b/src/main/java/com/pictalk/message/domain/Message.java @@ -52,17 +52,19 @@ public class Message extends BaseEntity { private String content; - @Column(nullable = false) - private LocalDateTime createdAt; - - private LocalDateTime updatedAt; private LocalDateTime sentAt; - @Builder.Default - private boolean deleted = false; + @Column(name = "external_message_id") + private String externalMessageId; + + public void addReceivers(List newReceivers) { + this.receivers.addAll(newReceivers); + newReceivers.forEach(receiver -> receiver.associateWithMessage(this)); + } - public void addReceivers(List receivers) { - this.receivers.addAll(receivers); + public void addReceiver(Receiver receiver) { + this.receivers.add(receiver); + receiver.associateWithMessage(this); } public void cancel() { @@ -71,7 +73,8 @@ public void cancel() { } } - public void softDelete() { - this.deleted = true; + public Message withExternalMessageId(String externalMessageId) { + this.externalMessageId = externalMessageId; + return this; } } diff --git a/src/main/java/com/pictalk/message/domain/MessageStatus.java b/src/main/java/com/pictalk/message/domain/MessageStatus.java index 138485c..dbc4258 100644 --- a/src/main/java/com/pictalk/message/domain/MessageStatus.java +++ b/src/main/java/com/pictalk/message/domain/MessageStatus.java @@ -3,5 +3,6 @@ public enum MessageStatus { SCHEDULED, // 예약됨 SENT, // 전송됨 - CANCELLED // 예약 취소됨 + CANCELLED, // 예약 취소됨 + TEMP // 임시 저장됨 } diff --git a/src/main/java/com/pictalk/message/domain/Receiver.java b/src/main/java/com/pictalk/message/domain/Receiver.java index bfad4f7..624ed8a 100644 --- a/src/main/java/com/pictalk/message/domain/Receiver.java +++ b/src/main/java/com/pictalk/message/domain/Receiver.java @@ -52,4 +52,7 @@ public Receiver(String nickname, String phoneNumber) { this.phoneNumber = phoneNumber; } + public void associateWithMessage(Message message) { + this.message = message; + } } diff --git a/src/main/java/com/pictalk/message/domain/Request.java b/src/main/java/com/pictalk/message/domain/Request.java new file mode 100644 index 0000000..99d0682 --- /dev/null +++ b/src/main/java/com/pictalk/message/domain/Request.java @@ -0,0 +1,20 @@ +package com.pictalk.message.domain; + +public class Request { + + private String requestUri; + private String authorization; + + public Request(String requestUri, String authorization) { + this.requestUri = requestUri; + this.authorization = authorization; + } + + public String getRequestUri() { + return requestUri; + } + + public String getAuthorization() { + return authorization; + } +} diff --git a/src/main/java/com/pictalk/message/domain/Sender.java b/src/main/java/com/pictalk/message/domain/Sender.java index b8e694a..60b5bfe 100644 --- a/src/main/java/com/pictalk/message/domain/Sender.java +++ b/src/main/java/com/pictalk/message/domain/Sender.java @@ -1,12 +1,25 @@ package com.pictalk.message.domain; import com.pictalk.user.domain.User; -import jakarta.persistence.*; -import lombok.*; - +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.PrePersist; +import jakarta.persistence.Table; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Entity @Table(name = "sender") @@ -37,9 +50,6 @@ public class Sender { @Column(updatable = false) private LocalDateTime createdAt; - @Builder.Default - private boolean deleted = false; - @PrePersist protected void onCreate() { createdAt = LocalDateTime.now(); diff --git a/src/main/java/com/pictalk/message/dto/MessageRequestDto.java b/src/main/java/com/pictalk/message/dto/MessageRequestDto.java index 49c9269..c54f064 100644 --- a/src/main/java/com/pictalk/message/dto/MessageRequestDto.java +++ b/src/main/java/com/pictalk/message/dto/MessageRequestDto.java @@ -22,10 +22,10 @@ public static class SendMessageRequest { private int targetCount; private List targets; private String refKey; - private String rejectType; - private String sendTime; - private String subject; - private List files; +// private String rejectType; +// private String sendTime; +// private String subject; +// private List files; } @Getter @@ -62,6 +62,13 @@ public static class FileDto { private String data; } + @Getter + public static class TempMessageRequest { + private String content; + private String to; + private String sendTime; + } + @Getter public static class CreateAIMessageRequest { private String situation; diff --git a/src/main/java/com/pictalk/message/dto/MessageResponseDto.java b/src/main/java/com/pictalk/message/dto/MessageResponseDto.java index 02d4648..b8b38c7 100644 --- a/src/main/java/com/pictalk/message/dto/MessageResponseDto.java +++ b/src/main/java/com/pictalk/message/dto/MessageResponseDto.java @@ -39,6 +39,13 @@ public static class CancelMessageResponse { private String status; } + @Getter + @Builder + public static class TempMessageResponse { + private Long messageId; + private String status; + } + @Getter @Builder public static class CreateAIMessageResponse { diff --git a/src/main/java/com/pictalk/message/repository/MessageRepository.java b/src/main/java/com/pictalk/message/repository/MessageRepository.java index 47e11ae..82b0040 100644 --- a/src/main/java/com/pictalk/message/repository/MessageRepository.java +++ b/src/main/java/com/pictalk/message/repository/MessageRepository.java @@ -2,18 +2,16 @@ import com.pictalk.message.domain.Message; import com.pictalk.user.domain.User; - import java.util.List; import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface MessageRepository extends JpaRepository { // 삭제되지 않은 특정 사용자의 모든 메시지 조회 - List findAllByDeletedFalseAndSenderUser(User user); + List findAllBySenderUser(User user); // 삭제되지 않은 특정 사용자의 특정 메시지 조회 - Optional findByIdAndSenderUserAndDeletedFalse(Long id, User user); + Optional findByIdAndSenderUser(Long id, User user); } diff --git a/src/main/java/com/pictalk/message/service/ImmediateMessageService.java b/src/main/java/com/pictalk/message/service/ImmediateMessageService.java deleted file mode 100644 index ac059b4..0000000 --- a/src/main/java/com/pictalk/message/service/ImmediateMessageService.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.pictalk.message.service; - -import com.pictalk.global.exception.GeneralException; -import com.pictalk.global.payload.status.ErrorStatus; -import com.pictalk.message.domain.*; -import com.pictalk.message.dto.MessageRequestDto.SendMessageRequest; -import com.pictalk.message.dto.MessageResponseDto.SendMessageResponse; -import com.pictalk.message.repository.MessageRepository; -import com.pictalk.message.repository.SenderRepository; -import com.pictalk.user.domain.User; -import com.pictalk.user.repository.UserRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; -import java.util.List; -import java.util.stream.Collectors; - -@Service -@RequiredArgsConstructor -public class ImmediateMessageService { - private final MessageRepository messageRepository; - private final SenderRepository senderRepository; - private final UserRepository userRepository; - - @Transactional - public SendMessageResponse sendImmediateMessage(SendMessageRequest request, String userEmail) { - User user = userRepository.findByEmail(userEmail) - .orElseThrow(() -> new GeneralException(ErrorStatus.USER_NOT_FOUND)); - - Sender sender = senderRepository.findSenderByPhoneNumber(request.getFrom()) - .orElseGet(() -> senderRepository.save( - Sender.builder() - .user(user) - .nickname(request.getFrom()) - .phoneNumber(request.getFrom()) - .build() - )); - - Message message = Message.builder() - .sender(sender) - .content(request.getContent()) - .status(MessageStatus.SENT) - .sentAt(LocalDateTime.now()) - .build(); - - List receivers = request.getTargets().stream() - .map(target -> Receiver.builder() - .message(message) - .nickname(target.getName()) - .phoneNumber(target.getTo()) - .build()) - .collect(Collectors.toList()); - - message.addReceivers(receivers); - messageRepository.save(message); - - sendSms(message, receivers); - - return SendMessageResponse.builder() - .externalMessageId(String.valueOf(message.getId())) - .status("sent") - .build(); - } - - private void sendSms(Message message, List receivers) { - receivers.forEach(receiver -> { - System.out.println("Sending SMS to " + receiver.getPhoneNumber() + ": " + message.getContent()); - }); - } -} diff --git a/src/main/java/com/pictalk/message/service/MessageService.java b/src/main/java/com/pictalk/message/service/MessageService.java index 9262411..572e445 100644 --- a/src/main/java/com/pictalk/message/service/MessageService.java +++ b/src/main/java/com/pictalk/message/service/MessageService.java @@ -3,75 +3,175 @@ import com.pictalk.global.exception.GeneralException; import com.pictalk.global.payload.status.ErrorStatus; import com.pictalk.message.domain.Message; +import com.pictalk.message.domain.MessageStatus; import com.pictalk.message.domain.Receiver; +import com.pictalk.message.domain.Sender; import com.pictalk.message.dto.MessageRequestDto.SendMessageRequest; +import com.pictalk.message.dto.MessageRequestDto.Target; +import com.pictalk.message.dto.MessageRequestDto.TempMessageRequest; import com.pictalk.message.dto.MessageResponseDto.CancelMessageResponse; -import com.pictalk.message.dto.MessageResponseDto.MessageResponse; import com.pictalk.message.dto.MessageResponseDto.SendMessageResponse; +import com.pictalk.message.dto.MessageResponseDto.TempMessageResponse; import com.pictalk.message.repository.MessageRepository; +import com.pictalk.message.repository.ReceiverRepository; +import com.pictalk.message.repository.SenderRepository; import com.pictalk.user.domain.User; import com.pictalk.user.repository.UserRepository; -import java.time.LocalDateTime; import java.util.List; -import java.util.stream.Collectors; +import java.util.Map; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.client.RestTemplate; @Service @RequiredArgsConstructor public class MessageService { + + @Value("${ppurio.api.url}") + private String apiUrl; + + @Value("${ppurio.api.key}") + private String apiKey; + + @Value("${ppurio.api.account}") + private String ppurioAccount; + + private final RestTemplate restTemplate; private final MessageRepository messageRepository; + private final SenderRepository senderRepository; + private final ReceiverRepository receiverRepository; private final UserRepository userRepository; - private final ImmediateMessageService immediateMessageService; - private final ScheduledMessageService scheduledMessageService; @Transactional public SendMessageResponse sendMessage(SendMessageRequest request, String userEmail) { - LocalDateTime sendTime = LocalDateTime.parse(request.getSendTime()); - LocalDateTime now = LocalDateTime.now(); + // 1. 사용자 및 발신자 정보 확인 + User user = userRepository.findByEmail(userEmail) + .orElseThrow(() -> new GeneralException(ErrorStatus.USER_NOT_FOUND)); - if (sendTime.isBefore(now)) { - throw new GeneralException(ErrorStatus.BAD_REQUEST); + Sender sender = senderRepository.findSenderByPhoneNumber(request.getFrom()).orElseGet( + () -> senderRepository.save(Sender.builder().user(user).phoneNumber(request.getFrom()).build())); + + // 2. 메시지 엔티티 생성 + Message message = Message.builder().sender(sender).content(request.getContent()).status(MessageStatus.SCHEDULED) + .build(); + + // 3. 수신자 정보 추가 + for (Target target : request.getTargets()) { + Receiver receiver = Receiver.builder().phoneNumber(target.getTo()).nickname(target.getName()).build(); + message.addReceiver(receiver); } - if (sendTime.isEqual(now)) { - return immediateMessageService.sendImmediateMessage(request, userEmail); - } else { - return scheduledMessageService.scheduleMessage(request, userEmail); + message = messageRepository.save(message); + + try { + // 4. 토큰 발급 받기 + HttpHeaders tokenHeaders = new HttpHeaders(); + tokenHeaders.setContentType(MediaType.APPLICATION_JSON); + tokenHeaders.setBasicAuth(ppurioAccount, apiKey); + + HttpEntity tokenRequest = new HttpEntity<>(tokenHeaders); + + ResponseEntity tokenResponse = restTemplate.exchange(apiUrl + "/v1/token", HttpMethod.POST, + tokenRequest, Map.class); + + if (tokenResponse.getStatusCode() != HttpStatus.OK || tokenResponse.getBody() == null) { + throw new GeneralException(ErrorStatus.INTERNAL_SERVER_ERROR); + } + + String accessToken = (String) tokenResponse.getBody().get("token"); + + // 5. 메시지 전송 요청 준비 + HttpHeaders messageHeaders = new HttpHeaders(); + messageHeaders.setContentType(MediaType.APPLICATION_JSON); + messageHeaders.setBearerAuth(accessToken); + + SendMessageRequest requestWithAccount = SendMessageRequest.builder().account(ppurioAccount) + .messageType(request.getMessageType()).content(request.getContent()).from(request.getFrom()) + .duplicateFlag(request.getDuplicateFlag()).targetCount(request.getTargets().size()) + .targets(request.getTargets()).refKey(request.getRefKey()).build(); + + HttpEntity messageEntity = new HttpEntity<>(requestWithAccount, messageHeaders); + + // 6. 메시지 전송 및 응답 처리 + ResponseEntity messageResponse = restTemplate.exchange(apiUrl + "/v1/message", HttpMethod.POST, + messageEntity, Map.class); + + if (messageResponse.getStatusCode() == HttpStatus.OK && messageResponse.getBody() != null) { + String messageKey = (String) messageResponse.getBody().get("messageKey"); + message.withExternalMessageId(messageKey); + message = messageRepository.save(message); + + return SendMessageResponse.builder().externalMessageId(messageKey).status("success").build(); + } else { + System.out.println("Error sending message1"); + throw new GeneralException(ErrorStatus.INTERNAL_SERVER_ERROR); + } + + } catch (Exception e) { + System.out.println("Error sending message2"); + throw new GeneralException(ErrorStatus.INTERNAL_SERVER_ERROR); } } + @Transactional + public TempMessageResponse saveTempMessage(TempMessageRequest request, String userEmail) { + User user = userRepository.findByEmail(userEmail) + .orElseThrow(() -> new GeneralException(ErrorStatus.USER_NOT_FOUND)); + + Message tempMessage = Message.builder() + .sender(user.getSenders().get(0)) // Assuming the user has at least one sender + .content(request.getContent()).status(MessageStatus.TEMP).build(); + + Receiver receiver = Receiver.builder().phoneNumber(request.getTo()).build(); + tempMessage.addReceiver(receiver); + + tempMessage = messageRepository.save(tempMessage); + + return TempMessageResponse.builder().messageId(tempMessage.getId()).status("temp_saved").build(); + } + + @Transactional(readOnly = true) public List getMessages(String userEmail) { User user = userRepository.findByEmail(userEmail) .orElseThrow(() -> new GeneralException(ErrorStatus.USER_NOT_FOUND)); - List messages = messageRepository.findAllByDeletedFalseAndSenderUser(user); - return messages; + return messageRepository.findAllBySenderUser(user); } - public static String getReceiversAsString(List receivers) { - return receivers.stream() - .map(Receiver::getPhoneNumber) - .collect(Collectors.joining(", ")); + + @Transactional(readOnly = true) + public Message getMessage(Long messageId, String userEmail) { + User user = userRepository.findByEmail(userEmail) + .orElseThrow(() -> new GeneralException(ErrorStatus.USER_NOT_FOUND)); + + return messageRepository.findByIdAndSenderUser(messageId, user) + .orElseThrow(() -> new GeneralException(ErrorStatus.MESSAGE_NOT_FOUND)); } - public MessageResponse getMessage(Long messageId, String userEmail) { + @Transactional + public CancelMessageResponse cancelScheduledMessage(Long messageId, String userEmail) { User user = userRepository.findByEmail(userEmail) .orElseThrow(() -> new GeneralException(ErrorStatus.USER_NOT_FOUND)); - Message message = messageRepository.findByIdAndSenderUserAndDeletedFalse(messageId, user) + Message message = messageRepository.findByIdAndSenderUser(messageId, user) .orElseThrow(() -> new GeneralException(ErrorStatus.MESSAGE_NOT_FOUND)); - return MessageResponse.builder() - .messageId(message.getId()) - .content(message.getContent()) - .to(getReceiversAsString(message.getReceivers())) - .sendTime(message.getSentAt() != null ? message.getSentAt().toString() : null) - .status(message.getStatus().toString()) - .messageImages(message.getMessageImages().stream() - .map(messageImage -> messageImage.getImage().getImageUrl()) - .collect(Collectors.toList())) + if (message.getStatus() != MessageStatus.SCHEDULED) { + throw new GeneralException(ErrorStatus.BAD_REQUEST); + } + + message.cancel(); + messageRepository.save(message); + + return CancelMessageResponse.builder().messageId(message.getId()).status(message.getStatus().toString()) .build(); } @@ -80,15 +180,10 @@ public void deleteMessage(Long messageId, String userEmail) { User user = userRepository.findByEmail(userEmail) .orElseThrow(() -> new GeneralException(ErrorStatus.USER_NOT_FOUND)); - Message message = messageRepository.findByIdAndSenderUserAndDeletedFalse(messageId, user) + Message message = messageRepository.findByIdAndSenderUser(messageId, user) .orElseThrow(() -> new GeneralException(ErrorStatus.MESSAGE_NOT_FOUND)); message.softDelete(); messageRepository.save(message); } - - @Transactional - public CancelMessageResponse cancelScheduledMessage(Long messageId, String userEmail) { - return scheduledMessageService.cancelScheduledMessage(messageId, userEmail); - } } diff --git a/src/main/java/com/pictalk/message/service/ScheduledMessageService.java b/src/main/java/com/pictalk/message/service/ScheduledMessageService.java deleted file mode 100644 index 3868bca..0000000 --- a/src/main/java/com/pictalk/message/service/ScheduledMessageService.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.pictalk.message.service; - -import com.pictalk.global.exception.GeneralException; -import com.pictalk.global.payload.status.ErrorStatus; -import com.pictalk.message.domain.*; -import com.pictalk.message.dto.MessageRequestDto.SendMessageRequest; -import com.pictalk.message.dto.MessageResponseDto.SendMessageResponse; -import com.pictalk.message.dto.MessageResponseDto.CancelMessageResponse; -import com.pictalk.message.repository.MessageRepository; -import com.pictalk.message.repository.SenderRepository; -import com.pictalk.user.domain.User; -import com.pictalk.user.repository.UserRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; -import java.util.List; -import java.util.stream.Collectors; - -@Service -@RequiredArgsConstructor -public class ScheduledMessageService { - private final MessageRepository messageRepository; - private final SenderRepository senderRepository; - private final UserRepository userRepository; - - @Transactional - public SendMessageResponse scheduleMessage(SendMessageRequest request, String userEmail) { - User user = userRepository.findByEmail(userEmail) - .orElseThrow(() -> new GeneralException(ErrorStatus.USER_NOT_FOUND)); - - Sender sender = senderRepository.findSenderByPhoneNumber(request.getFrom()) - .orElseGet(() -> senderRepository.save( - Sender.builder() - .user(user) - .nickname(request.getFrom()) - .phoneNumber(request.getFrom()) - .build() - )); - - LocalDateTime scheduledTime = LocalDateTime.parse(request.getSendTime()); - - if (scheduledTime.isBefore(LocalDateTime.now())) { - throw new GeneralException(ErrorStatus.BAD_REQUEST); - } - - Message message = Message.builder() - .sender(sender) - .content(request.getContent()) - .status(MessageStatus.SCHEDULED) - .sentAt(scheduledTime) - .build(); - - List receivers = request.getTargets().stream() - .map(target -> Receiver.builder() - .message(message) - .nickname(target.getName()) - .phoneNumber(target.getTo()) - .build()) - .collect(Collectors.toList()); - - message.addReceivers(receivers); - messageRepository.save(message); - - return SendMessageResponse.builder() - .externalMessageId(String.valueOf(message.getId())) - .status("scheduled") - .build(); - } - - @Transactional - public CancelMessageResponse cancelScheduledMessage(Long messageId, String userEmail) { - User user = userRepository.findByEmail(userEmail) - .orElseThrow(() -> new GeneralException(ErrorStatus.USER_NOT_FOUND)); - - Message message = messageRepository.findByIdAndSenderUserAndDeletedFalse(messageId, user) - .orElseThrow(() -> new GeneralException(ErrorStatus.MESSAGE_NOT_FOUND)); - - if (message.getStatus() != MessageStatus.SCHEDULED) { - throw new GeneralException(ErrorStatus.BAD_REQUEST); - } - - message.cancel(); - messageRepository.save(message); - - return CancelMessageResponse.builder() - .messageId(message.getId()) - .status("cancelled") - .build(); - } -} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e6fcc17..e21fe04 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -7,7 +7,7 @@ spring: jpa: hibernate: - ddl-auto: update + ddl-auto: create-drop show-sql: true properties: hibernate: @@ -54,4 +54,10 @@ cloud: region: static: ${AWS_S3_REGION} stack: - auto: false \ No newline at end of file + auto: false + +ppurio: + api: + url: ${PPURIO_API_URL} + key: ${PPURIO_API_KEY} + account: ${PPURIO_API_ACCOUNT} diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index f086e1c..8232a32 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -51,4 +51,11 @@ cloud: region: static: MockAWSS3Region stack: - auto: false \ No newline at end of file + auto: false + + +ppurio: + api: + url: MockPPURIOUrl + key: MockPPURIOKey + account: MockPPURIOAccount