728x90

회사에서 어떻게 하면 좀 더 편하게 어떤 기능을 사용하게 할 수 있을까?

라는 생각이 계속해서 들었는데, 좋은 기회가 생겼다.

회사에서 영업을 하시는분들이 컨퍼런스, 세미나 등등을 많이 참석하여 홍보하고 고객을 유치하는 과정에서 기회가 생겼다.

그것은 회사의 카드를 발급을 받았는지에 대한 여부 확인을 따로 할 수 없었다는 것인데, 당연히 그럴 것이 회원가입할 때 법인 유무를 체크하지는 않으니 말이다.

그래서 종이로든 아니면 엑셀시트던 특정 자료를 세미나 전에 준비해서 가는 부분이 매우 불편해보였다. (갈 때마다 추가 법인이 있으니까 매번 정리해야 된다.)

자! 그래서 슬랙에서 /법인찾기 법인명 하면 우리에게 가입된 법인인지를 찾는 기능을 구현하고 싶었다.

그래서 데모로 슬래시 커맨드를 만드는 법을 데모로 만드는 과정을 포스팅한다.

항상 다는 얘기지만 모든 코드는 깃허브 에 있다.

슬랙 설정

Slack Slash Commands

https://api.slack.com/apps 페이지에서 앱을 설정하여 들어온 후 다음과 같이 설정할 수 있다.

  1. 봇을 먼저 만들어야 한다.
    나는 봇을 만드는 과정을 진행하는 포스트는 아니기에 다른 포스트에서 알아보도록 합시다.
  2. Basic Information Signing Secret
    Settings > Basic Information > App Credentials 탭의 Signing Secret 정보를 따로 저장한다.
  3. Features > OAuth & Permissions > OAuth Tokens for Your Workspace 탭의 Bot User OAuth Token 정보를 따로 저장한다.

이렇게 저장하면 모든 설정은 준비됐다.

애플리케이션을 만들자

모든 코드는 회사에선 자바를 사용하지만, 집에서는 공부 목적 + 나중 을 위해 코틀린을 사용한다.

Slack은 SDK를 사용할 수 있도록 자체 라이브러리를 제공해주는데,

나는 bolt를 사용하여 구현할 계획이다. 자세한 정보는 https://slack.dev/java-slack-sdk/guides/slash-commands 에 있다.

build.gradle

의존성에는 위에서 말한것과 같이 bolt에 대한 설정을 추가해준다.

dependencies {
    implementation("com.slack.api:bolt:1.29.2")
    implementation("com.slack.api:bolt-servlet:1.29.2")
}

SlackConfiguration

슬래시 커맨드에 대한 수신 정보들을 해당 클래스에서 미리 설정한다.

@Configuration
class SlackConfiguration {
    @Bean
    fun testApp(): App {
        // 슬랙 앱 설정
        val app = App(
            AppConfig.builder()
                     .signingSecret("") //위에서 설명했던 Signing Secret 정보 넣기
                        .singleTeamBotToken("") // 위에서 설명했던 OAuth Token 정보 넣기
                     .build()
        )

        app.command("/echo", (req, ctx) -> {
              String commandArgText = req.getPayload().getText(); // text에 대한 값을 가져온다.
            String channelId = req.getPayload().getChannelId(); // 채널 id 수신
            String channelName = req.getPayload().getChannelName(); //채널명 수신
            String text = "테스트 발송";
            return ctx.ack(text); //슬랙으로 원하는 정보를 전송
        });
    }
}

Bean으로 각 호출할 커맨드들을 앱을 통해 등록해준다.
여기서 좀 더 고도화 하자면 AppConfig는 따로 분리하여 전역적으로 사용해도 무방하다.

SlackSender

이제 bolt에서 추가해준 라이브러리를 통해 SlackServlet을 생성할 것이다.

@WebServlet("/slack/events/test")
class SlashCommand(@Qualifier("testApp") app: App?) : SlackAppServlet(app)

구현은 끝났다.

이렇게 되고 나서는 슬랙에서 추가적으로 설정해주어야 하는 부분이 존재한다.

아래와 같이 커맨드 옵션을 추가해주어야 한다.

localhost를 사용한다면 내가 구현한 것처럼 ngrok등의 터널링 도구를 사용해서 서버를 라우팅해주어야 한다.

도메인이 있다면 도메인명을 바로 적어주면 실행된다.

requestURL에는 ngrok 주소 + /slack/events 를 붙여주고 맨 마지막은 command 경로를 넣어준다.

자 이제 실행해보자!

그러면 이제 서버를 켠 후 슬랙에서 /command 를 실행해서 해보자.

기본값이라면 나처럼 나오게 될 것이다.

왜 안되는 것인가...?

@ServletComponentScan

우리는 슬랙 웹 서블릿이라는 클래스를 추가해주었다.

그 클래스는 내부에서 HttpServlet 을 상속받아 구현하고 있기에 servlet을 수신할 수 있는 설정을 구현해주어야 한다.

이 문단의 제목인 @ServletComponentScan 을 통해 서블릿 객체들을 스캔해줄 수 있도록 설정을 해주어야 한다.

@ServletComponentScan(basePackages = ["com.github.lsj8367.slack.command"])

이런식으로 Application 클래스 위에 설정을 해주거나, 또는 별도의 설정 클래스를 통해 지정해주면 된다.

설정해주고 다시 실행해주게 되면?

위의 코드랑 조금은 상이하게 테스트라는 단어 3번을 출력하도록 해주었다.

잘 나오게 된다.

그리고 기본적으로는 슬랙의 문법을 다 알아듣기 때문에 https://api.slack.com/reference/surfaces/formatting 여기서 사용할만한 문법을 적용해서 추가해주면 되겠다.

이 부분을 이제 회사에 적용하면? 불편했던 점을 자동화한 개발자 타이틀에 1%는 달성하지 않았나? 싶다~ 👏👏👏

728x90

'Spring' 카테고리의 다른 글

분산 락  (0) 2023.04.15
@ModelAttribute, @RequestBody 커맨드 객체  (3) 2022.09.15
@Valid, @Validated 차이  (0) 2022.08.10
AOP  (0) 2022.08.10

+ Recent posts