diff --git a/src/main/java/clap/server/adapter/outbound/api/agit/AgitTemplateBuilder.java b/src/main/java/clap/server/adapter/outbound/api/agit/AgitTemplateBuilder.java index 452956bb..cac0c9f1 100644 --- a/src/main/java/clap/server/adapter/outbound/api/agit/AgitTemplateBuilder.java +++ b/src/main/java/clap/server/adapter/outbound/api/agit/AgitTemplateBuilder.java @@ -42,19 +42,19 @@ public String createPayLoad(PushNotificationTemplate request, Task task, String public String createMessage(PushNotificationTemplate request, String taskDetailUrl) { - return switch (request.notificationType()) { - case TASK_REQUESTED -> "πŸ“Œ *μƒˆ μž‘μ—… μš”μ²­:* `" + request.taskName() + "`\\n" - + "\\t\\t*β€’μš”μ²­μž: " + request.senderName() + "*\\n" - + "[ν™•μΈν•˜λŸ¬ κ°€κΈ°](" + taskDetailUrl + ")"; - case STATUS_SWITCHED -> "βš™οΈ *μž‘μ—… μƒνƒœ λ³€κ²½:* `" + request.taskName() + "\\n" - + "\\t\\t*β€’μž‘μ—… μƒνƒœ: " + request.message() + "*\\n" - + "[ν™•μΈν•˜λŸ¬ κ°€κΈ°](" + taskDetailUrl + ")"; - case PROCESSOR_CHANGED -> "πŸ”„ *λ‹΄λ‹Ήμž λ³€κ²½:* `" + request.taskName() + "\\n" - + "\\t\\t*β€’μƒˆ λ‹΄λ‹Ήμž: " + request.message() + "*\\n" - + "[ν™•μΈν•˜λŸ¬ κ°€κΈ°](" + taskDetailUrl + ")"; - case PROCESSOR_ASSIGNED -> "πŸ‘€ *μž‘μ—… λ‹΄λ‹Ήμž λ°°μ •:* `" + request.taskName() + "\\n" - + "\\t\\t*β€’λ‹΄λ‹Ήμž: " + request.message() + "*\\n" - + "[ν™•μΈν•˜λŸ¬ κ°€κΈ°](" + taskDetailUrl + ")"; + return switch (request.notificationType()) { + case TASK_REQUESTED -> "πŸ“Œ *μƒˆ μž‘μ—…μ΄ μš”μ²­λ˜μ—ˆμŠ΅λ‹ˆλ‹€.*\\n" + + "\\t\\t*β€’ πŸ”– μž‘μ—…λͺ…:* " + "*" + request.taskName() + "*" + "\\n" + + "\\t\\t*β€’ πŸ™‹ μš”μ²­μž:* " + "*" + request.senderName() + "*" + "\\n\\n" + + "\\t[μžμ„Ένžˆ 보기](" + taskDetailUrl + ")"; + + case STATUS_SWITCHED -> "μž‘μ—… μƒνƒœκ°€ " + "*" + request.message() + "*" + "으둜 λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€."; + + case PROCESSOR_CHANGED -> "λ‹΄λ‹Ήμžκ°€ " + "*" + request.message() + "*" + "으둜 λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€."; + + case PROCESSOR_ASSIGNED -> "μž‘μ—…μ΄ *승인*λ˜μ—ˆμŠ΅λ‹ˆλ‹€.*\n" + + "\\t\\t*β€’ πŸ‘€ λ‹΄λ‹Ήμž:* " + "*" + request.message() + "*"; + default -> null; }; } diff --git a/src/main/java/clap/server/adapter/outbound/api/data/PushNotificationTemplate.java b/src/main/java/clap/server/adapter/outbound/api/data/PushNotificationTemplate.java index 2a077a4b..154df739 100644 --- a/src/main/java/clap/server/adapter/outbound/api/data/PushNotificationTemplate.java +++ b/src/main/java/clap/server/adapter/outbound/api/data/PushNotificationTemplate.java @@ -9,6 +9,7 @@ public record PushNotificationTemplate( String taskName, String senderName, String message, - String commenterName + String commenterName, + String reason ) { } diff --git a/src/main/java/clap/server/adapter/outbound/api/email/EmailTemplateBuilder.java b/src/main/java/clap/server/adapter/outbound/api/email/EmailTemplateBuilder.java index a6a7ec49..bfdd1786 100644 --- a/src/main/java/clap/server/adapter/outbound/api/email/EmailTemplateBuilder.java +++ b/src/main/java/clap/server/adapter/outbound/api/email/EmailTemplateBuilder.java @@ -30,12 +30,20 @@ public EmailTemplate createWebhookTemplate(PushNotificationTemplate request, Str context.setVariable("title", request.taskName()); break; case STATUS_SWITCHED: - templateName = "status-switched"; - subject = "[TaskFlow] "+ request.taskName()+ " μž‘μ—…μ˜ μƒνƒœκ°€ " + request.message() + "으둜 λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€."; - context.setVariable("taskDetailUrl", taskDetailUrl); - context.setVariable("receiverName", request.senderName()); - context.setVariable("title", request.taskName()); - context.setVariable("status", request.message()); + if (request.message().equals("TERMINATED")) { + templateName = "task-terminated"; + subject = "[TaskFlow] " + request.taskName() + " μž‘μ—…μ΄ μ’…λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€."; + context.setVariable("taskDetailUrl", taskDetailUrl); + context.setVariable("reason", request.reason()); + context.setVariable("title", request.taskName()); + } else { + templateName = "status-switched"; + subject = "[TaskFlow] "+ request.taskName()+ " μž‘μ—…μ˜ μƒνƒœκ°€ " + request.message() + "으둜 λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€."; + context.setVariable("taskDetailUrl", taskDetailUrl); + context.setVariable("receiverName", request.senderName()); + context.setVariable("title", request.taskName()); + context.setVariable("status", request.message()); + } break; case PROCESSOR_CHANGED: templateName = "processor-changed"; diff --git a/src/main/java/clap/server/adapter/outbound/api/kakaoWork/KakaoWorkBlockBuilder.java b/src/main/java/clap/server/adapter/outbound/api/kakaoWork/KakaoWorkBlockBuilder.java index 97a5399f..9b450c61 100644 --- a/src/main/java/clap/server/adapter/outbound/api/kakaoWork/KakaoWorkBlockBuilder.java +++ b/src/main/java/clap/server/adapter/outbound/api/kakaoWork/KakaoWorkBlockBuilder.java @@ -17,7 +17,10 @@ public class KakaoWorkBlockBuilder { public String makeObjectBlock(PushNotificationTemplate request, String taskDetailUrl){ return switch (request.notificationType()) { case TASK_REQUESTED -> makeTaskRequestBlock(request, taskDetailUrl); - case STATUS_SWITCHED -> makeTaskStatusBlock(request, taskDetailUrl); + case STATUS_SWITCHED -> switch (request.message()) { // getStatusChangeType() λ©”μ„œλ“œλ‘œ μΆ”κ°€ λΆ„κΈ° + case "TERMINATED" -> makeTerminatedStatusBlock(request, taskDetailUrl); + default -> makeTaskStatusBlock(request, taskDetailUrl); + }; case PROCESSOR_CHANGED -> makeProcessorChangeBlock(request, taskDetailUrl); case PROCESSOR_ASSIGNED -> makeNewProcessorBlock(request, taskDetailUrl); case COMMENT -> makeCommentBlock(request, taskDetailUrl); @@ -366,4 +369,72 @@ private String makeTaskStatusBlock(PushNotificationTemplate request, String task return payload; } + + private String makeTerminatedStatusBlock(PushNotificationTemplate request, String taskDetailUrl) { + Object[] blocks = new Object[]{ + Map.of( + "type", "header", + "text", "TaskFlow μ•Œλ¦Ό μ„œλΉ„μŠ€", + "style", "blue" + ), + Map.of( + "type", "text", + "text", "TaskFlow μž‘μ—… μ’…λ£Œ μ•Œλ¦Ό", + "inlines", new Object[]{ + Map.of( + "type", "styled", + "text", "TaskFlow μž‘μ—… μ’…λ£Œ μ•Œλ¦Ό", + "bold", true + ) + } + ), + Map.of( + "type", "text", + "text", "TaskFlow μž‘μ—… μ’…λ£Œ μ•Œλ¦Ό", + "inlines", new Object[]{ + Map.of( + "type", "styled", + "text", " - Task Title : " + request.taskName(), + "bold", false + ) + } + ), + Map.of( + "type", "text", + "text", "TaskFlow μž‘μ—… μ’…λ£Œ μ•Œλ¦Ό", + "inlines", new Object[]{ + Map.of( + "type", "styled", + "text", " - 거절 μ‚¬μœ  : " + request.reason(), + "bold", false + ) + } + ), + Map.of( + "type", "button", + "text", "ν™•μΈν•˜κΈ°", + "style", "default", + "action", Map.of( + "type", "open_system_browser", + "name", "button1", + "value", taskDetailUrl + ) + ) + }; + + String payload; + try { + payload = "{" + + "\"email\":\"" + request.email() + "\"," + + "\"text\":\"μž‘μ—… μ’…λ£Œ μ•Œλ¦Ό\"," + + "\"blocks\":" + objectMapper.writeValueAsString(blocks) + + "}"; + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + + return payload; + } + + } diff --git a/src/main/java/clap/server/application/service/history/PostCommentService.java b/src/main/java/clap/server/application/service/history/PostCommentService.java index eaa20d31..1f08e2ba 100644 --- a/src/main/java/clap/server/application/service/history/PostCommentService.java +++ b/src/main/java/clap/server/application/service/history/PostCommentService.java @@ -97,6 +97,6 @@ private String saveAttachment(MultipartFile file, Task task, Comment comment) { private void publishNotification(Member receiver, Task task, String message, String commenterName) { boolean isManager = receiver.getMemberInfo().getRole() == MemberRole.ROLE_MANAGER; - sendNotificationService.sendPushNotification(receiver, NotificationType.COMMENT, task, message, commenterName, isManager); + sendNotificationService.sendPushNotification(receiver, NotificationType.COMMENT, task, message, null, commenterName, isManager); } } diff --git a/src/main/java/clap/server/application/service/task/ApprovalTaskService.java b/src/main/java/clap/server/application/service/task/ApprovalTaskService.java index 26dbd793..2fb3e305 100644 --- a/src/main/java/clap/server/application/service/task/ApprovalTaskService.java +++ b/src/main/java/clap/server/application/service/task/ApprovalTaskService.java @@ -75,7 +75,7 @@ private void publishNotification(List receivers, Task task, String proce receivers.forEach(receiver -> { boolean isManager = receiver.getMemberInfo().getRole() == MemberRole.ROLE_MANAGER; sendNotificationService.sendPushNotification(receiver, NotificationType.PROCESSOR_ASSIGNED, - task, processorName, null, isManager); + task, processorName, null, null, isManager); }); sendNotificationService.sendAgitNotification(NotificationType.PROCESSOR_ASSIGNED, task, processorName, null); diff --git a/src/main/java/clap/server/application/service/task/CreateTaskService.java b/src/main/java/clap/server/application/service/task/CreateTaskService.java index d29c0d50..60c6f010 100644 --- a/src/main/java/clap/server/application/service/task/CreateTaskService.java +++ b/src/main/java/clap/server/application/service/task/CreateTaskService.java @@ -70,7 +70,7 @@ private void publishNotification(Task task) { reviewers.forEach(reviewer -> { boolean isManager = reviewer.getMemberInfo().getRole() == MemberRole.ROLE_MANAGER; sendNotificationService.sendPushNotification(reviewer, NotificationType.TASK_REQUESTED, - task, null, null, isManager); + task, null, null, null, isManager); }); sendNotificationService.sendAgitNotification(NotificationType.TASK_REQUESTED, diff --git a/src/main/java/clap/server/application/service/task/TerminateTaskService.java b/src/main/java/clap/server/application/service/task/TerminateTaskService.java index 43281dfd..ecb92333 100644 --- a/src/main/java/clap/server/application/service/task/TerminateTaskService.java +++ b/src/main/java/clap/server/application/service/task/TerminateTaskService.java @@ -1,16 +1,22 @@ package clap.server.application.service.task; +import clap.server.adapter.outbound.persistense.entity.member.constant.MemberRole; +import clap.server.adapter.outbound.persistense.entity.notification.constant.NotificationType; import clap.server.adapter.outbound.persistense.entity.task.constant.TaskHistoryType; import clap.server.application.port.inbound.domain.MemberService; import clap.server.application.port.inbound.domain.TaskService; import clap.server.application.port.inbound.task.TerminateTaskUsecase; import clap.server.application.port.outbound.taskhistory.CommandTaskHistoryPort; +import clap.server.application.service.webhook.SendNotificationService; import clap.server.common.annotation.architecture.ApplicationService; +import clap.server.domain.model.member.Member; import clap.server.domain.model.task.Task; import clap.server.domain.model.task.TaskHistory; import lombok.RequiredArgsConstructor; import org.springframework.transaction.annotation.Transactional; +import java.util.List; + @ApplicationService @RequiredArgsConstructor @Transactional @@ -18,6 +24,7 @@ public class TerminateTaskService implements TerminateTaskUsecase { private final MemberService memberService; private final TaskService taskService; private final CommandTaskHistoryPort commandTaskHistoryPort; + private final SendNotificationService sendNotificationService; @Override public void terminateTask(Long memberId, Long taskId, String reason) { @@ -28,5 +35,12 @@ public void terminateTask(Long memberId, Long taskId, String reason) { TaskHistory taskHistory = TaskHistory.createTaskHistory(TaskHistoryType.TASK_TERMINATED, task, reason, null, null); commandTaskHistoryPort.save(taskHistory); + + publishNotification(task.getRequester(), task, String.valueOf(task.getTaskStatus()), reason); + + } + + private void publishNotification(Member receiver, Task task, String message, String reason) { + sendNotificationService.sendPushNotification(receiver, NotificationType.STATUS_SWITCHED, task, message, reason, null, false); } } diff --git a/src/main/java/clap/server/application/service/task/UpdateTaskBoardService.java b/src/main/java/clap/server/application/service/task/UpdateTaskBoardService.java index 095efc53..44836fd6 100644 --- a/src/main/java/clap/server/application/service/task/UpdateTaskBoardService.java +++ b/src/main/java/clap/server/application/service/task/UpdateTaskBoardService.java @@ -159,7 +159,7 @@ public void updateTaskOrderAndStatus(Long processorId, UpdateTaskOrderRequest re TaskHistory taskHistory = TaskHistory.createTaskHistory(TaskHistoryType.STATUS_SWITCHED, updatedTask, targetStatus.getDescription(), null,null); commandTaskHistoryPort.save(taskHistory); - publishNotification(targetTask, NotificationType.STATUS_SWITCHED, String.valueOf(updatedTask.getTaskStatus())); + publishNotification(targetTask); } /** @@ -181,14 +181,14 @@ public void validateRequest(UpdateTaskOrderRequest request, TaskStatus targetSta } } - private void publishNotification(Task task, NotificationType notificationType, String message) { + private void publishNotification(Task task) { List receivers = List.of(task.getRequester(), task.getProcessor()); receivers.forEach(receiver -> { boolean isManager = receiver.getMemberInfo().getRole() == MemberRole.ROLE_MANAGER; - sendNotificationService.sendPushNotification(receiver, notificationType, task, message, null, isManager); + sendNotificationService.sendPushNotification(receiver, NotificationType.STATUS_SWITCHED, task, String.valueOf(task.getTaskStatus()), null, null, isManager); }); - sendNotificationService.sendAgitNotification(notificationType, - task, message, null); + sendNotificationService.sendAgitNotification(NotificationType.STATUS_SWITCHED, + task, String.valueOf(task.getTaskStatus()), null); } } diff --git a/src/main/java/clap/server/application/service/task/UpdateTaskService.java b/src/main/java/clap/server/application/service/task/UpdateTaskService.java index 64af78a5..56d000b4 100644 --- a/src/main/java/clap/server/application/service/task/UpdateTaskService.java +++ b/src/main/java/clap/server/application/service/task/UpdateTaskService.java @@ -151,7 +151,7 @@ private void publishNotification(List receivers, Task task, Notification receivers.forEach(receiver -> { boolean isManager = receiver.getMemberInfo().getRole() == MemberRole.ROLE_MANAGER; sendNotificationService.sendPushNotification(receiver, notificationType, - task, message, null, isManager); + task, message, null, null, isManager); }); sendNotificationService.sendAgitNotification(notificationType, task, message, null); diff --git a/src/main/java/clap/server/application/service/webhook/SendNotificationService.java b/src/main/java/clap/server/application/service/webhook/SendNotificationService.java index e3d28748..f28c4852 100644 --- a/src/main/java/clap/server/application/service/webhook/SendNotificationService.java +++ b/src/main/java/clap/server/application/service/webhook/SendNotificationService.java @@ -37,7 +37,7 @@ public class SendNotificationService { @Async("notificationExecutor") public void sendPushNotification(Member receiver, NotificationType notificationType, - Task task, String message, String commenterName, Boolean isManager) { + Task task, String message, String reason, String commenterName, Boolean isManager) { String email = receiver.getMemberInfo().getEmail(); String taskTitle = task.getTitle(); @@ -48,7 +48,7 @@ public void sendPushNotification(Member receiver, NotificationType notificationT Notification notification = createTaskNotification(task, receiver, notificationType, message, taskTitle); PushNotificationTemplate pushNotificationTemplate = new PushNotificationTemplate( - email, notificationType, taskTitle, requesterNickname, message, commenterName + email, notificationType, taskTitle, requesterNickname, message, commenterName, reason ); CompletableFuture saveNotification = CompletableFuture.runAsync(() -> { @@ -95,7 +95,8 @@ public void sendAgitNotification(NotificationType notificationType, task.getTitle(), task.getRequester().getNickname(), message, - commenterName + commenterName, + null ); String taskDetailUrl = extractTaskUrl(notificationType, task, true); diff --git a/src/main/resources/templates/task-terminated.html b/src/main/resources/templates/task-terminated.html new file mode 100644 index 00000000..6c01732f --- /dev/null +++ b/src/main/resources/templates/task-terminated.html @@ -0,0 +1,86 @@ + + + + + Notion Notification + + + + + +