Skip to content

Commit

Permalink
feat: 슬랙 봇 연결
Browse files Browse the repository at this point in the history
  • Loading branch information
nahowo committed Nov 12, 2024
1 parent 182243e commit d004056
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 105 deletions.
9 changes: 5 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,13 @@ dependencies {
implementation 'io.micrometer:micrometer-registry-prometheus'

// Slack API
implementation("com.slack.api:bolt:1.18.0")
implementation("com.slack.api:bolt-servlet:1.18.0")
implementation("com.slack.api:bolt-jetty:1.18.0")
implementation 'com.slack.api:bolt:1.18.0'
implementation 'com.slack.api:bolt-servlet:1.18.0'
implementation 'com.slack.api:bolt-jetty:1.18.0'
implementation 'com.slack.api:slack-api-client:1.44.1'

// Discord API
implementation("net.dv8tion:JDA:5.0.0-beta.5")
implementation 'net.dv8tion:JDA:5.0.0-beta.5'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ public enum ResultCode {
SNS_CREATE_SUCCESS("N002", "소셜 생성 성공"),

// DISCORD
DISCORD_DM_SEND_SUCCESS("D001", "디스코드 DM 전송 성공");
DISCORD_DM_SEND_SUCCESS("D001", "디스코드 DM 전송 성공"),

// SLACK
SLACK_DM_SEND_SUCCESS("L001", "슬랙 DM 전송 성공");
private final String code;
private final String message;
}
20 changes: 14 additions & 6 deletions src/main/java/com/Alchive/backend/domain/sns/Sns.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,17 @@ public class Sns extends BaseEntity {
@Column(name = "category", length = 20, nullable = false)
private SnsCategory category;

@Column(name = "token", columnDefinition = "TEXT", nullable = false)
private String token;
@Column(name = "bot_token", columnDefinition = "TEXT")
private String bot_token;

@Column(name = "channel", columnDefinition = "TEXT")
private String channel;
@Column(name = "user_token", columnDefinition = "TEXT")
private String user_token;

@Column(name = "channel_id", columnDefinition = "TEXT")
private String channel_id;

@Column(name = "sns_id", columnDefinition = "TEXT")
private String sns_id;

@Column(name = "time", length = 30)
private String time;
Expand All @@ -43,8 +49,10 @@ public static Sns of(User user, SnsCreateRequest snsCreateRequest) {
return Sns.builder()
.user(user)
.category(snsCreateRequest.getCategory())
.token(snsCreateRequest.getToken())
.channel(snsCreateRequest.getChannel())
.bot_token(snsCreateRequest.getBot_token())
.user_token(snsCreateRequest.getUser_token())
.channel_id(snsCreateRequest.getChannel_id())
.sns_id(snsCreateRequest.getSns_id())
.time(snsCreateRequest.getTime())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
public class SnsCreateRequest {
@NotNull(message = "소셜 카테고리는 필수입니다. ")
private SnsCategory category;
@NotNull(message = "토큰은 필수입니다. ")
private String token;
private String channel;
private String bot_token;
private String user_token;
private String channel_id;
private String sns_id;
private String time;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,21 @@ public class SnsResponseDTO {
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
private SnsCategory category;
private String token;
private String channel;
private String bot_token;
private String user_token;
private String channel_id;
private String sns_id;
private String time;

public SnsResponseDTO(Sns sns) {
this.id = sns.getId();
this.createdAt = sns.getCreatedAt();
this.updatedAt = sns.getUpdatedAt();
this.category = sns.getCategory();
this.token = sns.getToken();
this.channel = sns.getChannel();
this.bot_token = sns.getBot_token();
this.user_token = sns.getUser_token();
this.channel_id = sns.getChannel_id();
this.sns_id = sns.getSns_id();
this.time = sns.getTime();
}
}
25 changes: 3 additions & 22 deletions src/main/java/com/Alchive/backend/sns/DiscordController.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.Alchive.backend.sns;

import com.Alchive.backend.config.error.exception.sns.InvalidGrantException;
import com.Alchive.backend.config.result.ResultResponse;
import com.Alchive.backend.domain.sns.SnsCategory;
import com.Alchive.backend.dto.request.SnsCreateRequest;
Expand All @@ -11,12 +10,8 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import static com.Alchive.backend.config.result.ResultCode.DISCORD_DM_SEND_SUCCESS;

Expand All @@ -26,26 +21,12 @@
@Slf4j
@RequestMapping("/api/v1/discord")
public class DiscordController {
@Value("${DISCORD_CLIENT_ID}")
private String clientId;

@Value("${DISCORD_CLIENT_SECRET}")
private String clientSecret;

@Value("${DISCORD_REDIRECT_URI}")
private String redirectUri;

@Value("${DISCORD_BOT_TOKEN}")
private String discordBotToken;

private final SnsService snsService;
private final DiscordService discordService;

@Operation(summary = "디스코드 봇 연결", description = "디스코드 액세스 토큰을 요청하고 DM 채널을 연결하는 api입니다. ")
@GetMapping("/dm/open")
public ResponseEntity<ResultResponse> installDiscordBot(HttpServletRequest tokenRequest, @RequestParam String code) {
RestTemplate restTemplate = new RestTemplate();

public ResponseEntity<ResultResponse> openDiscordDm(HttpServletRequest tokenRequest, @RequestParam String code) {
// Access Token 요청
String accessToken = discordService.getAccessToken(code);
log.info("Access Token 반환 완료: " + accessToken);
Expand All @@ -61,8 +42,8 @@ public ResponseEntity<ResultResponse> installDiscordBot(HttpServletRequest token
// Discord SNS 정보 저장
SnsCreateRequest snsCreateRequest = SnsCreateRequest.builder()
.category(SnsCategory.DISCORD)
.token(discordUserId) // Discord User Id
.channel(channelId) // Discord Channel Id
.sns_id(discordUserId) // Discord User Id
.channel_id(channelId) // Discord Channel Id
.time("0 0 18 ? * MON")
.build();
snsService.createSns(tokenRequest, snsCreateRequest);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/Alchive/backend/sns/DiscordService.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public String getDiscordUserId(HttpServletRequest tokenRequest) {
Long userId = tokenService.validateAccessToken(tokenRequest);
Sns snsInfo = snsReporitory.findByUser_IdAndCategory(userId, SnsCategory.DISCORD)
.orElseThrow(NoSuchSnsIdException::new);
String discordUserId = snsInfo.getToken();
String discordUserId = snsInfo.getSns_id();
return discordUserId;
}

Expand Down
68 changes: 54 additions & 14 deletions src/main/java/com/Alchive/backend/sns/SlackController.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,74 @@
package com.Alchive.backend.sns;

import com.Alchive.backend.config.error.exception.sns.NoSuchSnsIdException;
import com.Alchive.backend.config.jwt.TokenService;
import com.Alchive.backend.config.result.ResultResponse;
import com.Alchive.backend.domain.sns.Sns;
import com.Alchive.backend.domain.sns.SnsCategory;
import com.Alchive.backend.dto.request.SnsCreateRequest;
import com.Alchive.backend.repository.SnsReporitory;
import com.Alchive.backend.service.SnsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import static com.Alchive.backend.config.result.ResultCode.SLACK_DM_SEND_SUCCESS;

@Slf4j
@Tag(name = "슬랙", description = "슬랙 관련 API입니다. ")
@RestController
@RequestMapping("/api/v1/slack")
@RequiredArgsConstructor
public class SlackController {
@Autowired
private final SlackService slackService;
private final SnsService snsService;
private final SnsReporitory snsReporitory;
private final TokenService tokenService;

@Operation(summary = "슬랙 봇 연결", description = "슬랙 액세스 토큰을 요청하고 DM 채널을 연결하는 api입니다. ")
@GetMapping("/dm/open")
public ResponseEntity<ResultResponse> openSlackDm(HttpServletRequest tokenRequest, @RequestParam String code) {
// Bot Access Token, User Access Token, Slack User Id 요청
SnsCreateRequest snsCreateRequest = slackService.getSlackInfo(code);
log.info("사용자 slack 정보를 불러왔습니다. ");

// Slack SNS 정보 저장
snsService.createSns(tokenRequest, snsCreateRequest);
log.info("사용자 slack 정보를 저장했습니다. ");

@Operation(summary = "슬랙 봇 설정", description = "슬랙 봇 추가 시 메시지를 전송하는 메서드입니다. ")
@GetMapping("/added")
public void addedSlackBot() {
slackService.sendMessage(":wave: Hi from a bot written in Alchive!");
log.info("Slack Test");
// DM 전송 요청
String slackUserId = snsCreateRequest.getSns_id();
String botAccessToken = snsCreateRequest.getBot_token();

slackService.sendDm(slackUserId, botAccessToken, "안녕하세요! 이제부터 풀지 못한 문제들을 정해진 시간에 알려드릴게요. ");
log.info("봇을 사용자 slack 채널에 추가했습니다. ");
return ResponseEntity.ok(ResultResponse.of(SLACK_DM_SEND_SUCCESS));
}

@Operation(summary = "문제 리마인더", description = "30분마다 해결하지 못한 문제를 리마인드해주는 메서드입니다. ")
@GetMapping("/reminder")
public void sendReminder(HttpServletRequest tokenRequest) {
slackService.sendMessageReminderBoard(tokenRequest);
@Operation(summary = "슬랙 DM 전송", description = "슬랙 DM으로 메시지를 전송하는 api입니다. ")
@PostMapping("dm/send")
public ResponseEntity<ResultResponse> sendSlackDm(HttpServletRequest tokenRequest, @RequestParam String message) {
Long userId = tokenService.validateAccessToken(tokenRequest);
Sns sns = snsReporitory.findByUser_IdAndCategory(userId, SnsCategory.SLACK)
.orElseThrow(NoSuchSnsIdException::new);
slackService.sendDm(sns.getSns_id(), sns.getBot_token(), message);
return ResponseEntity.ok(ResultResponse.of(SLACK_DM_SEND_SUCCESS));
}

// @Operation(summary = "슬랙 봇 설정", description = "슬랙 봇 추가 시 메시지를 전송하는 메서드입니다. ")
// @GetMapping("/added")
// public void addedSlackBot() {
// slackService.sendMessage(":wave: Hi from a bot written in Alchive!");
// log.info("Slack Test");
// }
//
// @Operation(summary = "문제 리마인더", description = "30분마다 해결하지 못한 문제를 리마인드해주는 메서드입니다. ")
// @GetMapping("/reminder")
// public void sendReminder(HttpServletRequest tokenRequest) {
// slackService.sendMessageReminderBoard(tokenRequest);
// }
}
Loading

0 comments on commit d004056

Please sign in to comment.