KOTLIN

코프링(코틀린 + 스프링부트) + 구글 스프레드 시트로 슬랙봇 만들기 - ① 슬랙앱 생성 및 사용 설정하기

dodop 2022. 10. 22. 13:59

 

 

 

이번에는 코틀린을 공부하면서 코틀린과 함께 스프링부트를 이용한 슬랙봇을 만들어 보았다.

아이디어는 동기분이 점심봇을 얘기해주셨고,

이를 이용해서 공부하면 좋을 것 같아 슬랙봇이 메세지 통신을 어떻게하고 보여주는지 간단한 학습용 프로젝트를 진행했다!

 

참고로 데이터 베이스를 어떻게 할 지 생각해 보았는데,

예전에 유튜브에서 비슷한 아이디어로 슬랙봇을 만든 동영상이 생각이 났다!

영상을 보고 구글 스프레드 시트를 데이터베이스로 활용할 수 있다는 것을 알게 되었고,

리스트를 관리하기에 스프레드시트가 훨씬 편할 것 같아 나도 같은 방식을 적용하되 파이썬이 아닌 코틀린에 적용하도록 하였다!

 

참고한 영상

https://www.youtube.com/watch?v=NfJjaGjVceo

 

 

 

 

먼저 코틀린 + 스프링부트로 프로젝트를 생성한 부분은

Restaurant 객체 하나로 구성하여 간단하기도 하고,

기존에 스프링부트 프로젝트를 적용 한 부분이 비슷하여 이 부분은 생략하였다..!

적용하고 싶은 내용대로 구성하면 될 듯 하다.

(참고로 프로젝트에 적용한 인수테스트 부분은 나중에 추가로 블로그 글을 작성할 예정이다!)

기존 프로젝트 + 슬랙 앱 + 구글 스프레드 시트 연동 방법을 위주로 기록하였다.

 

 

 

슬랙 연동을 위한 dependency 추가하기

다음의 글을 참고하여 슬랙연동을 위한 dependency를 추가하였다.

https://medium.com/codex/creating-a-slack-bot-kotlin-and-deploying-it-in-heroku-32f884e39bea

 

Creating a Slack bot (Kotlin) and deploying it in Heroku

This is the minimum needed to create and deploy an app that replies to Slack commands.

medium.com

https://jsonobject.tistory.com/m/518

 

Spring Boot, Kotlin, Slack 채널 메시지 전송하기

개요 Slack은 아주 편리한 엔터프라이즈 협업 도구이다. 애플리케이션에서도 Slack을 이용하면 장애와 같은 중요한 상황에서 적절한 메시지를 특정 채널에 전송할 수 있다. 이번 글에서는 Slack 연

jsonobject.tistory.com

 

위의 글을 참고하여 적용한 내 프로젝트의 dependency는 다음과 같다.

아래의 내용중에서 slack항목을 추가해주면 된다.

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.gradle.api.tasks.testing.logging.TestExceptionFormat


plugins {
// 스프링 프레임워크 
	id("org.springframework.boot") version "2.7.4"
	id("io.spring.dependency-management") version "1.0.14.RELEASE"

// springRestDoc을 위한 플러그인 
	id("org.asciidoctor.convert") version "1.5.8"

// jpa을 위한 플러그인
	id("org.jetbrains.kotlin.plugin.noarg") version "1.5.30"
	kotlin("jvm") version "1.6.21"
	kotlin("plugin.spring") version "1.6.21"
	kotlin("plugin.jpa") version "1.4.32"

// slack을 위한 플러그인 
	kotlin("kapt") version "1.3.61"
	kotlin("plugin.serialization") version "1.6.20"
}

group = "slack"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11

configurations {
	compileOnly {
		extendsFrom(configurations.annotationProcessor.get())
	}
}

repositories {
	mavenCentral()
}


// slack을 위한 추가 항목 
val snippetsDir by extra { file("build/generated-snippets")}
sourceSets["main"].withConvention(org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet::class) {
	kotlin.srcDir("$buildDir/generated/source/kapt/main")
}

dependencies {
	implementation("org.springframework.boot:spring-boot-starter-web")
	implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
	implementation("org.jetbrains.kotlin:kotlin-reflect")
	implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

// 추후에 구글 스프레드 시트 사용을 위한 추가항목 
	implementation("com.google.api-client:google-api-client:1.30.4")
	implementation("com.google.apis:google-api-services-sheets:v4-rev581-1.25.0")

// 데이터 베이스 및 jpa 항목 
	implementation("org.springframework.boot:spring-boot-starter-data-jpa")
	implementation("org.springframework.boot:spring-boot-starter-jdbc")
	implementation("mysql:mysql-connector-java")
	implementation("com.h2database:h2")
	implementation("com.querydsl:querydsl-jpa:5.0.0")

// slack을 위한 추가 항목 
	implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2")
	implementation("com.slack.api:slack-api-client:1.20.2")
	implementation("com.slack.api:bolt:1.1.+")
	implementation("com.slack.api:bolt-servlet:1.1.+")
	implementation("com.slack.api:bolt-jetty:1.1.+")
	implementation ("com.slack.api:slack-api-client-kotlin-extension:1.10.0")
	implementation("com.google.code.gson:gson:2.9.1")

// query dsl 및 테스트를 위한  추가 항목 
	kapt("com.querydsl:querydsl-apt:5.0.0:jpa")
	kapt("org.springframework.boot:spring-boot-configuration-processor")
	compileOnly("org.projectlombok:lombok")
	annotationProcessor("org.projectlombok:lombok")
	testImplementation("org.springframework.boot:spring-boot-starter-test")
	testImplementation("org.springframework.restdocs:spring-restdocs-mockmvc")
	testImplementation("io.mockk:mockk:1.12.0")
	testImplementation("org.jetbrains.kotlin:kotlin-test-junit5:1.6.20")
	testImplementation("org.hamcrest:hamcrest:2.2")
	testImplementation("io.rest-assured:kotlin-extensions:5.0.1")
	testImplementation("com.squareup.okhttp3:mockwebserver:4.0.0")
	testImplementation("com.squareup.okhttp3:okhttp:4.0.0")
	testImplementation("com.github.tomakehurst:wiremock-jre8:2.34.0")
}


// jpa 설정 항목 
allOpen { // 추가적으로 열어줄 allOpen
	annotation("javax.persistence.Entity")
	annotation("javax.persistence.MappedSuperclass")
	annotation("javax.persistence.Embeddable")
}

tasks.withType<KotlinCompile> {
	kotlinOptions {
		freeCompilerArgs = listOf("-Xjsr305=strict")
		jvmTarget = "11"
	}
}

tasks.withType<Test> {
	useJUnitPlatform()
}

tasks.test {
	outputs.dir(snippetsDir)
	useJUnitPlatform()
	testLogging {
		events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
		exceptionFormat = TestExceptionFormat.SHORT
		showCauses = true
		showExceptions = true
		showStackTraces = true
	}
}

tasks.asciidoctor {
	inputs.dir(snippetsDir)
	dependsOn(tasks.test)
}

 

 

 

 

 

 

슬랙앱 생성하기

이 부분은 다음의 사이트를 참고하여 진행하였다.

http:// https://zzang9ha.tistory.com/m/400

 

 

 

우선 슬랙에 워크스페이스가 없다면 먼저 워크스페이스를 만들어주어야 한다.

이후 슬랙 사이트에 가서 앱을 생성(Create New App)해준다.

From scratch 선택 후 생성하고자 하는 슬랙봇 이름과 워크스페이스를 선택해준다.

 

 

 

 

 

토큰 생성하기

이제 앱을 사용하기 위한 토큰을 생성해준다.

좌측의 OAuth & Permission을 선택한 후 원하는 Scope를 선택해준다.

  • 간단 설명
    • app_mention_read : @<앱 이름>을 이용해 들어오는 요청을 읽을 수 있음
    • channels:[history:read:write] : 앱이 할당된 채널에 대한 메세지를 읽고 쓸 수 있음
    • commands : /<요청>을 통해 들어오는 메세지를 읽을 수 있음
    • groups:read : 채널을 확인 권한 부여로 private 채널에 슬랙봇 사용시 필요
    • im:[history:read:write] : 슬랙봇과의 DM으로 들어온 요청을 읽고 쓸 수 있음
    • incoming-webhook : 웹훅으로 들어온 요청을 처리할 수 있음
    • users-profile : 사용자의 정보를 확인할 수 있음

 

 

권한부여를 완료하였다면 install to Workspace를 통해 앱을 만들어준다.

참고로, 여기서 생성된 토큰은 노출되지 않도록 조심해야한다.

 

 

게시하고자 하는 채널을 선택 후 허용을 클릭한다.

 

 

 

 

채널에 앱 등록하기

다음과 같이 슬랙 워크스페이스의 앱을 게시하고자 하는 채널에 가서 세부정보에 앱을 추가해준다.

채널 세부 정보 보기 → 통합 → 앱 추가

 

 

 

 

앱이 등록된 채널 아이디 얻기

사이트에 들어가서 다음과 같이 앱이 등록된 채널 아이디를 얻는다.

  • 다음와 같이 발급받은 oauth 토큰을 입력하고 생성했던 채널 이름을 확인하여 id를 얻는다.

나의 경우에는 restaurant_bot_test 이름의 채널에 게시하였다.

 

 

 

 

 

 

슬랙봇 사용을 위한 설정값 추가하기

이제 만들어둔 프로젝트에서 슬랙을 사용하기 위해 설정값을 추가해준다.

secret은 다음과 같이 슬랙 정보에서 확인해준다.

Basic Information → App Credentials → Signing Secret

 

 

 

/resources/application.properties 에 다음과 같이 작성해준다.

내 프로젝트의 데이터는 영상과 같이 구글 스프레드 시트에 담아 영구적으로 저장하도록 만들고, 서버가 실행될 시 스프레드 시트와 동기화 시켜서 데이터를 이용할 것이기 때문에 DB설정을 인메모리 데이터인 h2를 사용하도록 설정하였다.

// DB 설정 
spring.datasource.hikari.driver-class-name=org.h2.Driver
spring.datasource.hikari.jdbc-url=jdbc:h2:mem:testdb;MODE=MySQL
spring.datasource.hikari.username=sa
spring.datasource.hikari.password=
spring.jpa.hibernate.ddl-auth=update

server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force=true

slack.bot.token=<발급받은 oAuth 토큰>
slack.monitor.channel.token=<앱이 등록된 채널의 ID>
slack.signing.secret=<앱의 signing secret>

 

 

 

 

이제 슬랙을 사용하기 위한 기본적인 설정은 완료가 되었다! ✨