add POST /user endpoints.

- POST /user {"chzzkUrl": String} to add chzzk account to bots.
- and it post event UserRegisterEvent
This commit is contained in:
dalbodeule 2024-08-08 19:36:58 +09:00
parent d0840ad6a7
commit 80fa2d5029
No known key found for this signature in database
GPG Key ID: EFA860D069C9FA65
4 changed files with 97 additions and 7 deletions

View File

@ -8,6 +8,7 @@ import org.koin.java.KoinJavaComponent.inject
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import space.mori.chzzk_bot.chatbot.chzzk.Connector.chzzk 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.chatbot.discord.Discord
import space.mori.chzzk_bot.common.events.* import space.mori.chzzk_bot.common.events.*
import space.mori.chzzk_bot.common.models.User import space.mori.chzzk_bot.common.models.User
@ -28,6 +29,7 @@ object ChzzkHandler {
private val logger = LoggerFactory.getLogger(this::class.java) private val logger = LoggerFactory.getLogger(this::class.java)
lateinit var botUid: String lateinit var botUid: String
@Volatile private var running: Boolean = false @Volatile private var running: Boolean = false
val dispatcher: CoroutinesEventBus by inject(CoroutinesEventBus::class.java)
fun addUser(chzzkChannel: ChzzkChannel, user: User) { fun addUser(chzzkChannel: ChzzkChannel, user: User) {
handlers.add(UserHandler(chzzkChannel, logger, user, streamStartTime = null)) handlers.add(UserHandler(chzzkChannel, logger, user, streamStartTime = null))
@ -43,6 +45,14 @@ object ChzzkHandler {
val streamInfo = getStreamInfo(handler.listener.channelId) val streamInfo = getStreamInfo(handler.listener.channelId)
if (streamInfo.content?.status == "OPEN") handler.isActive(true, streamInfo) 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() { fun disable() {

View File

@ -0,0 +1,7 @@
package space.mori.chzzk_bot.common.events
data class UserRegisterEvent(
val chzzkId: String
): Event {
val TAG = javaClass.simpleName
}

View File

@ -7,16 +7,31 @@ import space.mori.chzzk_bot.common.models.User
import space.mori.chzzk_bot.common.models.Users import space.mori.chzzk_bot.common.models.Users
object UserService { object UserService {
fun saveUser(username: String, token: String, discordID: Long): User { fun saveUser(username: String, naverId: String): User {
return transaction { return transaction {
User.new { User.new {
this.username = username this.username = username
this.token = token this.naverId = naverId
this.discord = discordID
} }
} }
} }
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? { fun getUser(id: Int): User? {
return transaction { return transaction {
User.findById(id) User.findById(id)

View File

@ -2,10 +2,17 @@ package space.mori.chzzk_bot.webserver.routes
import io.ktor.http.* import io.ktor.http.*
import io.ktor.server.application.* import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.* import io.ktor.server.response.*
import io.ktor.server.routing.* import io.ktor.server.routing.*
import io.ktor.server.sessions.* import io.ktor.server.sessions.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable 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.SongConfigService
import space.mori.chzzk_bot.common.services.UserService import space.mori.chzzk_bot.common.services.UserService
import space.mori.chzzk_bot.common.utils.getStreamInfo import space.mori.chzzk_bot.common.utils.getStreamInfo
@ -30,7 +37,15 @@ data class GetSessionDTO(
val isStreamerOnly: Boolean, val isStreamerOnly: Boolean,
) )
@Serializable
data class RegisterChzzkUserDTO(
val chzzkUrl: String
)
fun Routing.apiRoutes() { fun Routing.apiRoutes() {
val chzzkIDRegex = """(?:.+chzzk\.naver\.com/)?([a-f0-9]{32})?(?:/live)?${'$'}""".toRegex()
val dispatcher: CoroutinesEventBus by inject(CoroutinesEventBus::class.java)
route("/") { route("/") {
get { get {
call.respondText("Hello World!", status = call.respondText("Hello World!", status =
@ -69,18 +84,21 @@ fun Routing.apiRoutes() {
val session = call.sessions.get<UserSession>() val session = call.sessions.get<UserSession>()
if(session == null) { if(session == null) {
call.respondText("No session found", status = HttpStatusCode.NotFound) call.respondText("No session found", status = HttpStatusCode.Unauthorized)
return@get return@get
} }
println(session) println(session)
val user = UserService.getUserWithNaverId(session.id) var user = UserService.getUserWithNaverId(session.id)
if(user == null) { if(user == null) {
call.respondText("No session found", status = HttpStatusCode.NotFound) user = UserService.saveUser(session.nickname, session.id)
return@get
} }
val songConfig = SongConfigService.getConfig(user) val songConfig = SongConfigService.getConfig(user)
val status = getStreamInfo(user.token) val status = getStreamInfo(user.token)
if(status.content == null) {
call.respondText(user.naverId, status = HttpStatusCode.NotFound)
}
call.respond(HttpStatusCode.OK, GetSessionDTO( call.respond(HttpStatusCode.OK, GetSessionDTO(
status.content!!.channel.channelId, status.content!!.channel.channelId,
status.content!!.channel.channelName, status.content!!.channel.channelName,
@ -91,5 +109,45 @@ fun Routing.apiRoutes() {
songConfig.streamerOnly songConfig.streamerOnly
)) ))
} }
post {
val session = call.sessions.get<UserSession>()
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
}
} }
} }