[Spring Boot] Discord Bot(๋์ค์ฝ๋ ๋ด) ๋ง๋ค๊ธฐ
"์ด ํฌ์คํ ์ ์ฟ ํก ํํธ๋์ค ํ๋์ ์ผํ์ผ๋ก, ์ด์ ๋ฐ๋ฅธ ์ผ์ ์ก์ ์์๋ฃ๋ฅผ ์ ๊ณต๋ฐ์ต๋๋ค."
๐ ๋ชฉ์ฐจ
1. [Spring Boot] Discord Bot(๋์ค์ฝ๋ ๋ด) ๋ง๋ค๊ธฐ
2. [Spring Boot] Discord Bot(๋์ค์ฝ๋ ๋ด) ๋ง๋ค๊ธฐ - Spring Boot(์คํ๋ง ๋ถํธ)๋ฅผ ์ด์ฉํ ๊ฐ๋จํ API ๋ง๋ค๊ธฐ feat.Mybatis(๋ง์ด๋ฐํฐ์ค)
3. [Spring Boot] Discord Bot(๋์ค์ฝ๋ ๋ด) ๋ง๋ค๊ธฐ - JAVA๋ฅผ ์ด์ฉํ API ํธ์ถ
๐ ์ด๊ธฐ ๊ตฌ์ฑ
์ต์ด ๋์ค์ฝ๋ ๋ด์ ๋ฑ๋กํ๊ณ , ์ฃผ๋๊ฐ ๋ง๋ Server(์๋ฒ)์ ์ด๋ํ๋ ๋ถ๋ถ์ ํด์ฃผ์ด์ผ ํด์.
์ต์ด ์ Site(์ฌ์ดํธ)์ ์ ์ํด ์ค๋๋ค.
์ต์ด ๋ก๊ทธ์ธ์ ํ๋ฉด ์ด๋ฐ Page(ํ์ด์ง)๋ฅผ ๋ง๋ ์ ์์ด์.
์ด ๊ณณ์์ ์ ์ค๋ฅธ์ชฝ์ New Application์ ๋๋ฌ ์ค๋๋ค.
์์ ๊ฐ์ด ์ด๋ฆ์ ์ ์ํด์ฃผ๊ณ , ์ด์ฉ ์ฝ๊ด์ ๋์๋ฅผ ํด ์ค ๋ค Create๋ฅผ ๋๋ฌ ์ค๋๋ค.
Bot Tab์ผ๋ก ์ด๋ํ์ฌ Add Bot ๋ฒํผ์ ํด๋ฆญํ์ฌ ์ค๊ฒ์.
Yes, do it! ์ ๋๋ฌ ์ค๋๋ค.
MESSAGE CONTENT INTENT๋ฅผ ์์ ๊ฐ์ด ํ์ฉ์ ํด์ฃผ์ด์ผ ๋์ค์ฝ๋์์ ๋ฉ์์ง๋ฅผ ์
๋ ฅํ์ ๋, ์คํ๋ง ๋ถํธ์์ ๋ฐ์ ์ ์์ด์.
๋ง์ฝ ์ด๋ ๊ฒ ํ์ง ์๋๋ค๋ฉด ์คํ๋ง ๋ถํธ์์๋ ๊ณต๋ฐฑ๊ฐ๋ง ๋ค์ด์ค๊ฒ ๋ ๊ฑฐ์์.
์ด๊ฑฐ ์ฐพ๋๋ผ ๋ง์ด ๊ณ ์ํ์ด์...
์ด๋ ๊ฒ ํ๋ฉด Bot์ด ๋ง๋ค์ด ์ง๊ฑธ ํ์ธ ํ ์ ์์ด์.
๊ทธ๋ฐ ๋ค TOKEN์ COPY๋ฅผ ๋๋ฅด๋ฉด BOT ๊ด๋ จ TOKEN ๊ฐ์ ์ป์ ์ ์์ด์.
์ค์ JAVA์์ ์ด TOKEN ๊ฐ์ ์จ์ผ ํ๊ธฐ ๋๋ฌธ์ ์ ์ ์ฅํด ๋์ด์ผ ํด์.
๊ทธ๋ผ ์์ ๊ฐ์ด APPLICATION ID, PUBLIC KEY๊ฐ ๋ง๋ค์ด์ง ๊ฑธ ํ์ธํ ์ ์์ด์.
OAuth2 Tab์ ๋ค์ด๊ฐ ๋ณด๋ฉด ์์ ๊ฐ์ด CLIENT ID๋ฅผ ์ป์ ์ ์์ด์.
์ด ๊ณณ์์ BOT์ ๊ถํ๋ ์ค์ ํด ์ค ์ ์์ด์.
์ฃผ๋๋ ์์ ๊ฐ์ด BOT์๊ฒ ๊ถํ์ ์ฃผ๋ ค๊ณ ํด์.
๋ฐ์ ์์ ๊ฐ์ด URL์ด ํ๋ ๋ง๋ค์ด์งํ
๋ฐ, ๊ทธ๊ฑธ ๋ธ๋ผ์ฐ์ ์ ์
๋ ฅ ํด ์ค๋๋ค.
์ ์์ ํ๋ฉด ์์ ๊ฐ์ ํ์ด์ง๋ก ์ด๋ํ ์ ์์ด์.
์์ ๊ฐ์ด ์ถ๊ฐํ ๋์ค์ฝ๋ ์๋ฒ๋ฅผ ์ ํํ๊ณ , ์น์ธ์ ๋๋ฌ ์ค๋๋ค.
์ฃผ๋๊ฐ ๋ง๋ test-bot์ด ์ฑ๋์ ๋ค์ด์จ ๊ฑธ ํ์ธํ ์ ์์ด์.
์ด์ Bot ์ค๋น๋ฅผ ์๋ฃํ์์ผ๋ ์คํ๋ง ๋ถํธ Project(ํ๋ก์ ํธ)๋ฅผ ๋ง๋ค์ด ์ฃผ๋๋ก ํ ๊ฒ์.
์ฃผ๋๋ InteliJ Ultimate (์ธํ
๋ฆฌ์ ์ด ์ผํฐ๋ฉ์ดํธ) Version(๋ฒ์ )์ ํตํด ์์ ๊ฐ์ด ํ๋ก์ ํธ๋ฅผ ๋ง๋ค์ด ์ฃผ๋ ค๊ณ ํด์.
์คํ๋ง ๋ถํธ ๋ฒ์ ๊ณผ Dependency(์์กด์ฑ)์ ์ด๋ ๊ฒ ์ค์ ์ ํ๊ณ ์์ํด ๋ณด๋ ค๊ณ ํด์.
์ฃผ๋๋ JDA๋ผ๋ ๊ฒ์ ์ด์ฉํด์ ๊ฐ๋ฐ์ ์ฆ๊ฒจ๋ณด๋ ค๊ณ ํด์.
JDA ์์กด์ฑ์ build.gradle์ ์ถ๊ฐํด ์ฃผ์์ด์.
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// Discord Bot ์ฌ์ฉ์ ์ํ JDA ์์กด์ฑ
implementation 'net.dv8tion:JDA:5.0.0-beta.5'
}
์ด์ ์ฆ๊ฒ๊ฒ ์ฝ๋ฉ์ ์ฆ๊ฒจ ๋ณผ๊ฒ์.
๐ฝ ์ฝ๋ ์์ฑ ๋ฐ ์ด๊ธฐ ์ค์
์ต์ด ๋์ค์ฝ๋ ๋ด Token(ํ ํฐ) ๊ฐ์ ์์ ํ๊ฒ ๊ด๋ฆฌํ๊ธฐ ์ํด application.yml์ ์์ ๊ฐ์ด ๊ฐ์ ๋ฃ์ด ์ฃผ์์ด์.
์ต์ด ์์ ๊ฐ์ด main()์ด ์๋ ๊ณณ์ Login์ด ์ ๋์์ ๋ ์ฒ๋ฆฌ๋ฅผ ์ํ LoginException์ ์ฒ๋ฆฌํ๋๋ก ํด ์ฃผ์์ด์.
20~22๋ฒ์งธ ์ค ์ฝ๋๋ application.yml์ ์
๋ ฅํ Token๊ฐ์ main()์์ ๊ฐ์ ธ์ค๊ฒ ํ๊ธฐ ์ํด ๋ง๋ ๋ถ๋ถ์ด์์.
24๋ฒ์งธ ์ค์ JDABuilder๋ฅผ ํตํด application.yml์ ์
๋ ฅ๋ Token๊ฐ์ ๊ฐ์ ธ์ค๊ฒ ํด์ค๋๋ค.
25๋ฒ์งธ ์ค์ ๋ฌธ์์ด์ ๋ฃ๊ฒ ๋๋ฉด
์์ ๊ฐ์ด ์ํ ๋ฉ์ธ์ง๋ฅผ ์ฒ๋ฆฌํด ์ค ์ ์์ด์.
26๋ฒ์งธ ์ค์ GatewayIntent๋ฅผ ํตํด Message๋ฅผ ๋์ค์ฝ๋์์ ๋ฐ์ ์ ์๋๋ก ์ฒ๋ฆฌํด ์ค์ผ ํด์.
๊ทธ๋ฐ ๋ค 27๋ฒ์งธ ์ค์ EventListener์์ Listener ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด Message๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ ์๊ฒ ์ฒ๋ฆฌํด ์ค ์ ์์ด์.
์ ๋ถ๋ถ์์ application.yml์ ์๋ Token ๊ฐ์ ๊ฐ์ ธ์์ Getter๋ฅผ ํตํด main()์์ Token๊ฐ์ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ์ฒ๋ฆฌํด ์ฃผ์์ด์.
์ด๋ฒ์๋ ์ค์ ๋ก ๋ฉ์์ง ์ฒ๋ฆฌ๋ฅผ ๋ด๋นํ DiscordListener๋ฅผ ๋ง๋ค์ด ์ฃผ์์ด์.
18๋ฒ์งธ ์ค์ ๋งค๊ฐ ๋ณ์ event ์์ ๋์ค์ฝ๋์์ ๋ฉ์์ง๋ฅผ ๋ณด๋ธ ์ฌ๋์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋๋ก ํ์ฌ ์ฃผ๊ณ ,
19๋ฒ์งธ ์ค์ ๋ด์ด ๋ฉ์์ง๋ฅผ ๋ณด๋ผ ๋์ค์ฝ๋ Channel(์ฑ๋) ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ํ์ฌ ์ฃผ์์ด์.
๊ทธ๋ฐ ๋ค 20๋ฒ์งธ ์ค์ ๋์ค์ฝ๋ ์ชฝ์์ ์ ๋ฌ๋ ๋ฉ์์ง๋ฅผ ๋ฐ์ ์ ์๋ ๋ณ์๋ค์ ๋ง๋ค์ด ์ฃผ์์ด์.
24๋ฒ์งธ ์ค์ ๋ฉ์์ง ๋ณด๋ธ ์ฌ๋์ ์ ๋ณด๊ฐ ๋ด์ด๋ผ๋ฉด ์๋ฌด ๋์์ ํ์ง ์๋๋ก ์ฒ๋ฆฌํ์ฌ ์ฃผ์๊ณ , ๋ฉ์์ง๋ก ๋ค์ด์จ ๋ด์ฉ์ด ๊ณต๋ฐฑ์ด๋ผ๋ฉด 27๋ฒ์งธ ์ค ๋์์ด ์ฒ๋ฆฌ๋ ์ ์๊ฒ ํด ์ฃผ์์ด์.
์ฃผ๋๋ ๋์ค์ฝ๋์์ ๋ค์ด์จ ๋ฉ์์ง๋ฅผ ๋์ด์ฐ๊ธฐ ์ฆ, ๊ณต๋ฐฑ์ ๊ธฐ์ค์ผ๋ก ์๋ผ์ ์ฒ๋ฆฌ๋ฅผ ํ๊ณ ์ถ์๊ธฐ ๋๋ฌธ์ 30๋ฒ์งธ ์ค ์ฒ๋ผ ๊ณต๋ฐฑ์ ๊ธฐ์ค์ผ๋ก messageArray์ ๊ฐ๊ฐ์ ๋ฌธ์์ด์ด ๋ค์ด๊ฐ ์ ์๋๋ก ํ์ฌ ์ฃผ์์ด์.
๊ทธ๋ฐ ๋ค 32๋ฒ์งธ ์ค์ ๋ฉ์์ง์ ์ฒซ๋ฒ์งธ ๋ฌธ์์ด์ด ์ฃผ๋์ผ๋ผ๋ฉด 34 ~ 38๋ฒ์งธ ์ค ์ฒ๋ฆฌ๊ฐ ๋๋๋ก ํ์ฌ์ฃผ์์ด์.
์ฐธ๊ณ ๋ก equalsIgnoreCase()๋ ๋, ์๋ฌธ์๋ฅผ ๊ตฌ๋ถํ์ง ์๊ณ , ๋ค์ด์จ ๊ฐ์ ์๋ณํ๊ธฐ ์ํด ์ฌ์ฉํ๋ Method(๋ฉ์๋)์์.
34๋ฒ์งธ ์ค์ ๋ณด๋ฉด messageArray์ ๊ฐ ์ค ๋งจ ์ฒซ ๋ฐฐ์ด๊ฐ์ธ ์ฃผ๋์ผ๋ ์ด์ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ํด๋น ๊ฐ์ ์ ์ธํ ๋๋จธ์ง ๋ฌธ์์ด๋ค์ ์๋กญ๊ฒ messageArgs ๋ฐฐ์ด์ ๋ฃ์ด ์ฃผ์์ด์.
36๋ฒ์งธ์ ํด๋น ๋ฌธ์์ด ๋ฐฐ์ด ๊ฐ์๋งํผ ๋ฐ๋ณตํ๊ฒ ํ์ฌ sendMessage()์์ event์ ๋ฉ์์ง ๋ด์ฉ์ ๋ฐ์ ๋ด์ด ๋ฐํํ ๋ฉ์์ง๋ฅผ ๋ง๋ค์ด ๋ฐํ๋ฐ์ ์ ์๋๋ก ํด ์ฃผ์์ด์.
๊ทธ๋ฐ ๋ค 38๋ฒ์งธ ์ค์ ๋ฐํ ๋ฐ์ ๋ด์ ๋๋ต์ ๋์ค์ฝ๋ ํด๋น ์ฑ๋๋ก ๋ณด๋ด์ง ์ ์๊ฒ ํด ์ฃผ์์ด์.
์ด ๊ณณ์์ ๋์ค์ฝ๋ ๋ด์ด ๋๋ตํ ๋ฌธ์์ด์ ๋ง๋ค์ด ์ค ์ ์๊ฒ ํด ์ฃผ์์ด์.
45๋ฒ์งธ ์ค์ event.getAuthor()๋ฅผ ํตํด ๋ฉ์์ง๋ฅผ ๋ณด๋ธ ์ฌ์ฉ์์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ ๊ฐ์ฒด๋ฅผ user ๋ณ์์ ๋ฃ์ด ์ฃผ์๊ณ , ๋ด์ด ๋ฐํํ ๋๋ต ๋ฌธ์์ด ๋ณ์ returnMessage๋ฅผ ๊ณต๋ฐฑ์ผ๋ก ์ด๊ธฐํ ํด ์ฃผ์์ด์.
๊ทธ๋ฐ ๋ค ๋งค๊ฐ ๋ณ์๋ก ์ ๋ฌ๋ message ์ฆ, ์ฌ์ฉ์๊ฐ ๋ณด๋ธ ๋ฉ์์ง๋ฅผ ๊ฐ์ง๊ณ , ๋ถ๊ธฐ๋ฌธ(switch)๊ฐ ์ฒ๋ฆฌ ๋๋๋ก ํ์๋๋ฐ, ์๋
์ด๋ผ๋ ๋ฌธ์์ด์ด ๋ค์ด์จ๋ค๋ฉด ๋๋ต ๋ฌธ์์ด ๋ณ์์ ๋ณด๋ธ ์ฌ์ฉ์๊ฐ ์ค์ ํ ๋์ค์ฝ๋ ์ด๋ฆ๊ฐ๊ณผ ํจ๊ป ๋ฐํ๋ ๋ฌธ์์ด์ ๋ฃ์ด์ฃผ์์ด์.
51๋ฒ์งธ case์ ์ฌ์ฉ์๊ฐ test๋ผ๋ ๋ฌธ์์ด์ ๋ณด๋๋ค๋ฉด ์ฌ์ฉ์ ๊ณ์ ์ Tag ์ ๋ณด๊ฐ๊ณผ ํจ๊ป ๋ฌธ์์ด์ด ๋๋ต ๋ฌธ์์ด ๋ณ์์ ๋ค์ด๊ฐ ์ ์๋๋ก ํ์ฌ ์ฃผ์์ด์.
๋ง์ง๋ง์ผ๋ก ๋๊ตฌ์ผ๋ผ๋ ๋ฌธ์์ด์ด ๋ค์ด์จ๋ค๋ฉด ์ฌ์ฉ์๋ฅผ Mention(๋ฉ์
)ํ์ฌ ๋ถ๋ฅธ ๋ค ๋ค์ ๋ฌธ์์ด์ด ๋ค์ด๊ฐ ์ ์๋๋ก ์ฒ๋ฆฌํด ์ฃผ์์ด์.
์ด๋ ๊ฒ ๋์ค์ฝ๋๋ฅผ ํตํด ๋ด๊ณผ ๋ํํ ์ ์๋ ํ๋ก๊ทธ๋จ์ ๋ง๋ค์ด ๋ณด์์ด์.
๋ค์์๋ Data Base(๋ฐ์ดํฐ ๋ฒ ์ด์ค)์ ์ ์ฅ๋ ๊ฐ์ ์กฐํํ ์ ์๋ ๊ธฐ๋ฅ์ ๋ง๋ค์ด ๋ณด๋๋ก ํ ๊ฒ์.
์์ค์ฝ๋๋ ์ด ๊ณณ์ ์ค๋นํด ๋์์ด์.
"์ด ํฌ์คํ ์ ์ฟ ํก ํํธ๋์ค ํ๋์ ์ผํ์ผ๋ก, ์ด์ ๋ฐ๋ฅธ ์ผ์ ์ก์ ์์๋ฃ๋ฅผ ์ ๊ณต๋ฐ์ต๋๋ค."
๐ง ์ฐธ๊ณ ์๋ฃ