예약 메시지를 보내는 기능을 구현하기 위해 아무 생각없이 메서드에 @Scheduled 어노테이션을 달아놨다.
@RestController
@RequestMapping("/api/v1/slacks")
@RequiredArgsConstructor
public class SlackController {
private final SlackService slackService;
@PostMapping
public ResponseEntity<Void> sendSlackMessage(@RequestBody SlackMessageRequestDto requestDto) {
slackService.sendSlackMessage(requestDto);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
@PreAuthorize("hasAnyAuthority('MASTER')")
@PostMapping("/{deliveryAgentId}/company")
public ResponseEntity<Void> scheduleMessageForCompanyAgent(@PathVariable Long deliveryAgentId,
@RequestParam String appid) {
slackService.scheduleMessageForCompanyAgent(deliveryAgentId, appid);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
@PreAuthorize("hasAnyAuthority('MASTER')")
@PostMapping("/{deliveryAgentId}/hub")
public ResponseEntity<Void> scheduleMessageForHubAgent(@PathVariable Long deliveryAgentId) {
slackService.scheduleMessageForHubAgent(deliveryAgentId);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
}
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class SlackService {
private final SlackRepository slackRepository;
private final UserServiceClient userServiceClient;
private final AiServiceClient aiServiceClient;
@Value("${webhook.slack.bot.token}")
private String SLACK_BOT_TOKEN;
private final Slack slackClient = Slack.getInstance();
// 봇으로 DM 보내기
@Transactional
public void sendSlackMessage(SlackMessageRequestDto requestDto) {
try {
UserDto userDto = userServiceClient.getSlackIdByUserId(requestDto.userId());
String slackUserId = userDto.slackId();
String messageText = requestDto.data();
ChatPostMessageRequest messageRequest = ChatPostMessageRequest.builder()
.channel(slackUserId)
.text(messageText)
.build();
ChatPostMessageResponse response = slackClient.methods(SLACK_BOT_TOKEN).chatPostMessage(messageRequest);
if (response.isOk()) {
Long currentUserId = getCurrentUserId();
com.forj.slack_message.domain.model.Slack slackMessage = com.forj.slack_message.domain.model.Slack.createSlackMessage(
currentUserId,
messageText,
LocalDateTime.now()
);
slackRepository.save(slackMessage);
} else {
throw new RuntimeException("Failed to send message: " + response.getError());
}
} catch (IOException | SlackApiException e) {
e.printStackTrace();
}
}
// 업체 배송 담당자에게 보낼 DM 예약
@Transactional
@Scheduled(cron = "0 0 6 * * *")
public void scheduleMessageForCompanyAgent(Long deliveryAgentId, String appid) {
// ai 서비스에서 요약메시지 생성
String message = aiServiceClient.getInfoForCompanyDeliveryAgent(deliveryAgentId, appid);
SlackMessageRequestDto requestDto = new SlackMessageRequestDto(deliveryAgentId, message);
sendSlackMessage(requestDto);
}
// 허브 배송 담당자에게 보낼 DM 예약
@Transactional
@Scheduled(cron = "0 0 8 * * *")
public void scheduleMessageForHubAgent(Long deliveryAgentId) {
String message = aiServiceClient.getInfoForHubDeliveryAgent(deliveryAgentId);
SlackMessageRequestDto requestDto = new SlackMessageRequestDto(deliveryAgentId, message);
sendSlackMessage(requestDto);
}
private Long getCurrentUserId() {
return Long.parseLong(SecurityContextHolder.getContext().getAuthentication().getName());
}
}
근데 포스트맨으로 메서드를 실행해보니 바로 dm이 와졌다.
알고보니 @Scheduled 메서드에는 매개변수를 사용할 수가 없었고 해결방법을 찾아보니 여거가지 방법들이 있겠지만
일단 가장 이상적인 해결방법으로는 필요한 파라미터 대신 시간 또는 enum 상태로 조건을 걸어 데이터를 가져오고, 예민한 정보가 필요하다면 gitignore 처리된 yml에 넣어 @Value 어노테이션으로 직접 사용한다.