diff --git a/chatbot/src/main/kotlin/space/mori/chzzk_bot/chatbot/chzzk/ChzzkHandler.kt b/chatbot/src/main/kotlin/space/mori/chzzk_bot/chatbot/chzzk/ChzzkHandler.kt index 227ad13..65463c3 100644 --- a/chatbot/src/main/kotlin/space/mori/chzzk_bot/chatbot/chzzk/ChzzkHandler.kt +++ b/chatbot/src/main/kotlin/space/mori/chzzk_bot/chatbot/chzzk/ChzzkHandler.kt @@ -8,6 +8,7 @@ import org.koin.java.KoinJavaComponent.inject import org.slf4j.Logger import org.slf4j.LoggerFactory import space.mori.chzzk_bot.chatbot.chzzk.Connector.chzzk +import space.mori.chzzk_bot.chatbot.chzzk.Connector.getChannel import space.mori.chzzk_bot.chatbot.discord.Discord import space.mori.chzzk_bot.common.events.* import space.mori.chzzk_bot.common.models.User @@ -28,6 +29,7 @@ object ChzzkHandler { private val logger = LoggerFactory.getLogger(this::class.java) lateinit var botUid: String @Volatile private var running: Boolean = false + val dispatcher: CoroutinesEventBus by inject(CoroutinesEventBus::class.java) fun addUser(chzzkChannel: ChzzkChannel, user: User) { handlers.add(UserHandler(chzzkChannel, logger, user, streamStartTime = null)) @@ -43,6 +45,14 @@ object ChzzkHandler { val streamInfo = getStreamInfo(handler.listener.channelId) if (streamInfo.content?.status == "OPEN") handler.isActive(true, streamInfo) } + + dispatcher.subscribe(UserRegisterEvent::class) { + val channel = getChannel(it.chzzkId) + val user = UserService.getUser(it.chzzkId) + if(channel != null && user != null) { + addUser(channel, user) + } + } } fun disable() { diff --git a/common/src/main/kotlin/space/mori/chzzk_bot/common/events/UserRegisterEvent.kt b/common/src/main/kotlin/space/mori/chzzk_bot/common/events/UserRegisterEvent.kt new file mode 100644 index 0000000..e55d60a --- /dev/null +++ b/common/src/main/kotlin/space/mori/chzzk_bot/common/events/UserRegisterEvent.kt @@ -0,0 +1,7 @@ +package space.mori.chzzk_bot.common.events + +data class UserRegisterEvent( + val chzzkId: String +): Event { + val TAG = javaClass.simpleName +} \ No newline at end of file diff --git a/common/src/main/kotlin/space/mori/chzzk_bot/common/services/UserService.kt b/common/src/main/kotlin/space/mori/chzzk_bot/common/services/UserService.kt index 4b430a8..113c20c 100644 --- a/common/src/main/kotlin/space/mori/chzzk_bot/common/services/UserService.kt +++ b/common/src/main/kotlin/space/mori/chzzk_bot/common/services/UserService.kt @@ -7,16 +7,31 @@ import space.mori.chzzk_bot.common.models.User import space.mori.chzzk_bot.common.models.Users object UserService { - fun saveUser(username: String, token: String, discordID: Long): User { + fun saveUser(username: String, naverId: String): User { return transaction { User.new { this.username = username - this.token = token - this.discord = discordID + this.naverId = naverId } } } + fun updateUser(user: User, chzzkId: String, username: String): User { + return transaction { + user.token = chzzkId + user.username = username + + user + } + } + + fun updateUser(user: User, discordID: Long): User { + return transaction { + user.discord = discordID + user + } + } + fun getUser(id: Int): User? { return transaction { User.findById(id) diff --git a/webserver/src/main/kotlin/space/mori/chzzk_bot/webserver/routes/ApiRoutes.kt b/webserver/src/main/kotlin/space/mori/chzzk_bot/webserver/routes/ApiRoutes.kt index 617d03c..af8c34f 100644 --- a/webserver/src/main/kotlin/space/mori/chzzk_bot/webserver/routes/ApiRoutes.kt +++ b/webserver/src/main/kotlin/space/mori/chzzk_bot/webserver/routes/ApiRoutes.kt @@ -2,10 +2,17 @@ package space.mori.chzzk_bot.webserver.routes import io.ktor.http.* import io.ktor.server.application.* +import io.ktor.server.request.* 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 kotlinx.serialization.Serializable +import org.koin.java.KoinJavaComponent.inject +import space.mori.chzzk_bot.common.events.CoroutinesEventBus +import space.mori.chzzk_bot.common.events.UserRegisterEvent import space.mori.chzzk_bot.common.services.SongConfigService import space.mori.chzzk_bot.common.services.UserService import space.mori.chzzk_bot.common.utils.getStreamInfo @@ -30,7 +37,15 @@ data class GetSessionDTO( val isStreamerOnly: Boolean, ) +@Serializable +data class RegisterChzzkUserDTO( + val chzzkUrl: String +) + fun Routing.apiRoutes() { + val chzzkIDRegex = """(?:.+chzzk\.naver\.com/)?([a-f0-9]{32})?(?:/live)?${'$'}""".toRegex() + val dispatcher: CoroutinesEventBus by inject(CoroutinesEventBus::class.java) + route("/") { get { call.respondText("Hello World!", status = @@ -69,18 +84,21 @@ fun Routing.apiRoutes() { val session = call.sessions.get() if(session == null) { - call.respondText("No session found", status = HttpStatusCode.NotFound) + call.respondText("No session found", status = HttpStatusCode.Unauthorized) return@get } println(session) - val user = UserService.getUserWithNaverId(session.id) + var user = UserService.getUserWithNaverId(session.id) if(user == null) { - call.respondText("No session found", status = HttpStatusCode.NotFound) - return@get + user = UserService.saveUser(session.nickname, session.id) } val songConfig = SongConfigService.getConfig(user) val status = getStreamInfo(user.token) + if(status.content == null) { + call.respondText(user.naverId, status = HttpStatusCode.NotFound) + } + call.respond(HttpStatusCode.OK, GetSessionDTO( status.content!!.channel.channelId, status.content!!.channel.channelName, @@ -91,5 +109,45 @@ fun Routing.apiRoutes() { songConfig.streamerOnly )) } + post { + val session = call.sessions.get() + if(session == null) { + call.respondText("No session found", status = HttpStatusCode.Unauthorized) + return@post + } + + val body: RegisterChzzkUserDTO = call.receive() + + val user = UserService.getUserWithNaverId(session.id) + if(user == null) { + call.respondText("No session found", status = HttpStatusCode.Unauthorized) + return@post + } + + val matchResult = chzzkIDRegex.find(body.chzzkUrl) + val matchedChzzkId = matchResult?.groups?.get(1)?.value + + if (matchedChzzkId == null) { + call.respondText("Invalid chzzk ID", status = HttpStatusCode.BadRequest) + return@post + } + + val status = getStreamInfo(matchedChzzkId) + if (status.content == null) { + call.respondText("Invalid chzzk ID", status = HttpStatusCode.BadRequest) + return@post + } + UserService.updateUser( + user, + status.content!!.channel.channelId, + status.content!!.channel.channelName + ) + call.respondText("Done!", status = HttpStatusCode.OK) + + CoroutineScope(Dispatchers.Default).launch { + dispatcher.post(UserRegisterEvent(status.content!!.channel.channelId)) + } + return@post + } } } \ No newline at end of file