Skip to content

Commit

Permalink
πŸ”€ :: (#230) ν”Όλ“œ μ‹ κ³  Slack 연동
Browse files Browse the repository at this point in the history
πŸ”€ :: (#230) ν”Όλ“œ μ‹ κ³  Slack 연동
  • Loading branch information
jeongho1209 authored Sep 11, 2023
1 parent f2e7b39 commit 8391754
Show file tree
Hide file tree
Showing 16 changed files with 182 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ public void saveComment(CreateCommentDomainRequest request) {
.build()
);

if(!feed.getUserId().equals(userId)) {
if (!feed.getUserId().equals(userId)) {
sendNotification(feed);
}
}

private void sendNotification(Feed feed) {
if(CategoryEnum.NOTICE.getName().equals(categorySpi.queryCategoryById(feed.getCategoryId()).getName())) {
if (CategoryEnum.NOTICE.getName().equals(categorySpi.queryCategoryById(feed.getCategoryId()).getName())) {
commentNotificationUtil.sendNotification(feed, FEED_NOTICE_COMMENT);
} else {
commentNotificationUtil.sendNotification(feed, FEED_BAMBOO_COMMENT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,51 @@

import com.xquare.v1servicefeed.annotation.DomainService;
import com.xquare.v1servicefeed.configuration.spi.SecuritySpi;
import com.xquare.v1servicefeed.feed.Feed;
import com.xquare.v1servicefeed.feed.spi.QueryFeedSpi;
import com.xquare.v1servicefeed.report.Report;
import com.xquare.v1servicefeed.report.api.ReportApi;
import com.xquare.v1servicefeed.report.api.dto.CreateReportDomainRequest;
import com.xquare.v1servicefeed.report.exception.CannotReportMyFeedException;
import com.xquare.v1servicefeed.report.spi.CommandReportSpi;
import com.xquare.v1servicefeed.feed.Feed;
import com.xquare.v1servicefeed.feed.spi.QueryFeedSpi;
import com.xquare.v1servicefeed.user.User;
import com.xquare.v1servicefeed.user.exception.UserNotFoundException;
import com.xquare.v1servicefeed.user.spi.FeedUserSpi;
import com.xquare.v1servicefeed.webhook.SlackReport;
import com.xquare.v1servicefeed.webhook.spi.SendWebhookSpi;
import lombok.RequiredArgsConstructor;

import java.util.UUID;

@RequiredArgsConstructor
@DomainService
public class ReportApiImpl implements ReportApi {

private final QueryFeedSpi queryFeedSpi;
private final CommandReportSpi commandReportSpi;
private final SecuritySpi securitySpi;
private final SendWebhookSpi sendWebhookSpi;
private final FeedUserSpi feedUserSpi;

@Override
public void saveReport(CreateReportDomainRequest request) {
Feed feed = queryFeedSpi.queryFeedById(request.getFeedId());
UUID userId = securitySpi.getCurrentUserId();
User user = feedUserSpi.queryUserById(securitySpi.getCurrentUserId())
.orElseThrow(() -> UserNotFoundException.EXCEPTION);

if(userId.equals(feed.getUserId())) {
if (user.getId().equals(feed.getUserId())) {
throw CannotReportMyFeedException.EXCEPTION;
}

commandReportSpi.saveReport(
Report.builder()
.userId(userId)
.userId(user.getId())
.reportUserId(feed.getUserId())
.feedId(feed.getId())
.content(request.getContent())
.build()
);

sendWebhookSpi.sendReportToSlack(
new SlackReport(feed.getContent(), user.getName(), request.getContent())
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ public enum UserErrorCode implements ExceptionProperty {

FORBIDDEN_USER(403, "Forbidden User"),

INVALID_ROLE(403, "Invalid Role");
INVALID_ROLE(403, "Invalid Role"),

USER_NOT_FOUND(404, "User Not Found");

private final int status;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.xquare.v1servicefeed.user.exception;

import com.xquare.v1servicefeed.error.FeedException;
import com.xquare.v1servicefeed.user.error.UserErrorCode;

public class UserNotFoundException extends FeedException {

public static final FeedException EXCEPTION =
new UserNotFoundException();

private UserNotFoundException() {
super(UserErrorCode.USER_NOT_FOUND);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
import com.xquare.v1servicefeed.user.role.UserRole;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

@Spi
public interface FeedUserSpi {
List<User> queryUserByIds(List<UUID> ids);
void validateUserId(UUID userId, UUID currentUserId);
List<User> queryAllUserByRole(String role);
Optional<User> queryUserById(UUID id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.xquare.v1servicefeed.webhook;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class SlackReport {

private final String feedContent;

private final String userName;

private final String reportContent;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.xquare.v1servicefeed.webhook.spi;

import com.xquare.v1servicefeed.annotation.Spi;
import com.xquare.v1servicefeed.webhook.SlackReport;

@Spi
public interface SendWebhookSpi {

void sendReportToSlack(SlackReport slackReport);
}
3 changes: 3 additions & 0 deletions feed-infrastructure/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ dependencies {
// message
implementation 'org.springframework.cloud:spring-cloud-aws-messaging:2.2.6.RELEASE'

// Webhook
implementation 'net.gpedro.integrations.slack:slack-webhook:1.4.0'

implementation(project(":feed-domain"))

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.xquare.v1servicefeed.configuration.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync
@Configuration
public class AsyncConfig {
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import com.xquare.v1servicefeed.feed.api.FeedApi;
import com.xquare.v1servicefeed.feed.api.dto.request.DomainCreateFeedRequest;
import com.xquare.v1servicefeed.feed.api.dto.request.DomainUpdateFeedRequest;
import com.xquare.v1servicefeed.feed.api.dto.response.*;
import com.xquare.v1servicefeed.feed.api.dto.response.FeedCategoryListResponse;
import com.xquare.v1servicefeed.feed.api.dto.response.FeedListPageResponse;
import com.xquare.v1servicefeed.feed.api.dto.response.FeedListResponse;
import com.xquare.v1servicefeed.feed.api.dto.response.FeedWeakElement;
import com.xquare.v1servicefeed.feed.api.dto.response.SaveFeedResponse;
import com.xquare.v1servicefeed.feed.web.dto.request.WebCreateFeedRequest;
import com.xquare.v1servicefeed.feed.web.dto.request.WebUpdateFeedRequest;
import com.xquare.v1servicefeed.report.api.ReportApi;
Expand All @@ -12,7 +16,15 @@
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.time.LocalDateTime;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.xquare.v1servicefeed.feign.client;

import com.xquare.v1servicefeed.feign.client.dto.response.UserInfoElement;
import com.xquare.v1servicefeed.feign.client.dto.response.UserInfoResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;
Expand All @@ -16,4 +18,7 @@ public interface UserClient {

@GetMapping("/users/role")
UserInfoResponse getStudent(@RequestParam(value = "roleName", required = false) String role);

@GetMapping("/users/id/{userId}")
UserInfoElement getUserInfoByUserId(@PathVariable("userId") UUID userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;


@RequiredArgsConstructor
@Component
public class ReportMapperImpl implements ReportMapper {
public Report entityToDomain(ReportEntity reportEntity) {

public Report entityToDomain(ReportEntity reportEntity) {
return Report.builder()
.id(reportEntity.getId())
.userId(reportEntity.getUserId())
Expand All @@ -21,7 +20,6 @@ public Report entityToDomain(ReportEntity reportEntity) {
}

public ReportEntity domainToEntity(Report report) {

return ReportEntity.builder()
.id(report.getId())
.userId(report.getUserId())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

@RequiredArgsConstructor
Expand Down Expand Up @@ -69,4 +70,23 @@ public List<User> queryAllUserByRole(String role) {
.build())
.toList();
}

@Override
public Optional<User> queryUserById(UUID id) {
UserInfoElement userInfoElement = userClient.getUserInfoByUserId(id);

return Optional.of(
User.builder()
.id(userInfoElement.getId())
.accountId(userInfoElement.getAccountId())
.name(userInfoElement.getName())
.password(userInfoElement.getPassword())
.birthDay(userInfoElement.getBirthDay())
.grade(userInfoElement.getGrade())
.classNum(userInfoElement.getClassNum())
.num(userInfoElement.getNum())
.profileFileName(userInfoElement.getProfileFileName())
.build()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.xquare.v1servicefeed.webhook;

import net.gpedro.integrations.slack.SlackApi;
import net.gpedro.integrations.slack.SlackAttachment;
import net.gpedro.integrations.slack.SlackMessage;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Component
public class SendWebhookEventListener {

private static final String REPORT_MESSAGE = "ν”Όλ“œ μ‹ κ³  λ°œμƒ";
private static final String REPORT_USER_NAME = "μ‹ κ³ μž";
private static final String REPORT_CONTENT = "μ‹ κ³  λ‚΄μš©";
private static final String REPORT_FEED_CONTENT = "μ‹ κ³ λœ κ²Œμ‹œκΈ€ λ‚΄μš©";
private static final String MESSAGE_COLOR = "#9650FA";
private static final String FALLBACK = "μƒˆλ‘œμš΄ ν”Όλ“œ μ‹ κ³ κ°€ λ„μ°©ν–ˆμŠ΅λ‹ˆλ‹€.";

@Value("${webhook.url}")
private String webhookUrl;

@Async
@EventListener
public void sendReportToSlack(SlackReport slackReport) {
SlackAttachment slackAttachment = createSlackAttachment(slackReport);
SlackMessage slackMessage = new SlackMessage("").addAttachments(slackAttachment);
new SlackApi(webhookUrl).call(slackMessage);
}

private SlackAttachment createSlackAttachment(SlackReport slackReport) {
SlackAttachment slackAttachment = new SlackAttachment();
slackAttachment.setTitle(REPORT_MESSAGE);
slackAttachment.setText(getErrorReason(slackReport));
slackAttachment.setColor(MESSAGE_COLOR);
slackAttachment.setFallback(FALLBACK);
return slackAttachment;
}

private String getErrorReason(SlackReport slackReport) {
return REPORT_USER_NAME + " : " + slackReport.getUserName()
+ "\n" + REPORT_FEED_CONTENT + " : " + slackReport.getFeedContent()
+ "\n" + REPORT_CONTENT + " : " + slackReport.getReportContent();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.xquare.v1servicefeed.webhook;

import com.xquare.v1servicefeed.webhook.spi.SendWebhookSpi;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

@RequiredArgsConstructor
@Component
public class SendWebhookEventPublisher implements SendWebhookSpi {

private final ApplicationEventPublisher applicationEventPublisher;

@Override
public void sendReportToSlack(SlackReport slackReport) {
applicationEventPublisher.publishEvent(slackReport);
}
}
3 changes: 3 additions & 0 deletions feed-infrastructure/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,6 @@ springdoc:
display-request-duration: true
cache:
disabled: true

webhook:
url: ${webhook.url}

0 comments on commit 8391754

Please sign in to comment.