From b7608cba71e450831526a1d1d2af471793e2c3c7 Mon Sep 17 00:00:00 2001 From: Park Yun Chan Date: Wed, 2 Oct 2024 21:09:13 +0900 Subject: [PATCH] =?UTF-8?q?=ED=94=BC=EB=93=9C=20=EC=8B=A0=EA=B3=A0?= =?UTF-8?q?=EC=8B=9C=20discord=20=EC=95=8C=EB=A6=BC=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84=20(#290)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feature: 피드 신고시 discord 알림 기능 구현 * fix: properties사용하는방법으로 수정 * fix: comment기능 merge --- .../DiscordNotificationService.java | 52 +++++++++++++++++++ .../report/application/ReportService.java | 48 ++++++++++++++++- .../stonebed/global/error/ErrorCode.java | 6 ++- .../infra/properties/DiscordProperties.java | 6 +++ .../infra/properties/PropertiesConfig.java | 3 +- src/main/resources/application.yml | 3 ++ 6 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/depromeet/stonebed/domain/discord/application/DiscordNotificationService.java create mode 100644 src/main/java/com/depromeet/stonebed/infra/properties/DiscordProperties.java diff --git a/src/main/java/com/depromeet/stonebed/domain/discord/application/DiscordNotificationService.java b/src/main/java/com/depromeet/stonebed/domain/discord/application/DiscordNotificationService.java new file mode 100644 index 00000000..43f1452c --- /dev/null +++ b/src/main/java/com/depromeet/stonebed/domain/discord/application/DiscordNotificationService.java @@ -0,0 +1,52 @@ +package com.depromeet.stonebed.domain.discord.application; + +import com.depromeet.stonebed.global.error.ErrorCode; +import com.depromeet.stonebed.global.error.exception.CustomException; +import com.depromeet.stonebed.infra.properties.DiscordProperties; +import java.util.HashMap; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.client.RestClient; + +@Slf4j +@Service +@RequiredArgsConstructor +@Transactional +public class DiscordNotificationService { + + private final DiscordProperties discordProperties; + private final RestClient restClient; + + public void sendDiscordMessage(String message) { + Map payload = new HashMap<>(); + payload.put("content", message); + + try { + String discordWebhookUrl = discordProperties.url(); + log.info("Sending Discord notification to URL: {}", discordWebhookUrl); + + restClient + .post() + .uri(discordWebhookUrl) + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .body(payload) + .exchange( + (request, response) -> { + if (!response.getStatusCode().is2xxSuccessful()) { + throw new CustomException( + ErrorCode.DISCORD_NOTIFICATION_FAILED); + } + log.info("Discord 알림 전송 성공: {}", message); + return response.bodyTo(String.class); + }); + + } catch (Exception e) { + log.error("Discord 알림 전송 중 예외 발생: {}", message, e); + } + } +} diff --git a/src/main/java/com/depromeet/stonebed/domain/report/application/ReportService.java b/src/main/java/com/depromeet/stonebed/domain/report/application/ReportService.java index ba2f24a0..64bc0906 100644 --- a/src/main/java/com/depromeet/stonebed/domain/report/application/ReportService.java +++ b/src/main/java/com/depromeet/stonebed/domain/report/application/ReportService.java @@ -1,5 +1,6 @@ package com.depromeet.stonebed.domain.report.application; +import com.depromeet.stonebed.domain.discord.application.DiscordNotificationService; import com.depromeet.stonebed.domain.member.domain.Member; import com.depromeet.stonebed.domain.missionRecord.dao.MissionRecordRepository; import com.depromeet.stonebed.domain.missionRecord.domain.MissionRecord; @@ -9,6 +10,7 @@ import com.depromeet.stonebed.global.error.ErrorCode; import com.depromeet.stonebed.global.error.exception.CustomException; import com.depromeet.stonebed.global.util.MemberUtil; +import java.time.format.DateTimeFormatter; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -17,22 +19,64 @@ @RequiredArgsConstructor @Transactional public class ReportService { + private static final DateTimeFormatter DATE_TIME_FORMATTER = + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); private final ReportRepository reportRepository; private final MissionRecordRepository missionRecordRepository; private final MemberUtil memberUtil; + private final DiscordNotificationService discordNotificationService; public void reportFeed(ReportRequest reportRequest) { - final Member member = memberUtil.getCurrentMember(); + final Member reporter = memberUtil.getCurrentMember(); MissionRecord missionRecord = missionRecordRepository .findById(reportRequest.recordId()) .orElseThrow(() -> new CustomException(ErrorCode.MISSION_RECORD_NOT_FOUND)); + Member reportedMember = missionRecord.getMember(); + Report report = Report.createReport( - missionRecord, member, reportRequest.reason(), reportRequest.details()); + missionRecord, reporter, reportRequest.reason(), reportRequest.details()); reportRepository.save(report); + + sendReportNotificationToDiscord(reporter, reportedMember, missionRecord, reportRequest); + } + + private void sendReportNotificationToDiscord( + Member reporter, + Member reportedMember, + MissionRecord missionRecord, + ReportRequest reportRequest) { + String reportTime = java.time.LocalDateTime.now().format(DATE_TIME_FORMATTER); + + String message = + String.format( + "🚨 **신고 접수 알림** 🚨\n\n" + + "**-- 신고자 정보 --**\n" + + "**닉네임**: %s\n" + + "**신고 시간**: %s\n\n" + + "**-- 신고 상세 내용 --**\n" + + "**신고 사유**: %s\n" + + "**신고 내용**: %s\n\n" + + "**-- 신고 대상 정보 --**\n" + + "**닉네임**: %s\n" + + "**게시글 ID**: %d\n" + + "**게시글 이미지 URL**: %s\n" + + "**게시글 내용**: %s", + reporter.getProfile().getNickname(), + reportTime, + reportRequest.reason(), + reportRequest.details(), + reportedMember.getProfile().getNickname(), + missionRecord.getId(), + missionRecord.getImageUrl() != null + ? missionRecord.getImageUrl() + : "이미지 없음", + missionRecord.getContent() != null ? missionRecord.getContent() : "내용 없음"); + + discordNotificationService.sendDiscordMessage(message); } } diff --git a/src/main/java/com/depromeet/stonebed/global/error/ErrorCode.java b/src/main/java/com/depromeet/stonebed/global/error/ErrorCode.java index 4538396c..c34e0efe 100644 --- a/src/main/java/com/depromeet/stonebed/global/error/ErrorCode.java +++ b/src/main/java/com/depromeet/stonebed/global/error/ErrorCode.java @@ -62,9 +62,11 @@ public enum ErrorCode { // report INVALID_REPORT_REASON(HttpStatus.NOT_FOUND, "해당 신고 사유를 찾을 수 없습니다."), + DISCORD_NOTIFICATION_FAILED(HttpStatus.BAD_REQUEST, "디스코드 알림 전송이 실패했습니다."), + // comment - COMMENT_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 댓글을 찾을 수 없습니다."), - ; + COMMENT_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 댓글을 찾을 수 없습니다."); + private final HttpStatus httpStatus; private final String message; } diff --git a/src/main/java/com/depromeet/stonebed/infra/properties/DiscordProperties.java b/src/main/java/com/depromeet/stonebed/infra/properties/DiscordProperties.java new file mode 100644 index 00000000..68da44d5 --- /dev/null +++ b/src/main/java/com/depromeet/stonebed/infra/properties/DiscordProperties.java @@ -0,0 +1,6 @@ +package com.depromeet.stonebed.infra.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "discord") +public record DiscordProperties(String url) {} diff --git a/src/main/java/com/depromeet/stonebed/infra/properties/PropertiesConfig.java b/src/main/java/com/depromeet/stonebed/infra/properties/PropertiesConfig.java index 0d8c3752..b0159b82 100644 --- a/src/main/java/com/depromeet/stonebed/infra/properties/PropertiesConfig.java +++ b/src/main/java/com/depromeet/stonebed/infra/properties/PropertiesConfig.java @@ -9,7 +9,8 @@ JwtProperties.class, AppleProperties.class, SwaggerProperties.class, - SqsProperties.class + SqsProperties.class, + DiscordProperties.class }) @Configuration public class PropertiesConfig {} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index d8fd2762..1ca01776 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -20,3 +20,6 @@ logging: com.depromeet.stonebed.*.*.application.*: debug org.hibernate.SQL: debug org.hibernate.type: trace + +discord: + url: ${DISCORD_WEBHOOK_URL}