[SpringBoot] Slack Bot 만들기

애이용·2021년 6월 23일
1

springboot

목록 보기
15/20
post-thumbnail
post-custom-banner

✍️ Slack APP 생성 과정

해당 링크에 들어가 슬랙 APP 생성

이때 앱의 기능 Bots 추가하기
[Review Scopes to Add] 버튼 클릭 -> Oauth Scopes 추가

[ method 설명 링크 ]

그러면 [Install to Workspace] 버튼이 활성화가 된다. 버튼을 누르면 Access Token을 발급받는다. (요청 보낼 때 함께 보내는 토큰)

✍️ 스프링부트에 Slack API Method 적용하기

  • application.yml 에 토큰 저장
slack:
  token: [발급받은 토큰]

알림 과정과 적용할 API 정리

  • Slack User Id를 User 테이블 컬럼에 추가
  • @Scheduled 이용해 Slack User Id(channel이자 DM)로 알림 메세지 보내기 [chat.postMessage]
  • @Scheduled 이용해 User 테이블의 Slack User Id 데이터가 없는 회원을
    [users.lookupByEmail] 메서드를 이용해 Slack User Id 저장

✔️ @Scheduled를 이용해 알림 메세지 보내기

chat.postMessage 메서드를 호출하여 개인 DM을 보낸다.

  • Scheduler / notification

    오전 9시마다, 저장된 알림 날짜가 오늘이라면 알림 메세지를 보낸다.

    @Scheduled(cron = "0 0 9 * * *") // 매일 오전 9시마다
    public void notification() {
        List<Problem> problemList = problemRepository.findAllByNotificationDate(LocalDate.now());
        for (Problem problem : problemList) {
            slackBotService.notification(problem);
        }
    }
  • SlackBotService / notification

    channel 필드에 channer id 가 아닌 user id를 작성하면 DM으로 알림 메세지를 보내게 된다.
    (DM 찾기까지 매우 헤맸.. 영어 공부해야지.)
    개개인마다 알림 메세지를 보내야 한다면 user id를 입력하는 게 좋을 듯하다!

    public void notification(Problem problem) {
        String url = "https://slack.com/api/chat.postMessage";
        
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer " + slackToken);
        headers.add("Content-type", "application/json; charset=utf-8");
        
        String body = "{\"channel\": \"" + problem.getWriter().getSlackId() + "\", \"text\" : \"" + problem.getTitle() + " 문제를 풀 시간입니다!\"}";

        HttpEntity<String> requestEntity = new HttpEntity<>(body, headers);
        
        // 알림 메세지 보내기
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
        
        HttpStatus httpStatus = responseEntity.getStatusCode();
        int status = httpStatus.value();
        String response = responseEntity.getBody();
        log.info("Response status: " + status);
        log.info(response);
    }

✔️ @Scheduled를 이용해 이메일로 Slack User Id 얻기

  • Scheduler / registerSlackId

    자정마다, Slack User Id가 저장되어있지 않은 회원의 이메일로 Slack User Id를 얻는다.

    @Scheduled(cron = "0 0 0 * * *") // 매일 자정마다
    public void registerSlackId() throws JsonProcessingException {
        List<Member> memberList = memberRepository.findAllBySlackIdNull();
        for (Member member : memberList) {
            String slackId = slackBotService.getSlackIdByEmail(member.getEmail());
            if (slackId != null) {
                member.setSlackId(slackId);
                memberRepository.save(member);
            }
        }
    }
  • SlackBotService / getSlackIdByEmail
    public String getSlackIdByEmail(String email) throws JsonProcessingException {
        String url = "https://slack.com/api/users.lookupByEmail";
        url += "?email=" + email;
        
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer " + slackToken);
        headers.add("Content-type", "application/x-www-form-urlencoded");

        HttpEntity<String> requestEntity = new HttpEntity<>(headers);
        ResponseEntity<String> restResponse = restTemplate.exchange(
                url,
                HttpMethod.GET,
                requestEntity,
                String.class
        );
        
        HttpStatus httpStatus = restResponse.getStatusCode();
        int status = httpStatus.value();
        String response = restResponse.getBody();
        log.info("Response status: " + status);
        log.info(response);
        JsonNode body = objectMapper.readTree(restResponse.getBody());
        if (body.get("ok").asBoolean())
            return body.get("user").get("id").textValue();
        else
            return null;
    }

참고

profile
로그를 남기자 〰️
post-custom-banner

1개의 댓글

comment-user-thumbnail
2021년 9월 7일

누군가 했더니 아영님이셨군요. 잘 보고 가요~~

답글 달기