ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Server 기동 여부 등 slack에 알리기.
    Computer Science/Slack 2022. 8. 5. 01:44

    slack api 사이트에 들어가서 your app에 들어간다.

    https://api.slack.com/apps

     

    create new app을 해주어 해당 app이 작동할 workspace를 선택해준다.

     

    OAuth & Permissions

    Scopes를 먼저 설정해주어야 한다.

     

    Bot Token - bot의 접근 권한.

    - chat:write를 추가해 chat을 할 수 있는 권한을 주고,

    - channels:read 를 추가해 무슨 채널이 있는지 읽을 권한 을 준다.

     

    //User Token - user의 데이터에 bot이 접근 할 수 있는 권한.

     

    그런뒤 install workspace를 진행해준다.

    token 값이 나온다. 해당 값은 github등에 보여지게 되면 재발급 받아야하니 주의하자.

     

    그런뒤 slack에서 알림을 줄 channel에 해당 봇을 추가해준다.

     

    Spring boot 설정

    //slack bot
    implementation 'com.slack.api:bolt:1.24.0'
    implementation 'com.slack.api:bolt-jetty:1.24.0'

    slack bot을 이용하기 위해 2개의 implement를 해준다.

     

    우선 EventListener를 통해 시작과 끝에 slack에 알려줄수 있도록 하였다.

    추가적으로 함수를 넣어서 원할 때에도 slack에 보내 줄수 있다.

     

    package com.lofserver.soma.service;
    
    import com.slack.api.Slack;
    import com.slack.api.methods.SlackApiException;
    import com.slack.api.model.Conversation;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.event.ContextClosedEvent;
    import org.springframework.context.event.ContextRefreshedEvent;
    import org.springframework.context.event.EventListener;
    import org.springframework.stereotype.Service;
    
    import java.io.IOException;
    import java.time.ZoneId;
    import java.time.ZonedDateTime;
    import java.time.format.DateTimeFormatter;
    
    @Slf4j
    @Service
    public class SlackNotifyService {
    
        private String notifyChannelName = "notification";
        private String notifyChannelId;
        @Value("${slack.token}")
        private String token;
        @Value("${spring.profiles.active}")
        private String springProfile;
    
        @EventListener(ContextRefreshedEvent.class)
        public void onContextRefreshedEvent(ContextRefreshedEvent event) {
            log.info("insert??");
            if (springProfile.equals("server")) {
                if (notifyChannelId == null)
                    initChannelId();
    
                sendMessage(ZonedDateTime.now(ZoneId.of("Asia/Seoul"))
                        .format(DateTimeFormatter.ofPattern("yyyy년 MM월 dd일 HH:mm:ss"))
                        + " - 서버를 기동합니다. \nSwagger: \nDatadog: https://www.datadoghq.com/");
            }
        }
    
        @EventListener(ContextClosedEvent.class)
        public void onContextClosedEvent(ContextClosedEvent event) {
            if (springProfile.equals("server")) {
                if (notifyChannelId == null)
                    initChannelId();
    
                sendMessage(ZonedDateTime.now(ZoneId.of("Asia/Seoul"))
                        .format(DateTimeFormatter.ofPattern("yyyy년 MM월 dd일 HH:mm:ss"))
                        + " - 서버가 종료되었습니다.\nDatadog: https://www.datadoghq.com/");
            }
        }
    
        public void sendMessage(String text) {
            if (notifyChannelId == null) {
                log.error("[SlackAPI] error: channelId is null");
                return;
            }
    
            var client = Slack.getInstance().methods();
            try {
                var result = client.chatPostMessage( requestConfig ->
                        requestConfig
                                .token(token)
                                .channel(notifyChannelId)
                                .text(text)
                );
                log.info("[SlackAPI] result {}", result);
            } catch (IOException | SlackApiException e) {
                log.error("[SlackAPI] error: {}", e.getMessage(), e);
            }
        }
    
        private void initChannelId() {
            log.info("[SlackAPI] channelName: {}", notifyChannelName);
            var client = Slack.getInstance().methods();
    
            try {
                var result = client.conversationsList( requestConfig ->
                        requestConfig.token(token)
                );
                for (Conversation channel : result.getChannels()) {
                    if (channel.getName().equals(notifyChannelName)) {
                        notifyChannelId = channel.getId();
                        log.info("[SlackAPI] Channel ID: {}", notifyChannelId);
                        break;
                    }
                }
            } catch (IOException | SlackApiException | NullPointerException e) {
                log.error("[SlackAPI] error: {}", e.getMessage(), e);
            }
        }
    }

    slack 을 local이 아닌 server 에서만 진행하도록 하였다.

    localkey:
      slack-api:
        token: "token값"

    우선 local에서는 aws secret이 안됨으로 local전용 yml을 생성하여서 key를 저장해주었다.

    ---
    spring:
      config:
        activate:
          on-profile: localdb
        import: localkey.yaml
      datasource:
        url: jdbc:mariadb://localhost:3306/lof
        username: root
        password: 1234
    
    slack:
      token: ${localkey.slack-api.token}
    ---
    spring:
      config:
        activate:
          on-profile: serverdb
      datasource:
        url: ${lof.mariadb.url}/lof
        username: root
        password: ${lof.mariadb.password}
    slack:
      token: ${lof.slack.token}

    application 부분이다. yml 파일을 import해주고 

    slack.token에 해당 값을 추가해주었다.

     

    해당 localkey.yaml은 gitignore을 통해 github에는 올라가지 않도록하였다.

Designed by Tistory.