Merge pull request #52 from dalbodeule/develop

add and debug discord hook logics
This commit is contained in:
JinU Choi 2024-08-10 16:57:42 +09:00 committed by GitHub
commit ba028a01a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 138 additions and 68 deletions

View File

@ -61,7 +61,7 @@ class Discord: ListenerAdapter() {
AddCommand,
AlertCommand,
PingCommand,
RegisterCommand,
HookComand,
RemoveCommand,
UpdateCommand,
AddManagerCommand,

View File

@ -37,7 +37,7 @@ object AddManagerCommand : CommandInterface {
try {
ManagerService.saveManager(user, manager.idLong, manager.effectiveName)
if(user.liveAlertGuild == null)
UserService.updateLiveAlert(user.id.value, event.guild!!.idLong, event.channelIdLong, "")
UserService.updateLiveAlert(user, event.guild!!.idLong, event.channelIdLong, "")
event.hook.sendMessage("등록이 완료되었습니다. ${manager.effectiveName}").queue()
} catch (e: Exception) {
event.hook.sendMessage("에러가 발생했습니다.").queue()

View File

@ -46,7 +46,7 @@ object AlertCommand : CommandInterface {
val chzzkChannel = user!!.token?.let { Connector.getChannel(it) }
try {
val newUser = UserService.updateLiveAlert(user!!.id.value, channel?.guild?.idLong ?: 0L, channel?.idLong ?: 0L, content ?: "")
val newUser = UserService.updateLiveAlert(user!!, channel?.guild?.idLong ?: 0L, channel?.idLong ?: 0L, content ?: "")
try {
ChzzkHandler.reloadUser(chzzkChannel!!, newUser)
} catch (_: Exception) {}

View File

@ -0,0 +1,61 @@
package space.mori.chzzk_bot.chatbot.discord.commands
import net.dv8tion.jda.api.JDA
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent
import net.dv8tion.jda.api.interactions.commands.OptionType
import net.dv8tion.jda.api.interactions.commands.build.Commands
import net.dv8tion.jda.api.interactions.commands.build.OptionData
import org.koin.java.KoinJavaComponent.inject
import org.slf4j.LoggerFactory
import space.mori.chzzk_bot.chatbot.discord.CommandInterface
import space.mori.chzzk_bot.common.events.CoroutinesEventBus
import space.mori.chzzk_bot.common.events.DiscordRegisterEvent
import space.mori.chzzk_bot.common.services.UserService
import java.util.concurrent.ConcurrentHashMap
object HookComand: CommandInterface {
private val logger = LoggerFactory.getLogger(this::class.java)
override val name = "hook"
override val command = Commands.slash(name, "디스코드 계정과 서버를 등록합니다.")
.addOptions(OptionData(OptionType.STRING, "token", "디스코드 연동 토큰을 입력해주세요."))
// key: Token, value: ChzzkID
private val hookMap = ConcurrentHashMap<String, String>()
private val dispatcher: CoroutinesEventBus by inject(CoroutinesEventBus::class.java)
init {
dispatcher.subscribe(DiscordRegisterEvent::class) {
hookMap[it.token] = it.user
}
}
override fun run(event: SlashCommandInteractionEvent, bot: JDA) {
val token = event.getOption("token")?.asString
if(token == null) {
event.hook.sendMessage("Token은 필수 입력입니다.").queue()
return
}
val user = UserService.getUser(hookMap[token] ?: "")
if (user == null) {
event.hook.sendMessage("치지직 계정을 찾을 수 없습니다.").queue()
return
}
if(event.guild == null) {
event.hook.sendMessage("이 명령어는 디스코드 서버 안에서 실행해야 합니다.").queue()
return
}
try {
UserService.updateUser(user, event.user.idLong)
UserService.updateLiveAlert(user, event.guild!!.idLong, event.channelIdLong, "")
hookMap.remove(token)
event.hook.sendMessage("등록이 완료되었습니다. `${user.username}`")
} catch(e: Exception) {
event.hook.sendMessage("에러가 발생했습니다.").queue()
logger.debug(e.stackTraceToString())
}
}
}

View File

@ -1,54 +0,0 @@
package space.mori.chzzk_bot.chatbot.discord.commands
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import net.dv8tion.jda.api.JDA
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent
import net.dv8tion.jda.api.interactions.commands.OptionType
import net.dv8tion.jda.api.interactions.commands.build.Commands
import net.dv8tion.jda.api.interactions.commands.build.OptionData
import org.slf4j.LoggerFactory
import space.mori.chzzk_bot.chatbot.chzzk.ChzzkHandler
import space.mori.chzzk_bot.chatbot.chzzk.Connector
import space.mori.chzzk_bot.chatbot.discord.CommandInterface
import space.mori.chzzk_bot.common.services.UserService
object RegisterCommand: CommandInterface {
private val logger = LoggerFactory.getLogger(this::class.java)
override val name = "register"
private val regex = """(?:.+chzzk\.naver\.com/)?([a-f0-9]{32})?(?:/live)?${'$'}""".toRegex()
override val command = Commands.slash(name, "치지직 계정을 등록합니다.")
override fun run(event: SlashCommandInteractionEvent, bot: JDA) {
event.hook.sendMessage("가입은 여기를 참고해주세요!\nhttps://nabot.mori.space/register").queue()
/* val chzzkID = event.getOption("chzzk_id")?.asString
if(chzzkID == null) {
event.hook.sendMessage("치지직 계정은 필수 입력입니다.").queue()
return
}
val matchResult = regex.find(chzzkID)
val matchedChzzkId = matchResult?.groups?.get(1)?.value
val chzzkChannel = matchedChzzkId?.let { Connector.getChannel(it) }
if (chzzkChannel == null) {
event.hook.sendMessage("치지직 계정을 찾을 수 없습니다.").queue()
return
}
try {
val user = UserService.saveUser(chzzkChannel.channelName, chzzkChannel.channelId, event.user.idLong)
CoroutineScope(Dispatchers.Main).launch {
ChzzkHandler.addUser(chzzkChannel, user)
}
event.hook.sendMessage("등록이 완료되었습니다. `${chzzkChannel.channelId}` - `${chzzkChannel.channelName}`")
} catch(e: Exception) {
event.hook.sendMessage("에러가 발생했습니다.").queue()
logger.debug(e.stackTraceToString())
} */
}
}

View File

@ -0,0 +1,8 @@
package space.mori.chzzk_bot.common.events
class DiscordRegisterEvent(
val user: String,
val token: String,
): Event {
val TAG = javaClass.simpleName
}

View File

@ -2,7 +2,6 @@ package space.mori.chzzk_bot.common.services
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.update
import space.mori.chzzk_bot.common.models.User
import space.mori.chzzk_bot.common.models.Users
@ -76,18 +75,13 @@ object UserService {
}
}
fun updateLiveAlert(id: Int, guildId: Long, channelId: Long, alertMessage: String?): User {
fun updateLiveAlert(user: User, guildId: Long, channelId: Long, alertMessage: String?): User {
return transaction {
val updated = Users.update({ Users.id eq id }) {
it[liveAlertGuild] = guildId
it[liveAlertChannel] = channelId
it[liveAlertMessage] = alertMessage ?: ""
}
user.liveAlertGuild = guildId
user.liveAlertChannel = channelId
user.liveAlertMessage = alertMessage ?: ""
if(updated == 0) throw RuntimeException("User not found! $id")
val users = User.find { Users.id eq id }
return@transaction users.first()
user
}
}
}

View File

@ -111,6 +111,7 @@ val server = embeddedServer(Netty, port = 8080, ) {
apiSongRoutes()
apiCommandRoutes()
apiTimerRoutes()
apiDiscordRoutes()
wsTimerRoutes()
wsSongRoutes()

View File

@ -0,0 +1,60 @@
package space.mori.chzzk_bot.webserver.routes
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.sessions.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.koin.java.KoinJavaComponent.inject
import space.mori.chzzk_bot.common.events.CoroutinesEventBus
import space.mori.chzzk_bot.common.events.DiscordRegisterEvent
import space.mori.chzzk_bot.common.services.UserService
import space.mori.chzzk_bot.common.utils.getRandomString
import space.mori.chzzk_bot.webserver.UserSession
fun Route.apiDiscordRoutes() {
val dispatcher: CoroutinesEventBus by inject(CoroutinesEventBus::class.java)
route("/discord") {
get("{uid}") {
val uid = call.parameters["uid"]
val session = call.sessions.get<UserSession>()
if(uid == null) {
call.respond(HttpStatusCode.BadRequest, "UID is required")
return@get
}
val user = UserService.getUser(uid)
if(user == null || user.naverId != session?.id || user.token == null) {
call.respond(HttpStatusCode.BadRequest, "User does not exist")
return@get
}
if (user.discord == null) {
val randomString = getRandomString(8)
CoroutineScope(Dispatchers.Default).launch {
dispatcher.post(DiscordRegisterEvent(
user.token!!,
randomString
))
}
call.respond(HttpStatusCode.NotFound, DiscordRequireRegisterDTO(
user.token!!,
randomString
))
return@get
}
}
}
}
data class DiscordRequireRegisterDTO(
val user: String,
val passkey: String
)