본문 바로가기

[SpringBoot]

[SpringBoot] 슬랙 API 연동

반응형

0. 개요

스프링부트와 슬랙을 연동하는 방법은 내가 알기로 2가지 방법이 있다.

  1. Incoming Webhook
  2. API

1. Webhook Url 구현 방식

Incoming Webhook 방식은 앱 혹은 서비스로부터 슬랙에 알림을 보내는 가장 간단한 방법이다. (슬랙피셜)
Incoming Webhook을 사용하게 되면 고유 Url이 생성되는데 여기에 메시지를 보내는 방식이다

Webhook 방식은 주제가 아니기 때문에 간략하게만 설명하겠습니다.
Webhook 생성 참고링크

@Component
class SlackWebhookUtils(
    private val slackClient: SlackClient,
    @Value("\${feign.slack.url}") private val slackWebhookUrl,
) {
    val slack = 
    fun sendMessage(
        webhookUrl: String,
        message: String,
        quoteColor: String,
    ) {
        val slack = Slack.getInstance()

        try {
            slack.send(
                webhookUrl,
                payload { p ->
                    p.attachments(
                        listOf(
                            Attachment
                            .builder()
                            .color(quoteColor)
                            .fields(
                                listOf(
                                    Field.builder()
                                        .value(message)
                                        .valueShortEnough(false)
                                        .build()
                                )
                            ).build()
                        )
                    )
                }
            )
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }
}

파라미터 설명

  • webhookUrl: 생성한 웹훅 url
  • message: 전달할 메시지 문구
  • quoteColor: 슬랙에서 인용구를 보낼때 좌측에 나타내는 인용구 바 색깔

2. API를 이용한 구현 방식

Q. Webhook으로도 충분히 대응이 가능한데 왜 API를 사용하나요?

A. Webhook은...스레드를 달 수가 없어!!!

이게 뭔 소리냐? 슬랙은 신기하게도 메시지에 스레드를 달기위해선 아이디가 아닌 등록한 시간값을 알아야한다.

그래서 답글을 달고싶다면 API방식을 통해서 thread_ts 라는 값을 구해야한다.

2-1. 사전 작업

슬랙 API를 보내기 위해 우선 토큰 값을 설정하자

메뉴는 내 앱목록 > OAuth & Permissions > 토큰 생성

그 다음 화면을 내리다 보면 Scope이란 영역을 찾을 수 있는데, 쉽게 말해 권한 설정이라 생각하면 된다.

우리는 메시지를 보낼거니 chat:write 권한을 주자

이제 메시지를 보낼 슬랙채널에 봇을 추가해주면 사전작업은 끝이다.

 

2-2. 실제 구현

위에랑 다르게 이번엔 슬랙을 빈으로 등록하자

@Configuration  
class SlackConfig(
    @Value("\${feign.slack.token}") private val slackToken: String,
) {
    @Bean  
    fun slackClient(): MethodsClient {  
        return Slack.getInstance()  
            .methods(token)  
    }  
}

실제 코드

@Component  
class SlackUtils(  
    private val slackClient: MethodsClient,
    @Value("\${feign.slack.channel}")private val slackChannelId: String,
) {  
    fun sendMessage(): String {  
        try {  
            val response = slackClient.chatPostMessage {  
                it.channel(slackChannelId)  
                    .text("본문")  
            }  

            return response.ts  
        } catch (e: SlackApiException) {  
            throw R3Exception(ErrorCode.INTERNAL_SERVER_ERROR)  
        } catch (e: Exception) {  
            throw R3Exception(ErrorCode.NOT_FOUND)  
        }  
    }  

    fun addThread(timestamp: String) {  
        try {  
            val response = slackClient.chatPostMessage {  
                it.channel(slackChannelId)  
                    .text("스레드")  
                    .threadTs(timestamp)  
            }  

            println(response)  
        } catch (e: SlackApiException) {  
            throw R3Exception(ErrorCode.INTERNAL_SERVER_ERROR)  
        } catch (e: Exception) {  
            throw R3Exception(ErrorCode.NOT_FOUND)  
        }  
    }  
}

sendMessage() 함수는 Slack의 chatPostMessage()라는 기능을 통해 슬랙에 메시지를 보낸다.

addThread()sendMessage() 함수를 통해 받아온 ts

2-3. 결과

728x90

'[SpringBoot]' 카테고리의 다른 글

[SpringBoot] ServiceAccount로 IAM Credentials 대신하기 - 2  (0) 2023.01.20