From 822547fccf6f5bcf4e3ad0ecc4d9178a0032cb79 Mon Sep 17 00:00:00 2001 From: mmihye Date: Thu, 10 Oct 2024 22:10:43 +0900 Subject: [PATCH 1/9] =?UTF-8?q?[#243]=20feat:=20=EB=94=94=EC=8A=A4?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- linkmind/build.gradle | 9 ++++ .../com/app/toaster/ToasterApplication.java | 2 + .../java/com/app/toaster/exception/Error.java | 1 + .../client/discord/DiscordClient.java | 13 +++++ .../client/discord/DiscordMessage.java | 29 ++++++++++ .../discord/DiscordMessageProvider.java | 54 +++++++++++++++++++ .../app/toaster/service/auth/AuthService.java | 9 +++- 7 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordClient.java create mode 100644 linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessage.java create mode 100644 linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java diff --git a/linkmind/build.gradle b/linkmind/build.gradle index 2d94ddd..99c3874 100644 --- a/linkmind/build.gradle +++ b/linkmind/build.gradle @@ -79,6 +79,15 @@ dependencies { implementation 'io.sentry:sentry-spring-boot-starter:5.7.0' + // openfeign + implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' + +} + +dependencyManagement { + imports { + mavenBom("org.springframework.cloud:spring-cloud-dependencies:2023.0.3") + } } //sourceSets { // main { diff --git a/linkmind/src/main/java/com/app/toaster/ToasterApplication.java b/linkmind/src/main/java/com/app/toaster/ToasterApplication.java index cc0c595..d85e4b4 100644 --- a/linkmind/src/main/java/com/app/toaster/ToasterApplication.java +++ b/linkmind/src/main/java/com/app/toaster/ToasterApplication.java @@ -3,6 +3,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cglib.core.Local; +import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import javax.annotation.PostConstruct; @@ -10,6 +11,7 @@ import java.util.TimeZone; @SpringBootApplication +@EnableFeignClients @EnableJpaAuditing public class ToasterApplication { diff --git a/linkmind/src/main/java/com/app/toaster/exception/Error.java b/linkmind/src/main/java/com/app/toaster/exception/Error.java index 59b542e..164c3f9 100644 --- a/linkmind/src/main/java/com/app/toaster/exception/Error.java +++ b/linkmind/src/main/java/com/app/toaster/exception/Error.java @@ -70,6 +70,7 @@ public enum Error { CREATE_PUBLIC_KEY_EXCEPTION(HttpStatus.INTERNAL_SERVER_ERROR, "publickey 생성 과정 중 문제가 발생했습니다."), FAIL_TO_SEND_PUSH_ALARM(HttpStatus.INTERNAL_SERVER_ERROR, "다수기기 푸시메시지 전송 실패"), FAIL_TO_SEND_SQS(HttpStatus.INTERNAL_SERVER_ERROR, "sqs 전송 실패"), + INVALID_DISCORD_MESSAGE(HttpStatus.INTERNAL_SERVER_ERROR, "디스코드 알림 전송 실패"), CREATE_TOAST_PROCCESS_EXCEPTION(HttpStatus.INTERNAL_SERVER_ERROR, "토스트 저장 중 문제가 발생했습니다. 카테고리 또는 s3 관련 문제로 예상됩니다.") ; diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordClient.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordClient.java new file mode 100644 index 0000000..6f27ff5 --- /dev/null +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordClient.java @@ -0,0 +1,13 @@ +package com.app.toaster.external.client.discord; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +@FeignClient(name = "${discord.name}", url = "${discord.webhook-url}") +public interface DiscordClient { + @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE) + void sendMessage(@RequestBody DiscordMessage discordMessage); +} \ No newline at end of file diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessage.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessage.java new file mode 100644 index 0000000..ba64baf --- /dev/null +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessage.java @@ -0,0 +1,29 @@ +package com.app.toaster.external.client.discord; + +import java.util.List; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Builder +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class DiscordMessage { + + private String content; + private List embeds; + + @Builder + @AllArgsConstructor(access = AccessLevel.PROTECTED) + @NoArgsConstructor(access = AccessLevel.PROTECTED) + @Getter + public static class Embed { + + private String title; + private String description; + } +} \ No newline at end of file diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java new file mode 100644 index 0000000..c7a2fd2 --- /dev/null +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java @@ -0,0 +1,54 @@ +package com.app.toaster.external.client.discord; + +import java.time.LocalDateTime; +import java.util.List; + +import org.springframework.context.ApplicationContextException; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.WebRequest; + +import com.app.toaster.exception.Error; +import com.app.toaster.exception.model.CustomException; +import com.app.toaster.infrastructure.UserRepository; + +import feign.FeignException; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Component +public class DiscordMessageProvider { + private final DiscordClient discordClient; + private final UserRepository userRepository; + + public void sendSignUpNotification() { + sendMessageToDiscord(createSingUpMessage()); + } + + private void sendMessageToDiscord(DiscordMessage discordMessage) { + try { + discordClient.sendMessage(discordMessage); + } catch (FeignException e) { + throw new CustomException(Error.INVALID_DISCORD_MESSAGE, Error.INVALID_APPLE_IDENTITY_TOKEN.getMessage()); + } + } + + private DiscordMessage createSingUpMessage() { + return DiscordMessage.builder() + .content("# 😍 회원가입 이벤트가 발생했습니다.") + .embeds( + List.of( + DiscordMessage.Embed.builder() + .title("ℹ️ 회원가입 정보") + .description( + "### 🕖 발생 시간\n" + + LocalDateTime.now() + + "\n" + + "### 📜 유저 가입 정보\n" + + "토스터의 " + userRepository.count() + "번째 유저가 생성되었습니다!! ❤️" + + "\n") + .build() + ) + ) + .build(); + } +} \ No newline at end of file diff --git a/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java b/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java index 4855e58..a5e6cbb 100644 --- a/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java +++ b/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java @@ -1,11 +1,13 @@ package com.app.toaster.service.auth; import java.io.IOException; +import java.time.LocalDateTime; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.client.RestTemplate; +import org.springframework.web.context.request.WebRequest; import com.app.toaster.common.dto.ApiResponse; import com.app.toaster.config.jwt.JwtService; @@ -21,6 +23,8 @@ import com.app.toaster.exception.model.CustomException; import com.app.toaster.exception.model.NotFoundException; import com.app.toaster.exception.model.UnprocessableEntityException; +import com.app.toaster.external.client.discord.DiscordMessage; +import com.app.toaster.external.client.discord.DiscordMessageProvider; import com.app.toaster.external.client.slack.SlackApi; import com.app.toaster.infrastructure.CategoryRepository; import com.app.toaster.infrastructure.TimerRepository; @@ -48,6 +52,7 @@ public class AuthService { private final PopupManagerRepository popupManagerRepository; private final SlackApi slackApi; + private final DiscordMessageProvider discordMessageProvider; private final Long TOKEN_EXPIRATION_TIME_ACCESS = 7*24*60 * 60 * 1000L; //7일 @@ -76,7 +81,8 @@ public SignInResponseDto signIn(String socialAccessToken, SignInRequestDto reque .socialType(socialType).build(); newUser.updateFcmIsAllowed(true); //신규 유저면 true박고 userRepository.save(newUser); - slackApi.sendSuccess(Success.LOGIN_SUCCESS); + // slackApi.sendSuccess(Success.LOGIN_SUCCESS); + discordMessageProvider.sendSignUpNotification(); } User user = userRepository.findBySocialIdAndSocialType(socialId, socialType) @@ -167,4 +173,5 @@ public TokenHealthDto checkHealthOfToken(String refreshToken){ return TokenHealthDto.of(jwtService.verifyToken(refreshToken)); } + } From fce672707e650e80e3139527204a5ce0fb72be8a Mon Sep 17 00:00:00 2001 From: mmihye Date: Thu, 10 Oct 2024 22:42:04 +0900 Subject: [PATCH 2/9] =?UTF-8?q?[#243]=20feat:=20=EB=94=94=EC=8A=A4?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20+?= =?UTF-8?q?=20=EC=97=90=EB=9F=AC=20=EC=95=8C=EB=A6=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../advice/ControllerExceptionAdvice.java | 28 ++++---- .../controller/HealthCheckController.java | 10 +++ ...ordClient.java => DiscordErrorClient.java} | 5 +- .../discord/DiscordMessageProvider.java | 65 +++++++++++++++++-- .../client/discord/DiscordSingUpClient.java | 12 ++++ 5 files changed, 98 insertions(+), 22 deletions(-) rename linkmind/src/main/java/com/app/toaster/external/client/discord/{DiscordClient.java => DiscordErrorClient.java} (70%) create mode 100644 linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordSingUpClient.java diff --git a/linkmind/src/main/java/com/app/toaster/common/advice/ControllerExceptionAdvice.java b/linkmind/src/main/java/com/app/toaster/common/advice/ControllerExceptionAdvice.java index 6be80bc..73508fd 100644 --- a/linkmind/src/main/java/com/app/toaster/common/advice/ControllerExceptionAdvice.java +++ b/linkmind/src/main/java/com/app/toaster/common/advice/ControllerExceptionAdvice.java @@ -20,11 +20,13 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.context.request.WebRequest; import org.springframework.web.method.annotation.HandlerMethodValidationException; import com.app.toaster.common.dto.ApiResponse; import com.app.toaster.exception.Error; import com.app.toaster.exception.model.CustomException; +import com.app.toaster.external.client.discord.DiscordMessageProvider; import com.app.toaster.external.client.slack.SlackApi; import io.sentry.Sentry; @@ -39,12 +41,13 @@ @RequiredArgsConstructor public class ControllerExceptionAdvice { private final SlackApi slackApi; + private final DiscordMessageProvider discordMessageProvider; /** * custom error */ @ExceptionHandler(CustomException.class) - protected ResponseEntity handleCustomException(CustomException e) { + protected ResponseEntity handleCustomException(CustomException e , WebRequest request) { Sentry.captureException(e); return ResponseEntity.status(e.getHttpStatus()) .body(ApiResponse.error(e.getError(), e.getMessage())); @@ -52,7 +55,7 @@ protected ResponseEntity handleCustomException(CustomException e) { @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(MethodArgumentNotValidException.class) - protected ResponseEntity handleConstraintDefinitionException(final MethodArgumentNotValidException e) { + protected ResponseEntity handleConstraintDefinitionException(final MethodArgumentNotValidException e, WebRequest request) { FieldError fieldError = e.getBindingResult().getFieldError(); Sentry.captureException(e); return ResponseEntity.status(e.getStatusCode()) @@ -60,7 +63,7 @@ protected ResponseEntity handleConstraintDefinitionException(final } @ExceptionHandler(MalformedURLException.class) - protected ResponseEntity handleConstraintDefinitionException(final MalformedURLException e) { + protected ResponseEntity handleConstraintDefinitionException(final MalformedURLException e, WebRequest request) { Sentry.captureException(e); return ResponseEntity.status(Error.MALFORMED_URL_EXEPTION.getErrorCode()) .body(ApiResponse.error(Error.MALFORMED_URL_EXEPTION, Error.MALFORMED_URL_EXEPTION.getMessage())); @@ -68,42 +71,42 @@ protected ResponseEntity handleConstraintDefinitionException(final @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(DateTimeParseException.class) - protected ResponseEntity handleDateTimeParseException(final DateTimeParseException e) { + protected ResponseEntity handleDateTimeParseException(final DateTimeParseException e, WebRequest request) { return ResponseEntity.status(Error.BAD_REQUEST_REMIND_TIME.getErrorCode()) .body(ApiResponse.error(Error.BAD_REQUEST_REMIND_TIME, Error.BAD_REQUEST_REMIND_TIME.getMessage())); } @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(HttpRequestMethodNotSupportedException.class) - protected ResponseEntity handleHttpRequestMethodNotSupportedException(final HttpRequestMethodNotSupportedException e) { + protected ResponseEntity handleHttpRequestMethodNotSupportedException(final HttpRequestMethodNotSupportedException e, WebRequest request) { return ResponseEntity.status(e.getStatusCode()) .body(ApiResponse.error(Error.REQUEST_METHOD_VALIDATION_EXCEPTION, Error.REQUEST_METHOD_VALIDATION_EXCEPTION.getMessage())); } @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(HttpMediaTypeNotSupportedException.class) - protected ResponseEntity handleHttpMediaTypeNotSupportedException(final HttpMediaTypeNotSupportedException e) { + protected ResponseEntity handleHttpMediaTypeNotSupportedException(final HttpMediaTypeNotSupportedException e, WebRequest request) { return ResponseEntity.status(e.getStatusCode()) .body(ApiResponse.error(Error.REQUEST_MEDIA_TYPE_VALIDATION_EXCEPTION, Error.REQUEST_MEDIA_TYPE_VALIDATION_EXCEPTION.getMessage())); } @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(MissingServletRequestParameterException.class) - protected ResponseEntity MissingServletRequestParameterException(final MissingServletRequestParameterException e) { + protected ResponseEntity MissingServletRequestParameterException(final MissingServletRequestParameterException e, WebRequest request) { return ResponseEntity.status(e.getStatusCode()) .body(ApiResponse.error(Error.BAD_REQUEST_VALIDATION, Error.BAD_REQUEST_VALIDATION.getMessage())); } @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(HttpMessageNotReadableException.class) - protected ResponseEntity MissingServletRequestParameterException(final HttpMessageNotReadableException e) { + protected ResponseEntity MissingServletRequestParameterException(final HttpMessageNotReadableException e, WebRequest request) { return ResponseEntity.status(Error.BAD_REQUEST_VALIDATION.getErrorCode()) .body(ApiResponse.error(Error.BAD_REQUEST_VALIDATION, Error.BAD_REQUEST_VALIDATION.getMessage())); } @ResponseStatus(HttpStatus.BAD_REQUEST) // 커스텀 validation 에러 핸들링. @ExceptionHandler(HandlerMethodValidationException.class) - protected ResponseEntity ConstraintViolationException(final HandlerMethodValidationException e) { + protected ResponseEntity ConstraintViolationException(final HandlerMethodValidationException e, WebRequest request) { Sentry.captureException(e); return ResponseEntity.status(Error.BAD_REQUEST_VALIDATION.getErrorCode()) .body(ApiResponse.error(Error.BAD_REQUEST_VALIDATION, Error.BAD_REQUEST_VALIDATION.getMessage())); @@ -111,7 +114,7 @@ protected ResponseEntity ConstraintViolationException(final Handler @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(UnknownHostException.class) - protected ResponseEntity UnknownHostException(final UnknownHostException e) { + protected ResponseEntity UnknownHostException(final UnknownHostException e, WebRequest request) { Sentry.captureException(e); return ResponseEntity.status(Error.BAD_REQUEST_VALIDATION.getErrorCode()) .body(ApiResponse.error(Error.BAD_REQUEST_VALIDATION, Error.BAD_REQUEST_VALIDATION.getMessage())); @@ -119,7 +122,7 @@ protected ResponseEntity UnknownHostException(final UnknownHostExce @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(MissingRequestHeaderException.class) - protected ResponseEntity MissingRequestHeaderException(final MissingRequestHeaderException e){ + protected ResponseEntity MissingRequestHeaderException(final MissingRequestHeaderException e, WebRequest request){ Sentry.captureException(e); return ResponseEntity.status(Error.BAD_REQUEST_VALIDATION.getErrorCode()) .body(ApiResponse.error(Error.BAD_REQUEST_VALIDATION, Error.BAD_REQUEST_VALIDATION.getMessage())); @@ -134,8 +137,9 @@ protected ResponseEntity MissingRequestHeaderException(final Missin @ExceptionHandler(Exception.class) protected ApiResponse handleException(final Exception error, final HttpServletRequest request) throws IOException { - slackApi.sendAlert(error, request); + // slackApi.sendAlert(error, request); Sentry.captureException(error); + discordMessageProvider.sendErrorNotification(error,request.getRequestURI()); return ApiResponse.error(Error.INTERNAL_SERVER_ERROR); } diff --git a/linkmind/src/main/java/com/app/toaster/controller/HealthCheckController.java b/linkmind/src/main/java/com/app/toaster/controller/HealthCheckController.java index 3582b1f..2d04f01 100644 --- a/linkmind/src/main/java/com/app/toaster/controller/HealthCheckController.java +++ b/linkmind/src/main/java/com/app/toaster/controller/HealthCheckController.java @@ -1,8 +1,18 @@ package com.app.toaster.controller; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; +import com.app.toaster.controller.request.toast.IsReadDto; +import com.app.toaster.controller.response.toast.IsReadResponse; +import com.app.toaster.domain.User; +import com.app.toaster.exception.Error; +import com.app.toaster.exception.model.NotFoundException; +import com.app.toaster.infrastructure.UserRepository; + +import lombok.RequiredArgsConstructor; + @RestController public class HealthCheckController { diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordClient.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordErrorClient.java similarity index 70% rename from linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordClient.java rename to linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordErrorClient.java index 6f27ff5..aba5a0f 100644 --- a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordClient.java +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordErrorClient.java @@ -1,13 +1,12 @@ package com.app.toaster.external.client.discord; -import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -@FeignClient(name = "${discord.name}", url = "${discord.webhook-url}") -public interface DiscordClient { +@FeignClient(name = "${discord.sign-name}", url = "${discord.webhook-url-error}") +public interface DiscordErrorClient { @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE) void sendMessage(@RequestBody DiscordMessage discordMessage); } \ No newline at end of file diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java index c7a2fd2..9ca8fe5 100644 --- a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java @@ -1,10 +1,14 @@ package com.app.toaster.external.client.discord; +import java.io.PrintWriter; +import java.io.StringWriter; import java.time.LocalDateTime; import java.util.List; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContextException; import org.springframework.stereotype.Component; +import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.WebRequest; import com.app.toaster.exception.Error; @@ -12,26 +16,30 @@ import com.app.toaster.infrastructure.UserRepository; import feign.FeignException; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @Component public class DiscordMessageProvider { - private final DiscordClient discordClient; + private final DiscordSingUpClient discordSingUpClient; + private final DiscordErrorClient discordErrorClient; private final UserRepository userRepository; - public void sendSignUpNotification() { - sendMessageToDiscord(createSingUpMessage()); - } - - private void sendMessageToDiscord(DiscordMessage discordMessage) { try { - discordClient.sendMessage(discordMessage); + discordSingUpClient.sendMessage(createSingUpMessage()); } catch (FeignException e) { throw new CustomException(Error.INVALID_DISCORD_MESSAGE, Error.INVALID_APPLE_IDENTITY_TOKEN.getMessage()); } } + public void sendErrorNotification(Exception e, String request) { + try { + discordErrorClient.sendMessage(createErrorMessage(e,request)); + } catch (FeignException error) { + throw new CustomException(Error.INVALID_DISCORD_MESSAGE, Error.INVALID_APPLE_IDENTITY_TOKEN.getMessage()); + } + } private DiscordMessage createSingUpMessage() { return DiscordMessage.builder() .content("# 😍 회원가입 이벤트가 발생했습니다.") @@ -51,4 +59,47 @@ private DiscordMessage createSingUpMessage() { ) .build(); } + + + private DiscordMessage createErrorMessage(Exception e, String requestUrl) { + return DiscordMessage.builder() + .content("# 🚨 삐용삐용 에러났어요 에러났어요") + .embeds( + List.of( + DiscordMessage.Embed.builder() + .title("ℹ️ 에러 정보") + .description( + "### 🕖 발생 시간\n" + + LocalDateTime.now() + + "\n" + + "### 🔗 요청 URL\n" + + requestUrl + + "\n" + + "### 📄 Stack Trace\n" + + "```\n" + + getStackTrace(e).substring(0, 1000) + + "\n```") + .build() + ) + ) + .build(); + } + + private String createRequestFullPath(WebRequest webRequest) { + HttpServletRequest request = ((ServletWebRequest) webRequest).getRequest(); + String fullPath = request.getMethod() + " " + request.getRequestURL(); + + String queryString = request.getQueryString(); + if (queryString != null) { + fullPath += "?" + queryString; + } + + return fullPath; + } + + private String getStackTrace(Exception e) { + StringWriter stringWriter = new StringWriter(); + e.printStackTrace(new PrintWriter(stringWriter)); + return stringWriter.toString(); + } } \ No newline at end of file diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordSingUpClient.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordSingUpClient.java new file mode 100644 index 0000000..23a37e8 --- /dev/null +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordSingUpClient.java @@ -0,0 +1,12 @@ +package com.app.toaster.external.client.discord; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +@FeignClient(name = "${discord.error-name}", url = "${discord.webhook-url-sign}") +public interface DiscordSingUpClient { + @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE) + void sendMessage(@RequestBody DiscordMessage discordMessage); +} \ No newline at end of file From 83e5387fe20efcf95df8f542b8e21508d0fe374b Mon Sep 17 00:00:00 2001 From: mmihye Date: Tue, 15 Oct 2024 23:01:38 +0900 Subject: [PATCH 3/9] =?UTF-8?q?[#243]=20feat:=20=EB=A1=9C=EC=BB=AC?= =?UTF-8?q?=EC=97=90=EC=84=9C=EB=8A=94=20=EC=97=90=EB=9F=AC=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=A0=84=EC=86=A1=EB=90=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../advice/ControllerExceptionAdvice.java | 3 +- .../discord/DiscordMessageProvider.java | 28 ++++++++++--------- .../client/discord/NotificationType.java | 6 ++++ .../app/toaster/service/auth/AuthService.java | 3 +- 4 files changed, 25 insertions(+), 15 deletions(-) create mode 100644 linkmind/src/main/java/com/app/toaster/external/client/discord/NotificationType.java diff --git a/linkmind/src/main/java/com/app/toaster/common/advice/ControllerExceptionAdvice.java b/linkmind/src/main/java/com/app/toaster/common/advice/ControllerExceptionAdvice.java index 73508fd..912433a 100644 --- a/linkmind/src/main/java/com/app/toaster/common/advice/ControllerExceptionAdvice.java +++ b/linkmind/src/main/java/com/app/toaster/common/advice/ControllerExceptionAdvice.java @@ -27,6 +27,7 @@ import com.app.toaster.exception.Error; import com.app.toaster.exception.model.CustomException; import com.app.toaster.external.client.discord.DiscordMessageProvider; +import com.app.toaster.external.client.discord.NotificationType; import com.app.toaster.external.client.slack.SlackApi; import io.sentry.Sentry; @@ -139,7 +140,7 @@ protected ApiResponse handleException(final Exception error, final HttpS IOException { // slackApi.sendAlert(error, request); Sentry.captureException(error); - discordMessageProvider.sendErrorNotification(error,request.getRequestURI()); + discordMessageProvider.sendNotification(NotificationType.ERROR,error,request.getRequestURI()); return ApiResponse.error(Error.INTERNAL_SERVER_ERROR); } diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java index 9ca8fe5..8cdfd6f 100644 --- a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java @@ -3,10 +3,12 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.List; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContextException; +import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.WebRequest; @@ -23,23 +25,23 @@ @Component public class DiscordMessageProvider { private final DiscordSingUpClient discordSingUpClient; - private final DiscordErrorClient discordErrorClient; private final UserRepository userRepository; - public void sendSignUpNotification() { - try { - discordSingUpClient.sendMessage(createSingUpMessage()); - } catch (FeignException e) { - throw new CustomException(Error.INVALID_DISCORD_MESSAGE, Error.INVALID_APPLE_IDENTITY_TOKEN.getMessage()); - } - } + private final Environment environment; - public void sendErrorNotification(Exception e, String request) { - try { - discordErrorClient.sendMessage(createErrorMessage(e,request)); - } catch (FeignException error) { - throw new CustomException(Error.INVALID_DISCORD_MESSAGE, Error.INVALID_APPLE_IDENTITY_TOKEN.getMessage()); + public void sendNotification(NotificationType type, Exception e, String request) { + if (!Arrays.asList(environment.getActiveProfiles()).contains("local")) { + try { + switch (type){ + case ERROR -> discordSingUpClient.sendMessage(createErrorMessage(e,request)); + case SINGUP -> discordSingUpClient.sendMessage(createSingUpMessage()); + } + } catch (FeignException error) { + throw new CustomException(Error.INVALID_DISCORD_MESSAGE, + Error.INVALID_APPLE_IDENTITY_TOKEN.getMessage()); + } } } + private DiscordMessage createSingUpMessage() { return DiscordMessage.builder() .content("# 😍 회원가입 이벤트가 발생했습니다.") diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/NotificationType.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/NotificationType.java new file mode 100644 index 0000000..d04f377 --- /dev/null +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/NotificationType.java @@ -0,0 +1,6 @@ +package com.app.toaster.external.client.discord; + +public enum NotificationType { + ERROR, + SINGUP +} diff --git a/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java b/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java index a5e6cbb..e5bcbf4 100644 --- a/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java +++ b/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java @@ -25,6 +25,7 @@ import com.app.toaster.exception.model.UnprocessableEntityException; import com.app.toaster.external.client.discord.DiscordMessage; import com.app.toaster.external.client.discord.DiscordMessageProvider; +import com.app.toaster.external.client.discord.NotificationType; import com.app.toaster.external.client.slack.SlackApi; import com.app.toaster.infrastructure.CategoryRepository; import com.app.toaster.infrastructure.TimerRepository; @@ -82,7 +83,7 @@ public SignInResponseDto signIn(String socialAccessToken, SignInRequestDto reque newUser.updateFcmIsAllowed(true); //신규 유저면 true박고 userRepository.save(newUser); // slackApi.sendSuccess(Success.LOGIN_SUCCESS); - discordMessageProvider.sendSignUpNotification(); + discordMessageProvider.sendNotification(NotificationType.SINGUP,null,null); } User user = userRepository.findBySocialIdAndSocialType(socialId, socialType) From f947bdfd0eba0f40e69b30ad55c5542817db975b Mon Sep 17 00:00:00 2001 From: mmihye Date: Wed, 16 Oct 2024 23:12:54 +0900 Subject: [PATCH 4/9] =?UTF-8?q?[#243]=20fix:=20=EC=98=A4=ED=83=80=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../external/client/discord/DiscordMessageProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java index 8cdfd6f..f798671 100644 --- a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java @@ -33,7 +33,7 @@ public void sendNotification(NotificationType type, Exception e, String request) try { switch (type){ case ERROR -> discordSingUpClient.sendMessage(createErrorMessage(e,request)); - case SINGUP -> discordSingUpClient.sendMessage(createSingUpMessage()); + case SINGUP -> discordSingUpClient.sendMessage(createSignUpMessage()); } } catch (FeignException error) { throw new CustomException(Error.INVALID_DISCORD_MESSAGE, @@ -42,7 +42,7 @@ public void sendNotification(NotificationType type, Exception e, String request) } } - private DiscordMessage createSingUpMessage() { + private DiscordMessage createSignUpMessage() { return DiscordMessage.builder() .content("# 😍 회원가입 이벤트가 발생했습니다.") .embeds( From 81f671729cbb323624bfb173ab197444adf3cdb0 Mon Sep 17 00:00:00 2001 From: mmihye Date: Wed, 16 Oct 2024 23:30:30 +0900 Subject: [PATCH 5/9] =?UTF-8?q?[#243]=20fix:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=EC=8B=9C=20=EB=94=94=EC=8A=A4=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EC=97=90=EB=9F=AC=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/app/toaster/service/auth/AuthService.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java b/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java index e5bcbf4..6ed4c0b 100644 --- a/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java +++ b/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java @@ -39,7 +39,9 @@ import com.app.toaster.service.toast.ToastService; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +@Slf4j @Service @RequiredArgsConstructor public class AuthService { @@ -83,7 +85,12 @@ public SignInResponseDto signIn(String socialAccessToken, SignInRequestDto reque newUser.updateFcmIsAllowed(true); //신규 유저면 true박고 userRepository.save(newUser); // slackApi.sendSuccess(Success.LOGIN_SUCCESS); - discordMessageProvider.sendNotification(NotificationType.SINGUP,null,null); + + try { + discordMessageProvider.sendNotification(NotificationType.SINGUP,null,null); + } catch (Exception e) { + log.warn("discord SingUpNotification fail : userId = {}", newUser.getUserId()); + } } User user = userRepository.findBySocialIdAndSocialType(socialId, socialType) From a0f568f2fe35a750c70c1c2faa71349c78d1c5ba Mon Sep 17 00:00:00 2001 From: mmihye Date: Tue, 22 Oct 2024 22:07:10 +0900 Subject: [PATCH 6/9] =?UTF-8?q?[#243]=20fix:=20=EC=98=A4=ED=83=80=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../external/client/discord/DiscordMessageProvider.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java index f798671..02f0483 100644 --- a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java @@ -24,7 +24,7 @@ @RequiredArgsConstructor @Component public class DiscordMessageProvider { - private final DiscordSingUpClient discordSingUpClient; + private final DiscordSingUpClient discordSignUpClient; private final UserRepository userRepository; private final Environment environment; @@ -32,8 +32,8 @@ public void sendNotification(NotificationType type, Exception e, String request) if (!Arrays.asList(environment.getActiveProfiles()).contains("local")) { try { switch (type){ - case ERROR -> discordSingUpClient.sendMessage(createErrorMessage(e,request)); - case SINGUP -> discordSingUpClient.sendMessage(createSignUpMessage()); + case ERROR -> discordSignUpClient.sendMessage(createErrorMessage(e,request)); + case SINGUP -> discordSignUpClient.sendMessage(createSignUpMessage()); } } catch (FeignException error) { throw new CustomException(Error.INVALID_DISCORD_MESSAGE, From ad8cbd580404c1def6bfff5373200991ae704ee9 Mon Sep 17 00:00:00 2001 From: mmihye Date: Tue, 22 Oct 2024 22:18:29 +0900 Subject: [PATCH 7/9] =?UTF-8?q?[#243]=20feat:=20TransactionalEventListener?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../external/client/discord/DiscordMessageProvider.java | 5 +++++ .../java/com/app/toaster/service/auth/AuthService.java | 7 +------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java index 02f0483..5ca77c2 100644 --- a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java @@ -10,6 +10,10 @@ import org.springframework.context.ApplicationContextException; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.event.TransactionPhase; +import org.springframework.transaction.event.TransactionalEventListener; import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.WebRequest; @@ -28,6 +32,7 @@ public class DiscordMessageProvider { private final UserRepository userRepository; private final Environment environment; + @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) public void sendNotification(NotificationType type, Exception e, String request) { if (!Arrays.asList(environment.getActiveProfiles()).contains("local")) { try { diff --git a/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java b/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java index 6ed4c0b..84b44c4 100644 --- a/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java +++ b/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java @@ -84,13 +84,8 @@ public SignInResponseDto signIn(String socialAccessToken, SignInRequestDto reque .socialType(socialType).build(); newUser.updateFcmIsAllowed(true); //신규 유저면 true박고 userRepository.save(newUser); - // slackApi.sendSuccess(Success.LOGIN_SUCCESS); - try { - discordMessageProvider.sendNotification(NotificationType.SINGUP,null,null); - } catch (Exception e) { - log.warn("discord SingUpNotification fail : userId = {}", newUser.getUserId()); - } + discordMessageProvider.sendNotification(NotificationType.SINGUP,null,null); } User user = userRepository.findBySocialIdAndSocialType(socialId, socialType) From d8bb06f889dc10e27b9822801ee3fab82e780938 Mon Sep 17 00:00:00 2001 From: mmihye Date: Thu, 24 Oct 2024 20:30:00 +0900 Subject: [PATCH 8/9] =?UTF-8?q?[#243]=20feat:=20TransactionalEventListener?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20DiscordClient=20=ED=86=B5?= =?UTF-8?q?=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../advice/ControllerExceptionAdvice.java | 4 ++- .../controller/HealthCheckController.java | 5 ++++ ...ordErrorClient.java => DiscordClient.java} | 8 ++++-- .../discord/DiscordMessageProvider.java | 28 +++++++++++-------- .../client/discord/DiscordSingUpClient.java | 12 -------- .../client/discord/NotificationDto.java | 9 ++++++ .../client/discord/NotificationType.java | 2 +- .../app/toaster/service/auth/AuthService.java | 3 +- 8 files changed, 42 insertions(+), 29 deletions(-) rename linkmind/src/main/java/com/app/toaster/external/client/discord/{DiscordErrorClient.java => DiscordClient.java} (64%) delete mode 100644 linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordSingUpClient.java create mode 100644 linkmind/src/main/java/com/app/toaster/external/client/discord/NotificationDto.java diff --git a/linkmind/src/main/java/com/app/toaster/common/advice/ControllerExceptionAdvice.java b/linkmind/src/main/java/com/app/toaster/common/advice/ControllerExceptionAdvice.java index 912433a..34734d7 100644 --- a/linkmind/src/main/java/com/app/toaster/common/advice/ControllerExceptionAdvice.java +++ b/linkmind/src/main/java/com/app/toaster/common/advice/ControllerExceptionAdvice.java @@ -27,6 +27,7 @@ import com.app.toaster.exception.Error; import com.app.toaster.exception.model.CustomException; import com.app.toaster.external.client.discord.DiscordMessageProvider; +import com.app.toaster.external.client.discord.NotificationDto; import com.app.toaster.external.client.discord.NotificationType; import com.app.toaster.external.client.slack.SlackApi; @@ -140,7 +141,8 @@ protected ApiResponse handleException(final Exception error, final HttpS IOException { // slackApi.sendAlert(error, request); Sentry.captureException(error); - discordMessageProvider.sendNotification(NotificationType.ERROR,error,request.getRequestURI()); + discordMessageProvider.sendNotification( + new NotificationDto(NotificationType.ERROR,error,request.getRequestURI())); return ApiResponse.error(Error.INTERNAL_SERVER_ERROR); } diff --git a/linkmind/src/main/java/com/app/toaster/controller/HealthCheckController.java b/linkmind/src/main/java/com/app/toaster/controller/HealthCheckController.java index 2d04f01..ddfe791 100644 --- a/linkmind/src/main/java/com/app/toaster/controller/HealthCheckController.java +++ b/linkmind/src/main/java/com/app/toaster/controller/HealthCheckController.java @@ -9,12 +9,17 @@ import com.app.toaster.domain.User; import com.app.toaster.exception.Error; import com.app.toaster.exception.model.NotFoundException; +import com.app.toaster.external.client.discord.DiscordMessageProvider; +import com.app.toaster.external.client.discord.NotificationDto; +import com.app.toaster.external.client.discord.NotificationType; import com.app.toaster.infrastructure.UserRepository; import lombok.RequiredArgsConstructor; @RestController +@RequiredArgsConstructor public class HealthCheckController { + private final DiscordMessageProvider discordMessageProvider; @GetMapping("/health") public String healthCheck() { diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordErrorClient.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordClient.java similarity index 64% rename from linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordErrorClient.java rename to linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordClient.java index aba5a0f..b56c368 100644 --- a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordErrorClient.java +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordClient.java @@ -1,12 +1,14 @@ package com.app.toaster.external.client.discord; +import java.net.URI; + import org.springframework.cloud.openfeign.FeignClient; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -@FeignClient(name = "${discord.sign-name}", url = "${discord.webhook-url-error}") -public interface DiscordErrorClient { +@FeignClient(name = "discord-feign-client", url = "URI") +public interface DiscordClient { @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE) - void sendMessage(@RequestBody DiscordMessage discordMessage); + void sendMessage(URI uri, @RequestBody DiscordMessage discordMessage); } \ No newline at end of file diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java index 5ca77c2..2ec9966 100644 --- a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordMessageProvider.java @@ -2,16 +2,14 @@ import java.io.PrintWriter; import java.io.StringWriter; +import java.net.URI; import java.time.LocalDateTime; import java.util.Arrays; import java.util.List; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.ApplicationContextException; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.event.TransactionPhase; import org.springframework.transaction.event.TransactionalEventListener; import org.springframework.web.context.request.ServletWebRequest; @@ -24,25 +22,33 @@ import feign.FeignException; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; @RequiredArgsConstructor @Component +@Slf4j public class DiscordMessageProvider { - private final DiscordSingUpClient discordSignUpClient; + private final DiscordClient discordClient; private final UserRepository userRepository; private final Environment environment; + @Value("${discord.webhook-url-error}") + private String webhookUrlError; + + + @Value("${discord.webhook-url-sign}") + private String webhookUrlSign; + @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) - public void sendNotification(NotificationType type, Exception e, String request) { + public void sendNotification(NotificationDto notification) { if (!Arrays.asList(environment.getActiveProfiles()).contains("local")) { try { - switch (type){ - case ERROR -> discordSignUpClient.sendMessage(createErrorMessage(e,request)); - case SINGUP -> discordSignUpClient.sendMessage(createSignUpMessage()); + switch (notification.type()){ + case ERROR -> discordClient.sendMessage(URI.create(webhookUrlError), createErrorMessage(notification.e(), notification.request())); + case SIGNUP -> discordClient.sendMessage(URI.create(webhookUrlSign), createSignUpMessage()); } - } catch (FeignException error) { - throw new CustomException(Error.INVALID_DISCORD_MESSAGE, - Error.INVALID_APPLE_IDENTITY_TOKEN.getMessage()); + } catch (Exception error) { + log.warn("discord notification fail : " + error); } } } diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordSingUpClient.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordSingUpClient.java deleted file mode 100644 index 23a37e8..0000000 --- a/linkmind/src/main/java/com/app/toaster/external/client/discord/DiscordSingUpClient.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.app.toaster.external.client.discord; - -import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; - -@FeignClient(name = "${discord.error-name}", url = "${discord.webhook-url-sign}") -public interface DiscordSingUpClient { - @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE) - void sendMessage(@RequestBody DiscordMessage discordMessage); -} \ No newline at end of file diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/NotificationDto.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/NotificationDto.java new file mode 100644 index 0000000..5a745c7 --- /dev/null +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/NotificationDto.java @@ -0,0 +1,9 @@ +package com.app.toaster.external.client.discord; + + +public record NotificationDto( + NotificationType type, + Exception e, + String request +) { +} diff --git a/linkmind/src/main/java/com/app/toaster/external/client/discord/NotificationType.java b/linkmind/src/main/java/com/app/toaster/external/client/discord/NotificationType.java index d04f377..ac154ab 100644 --- a/linkmind/src/main/java/com/app/toaster/external/client/discord/NotificationType.java +++ b/linkmind/src/main/java/com/app/toaster/external/client/discord/NotificationType.java @@ -2,5 +2,5 @@ public enum NotificationType { ERROR, - SINGUP + SIGNUP } diff --git a/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java b/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java index 84b44c4..6a34f89 100644 --- a/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java +++ b/linkmind/src/main/java/com/app/toaster/service/auth/AuthService.java @@ -25,6 +25,7 @@ import com.app.toaster.exception.model.UnprocessableEntityException; import com.app.toaster.external.client.discord.DiscordMessage; import com.app.toaster.external.client.discord.DiscordMessageProvider; +import com.app.toaster.external.client.discord.NotificationDto; import com.app.toaster.external.client.discord.NotificationType; import com.app.toaster.external.client.slack.SlackApi; import com.app.toaster.infrastructure.CategoryRepository; @@ -85,7 +86,7 @@ public SignInResponseDto signIn(String socialAccessToken, SignInRequestDto reque newUser.updateFcmIsAllowed(true); //신규 유저면 true박고 userRepository.save(newUser); - discordMessageProvider.sendNotification(NotificationType.SINGUP,null,null); + discordMessageProvider.sendNotification(new NotificationDto(NotificationType.SIGNUP,null,null)); } User user = userRepository.findBySocialIdAndSocialType(socialId, socialType) From 898fa9d08710c05751c4af3c5f109edc3a4ee309 Mon Sep 17 00:00:00 2001 From: mmihye Date: Thu, 24 Oct 2024 20:31:37 +0900 Subject: [PATCH 9/9] =?UTF-8?q?[#243]=20fix:=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20import=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/app/toaster/controller/HealthCheckController.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/linkmind/src/main/java/com/app/toaster/controller/HealthCheckController.java b/linkmind/src/main/java/com/app/toaster/controller/HealthCheckController.java index ddfe791..43d22a4 100644 --- a/linkmind/src/main/java/com/app/toaster/controller/HealthCheckController.java +++ b/linkmind/src/main/java/com/app/toaster/controller/HealthCheckController.java @@ -4,11 +4,6 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import com.app.toaster.controller.request.toast.IsReadDto; -import com.app.toaster.controller.response.toast.IsReadResponse; -import com.app.toaster.domain.User; -import com.app.toaster.exception.Error; -import com.app.toaster.exception.model.NotFoundException; import com.app.toaster.external.client.discord.DiscordMessageProvider; import com.app.toaster.external.client.discord.NotificationDto; import com.app.toaster.external.client.discord.NotificationType;