mirror of
https://github.com/dalbodeule/chibot-chzzk-bot.git
synced 2025-06-09 07:18:22 +00:00
commit
8aab3aa15b
@ -5,16 +5,11 @@ import io.ktor.server.application.*
|
|||||||
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 org.koin.java.KoinJavaComponent.inject
|
import org.koin.java.KoinJavaComponent.inject
|
||||||
import space.mori.chzzk_bot.common.events.CoroutinesEventBus
|
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.services.UserService
|
||||||
import space.mori.chzzk_bot.common.utils.getRandomString
|
|
||||||
import space.mori.chzzk_bot.webserver.UserSession
|
import space.mori.chzzk_bot.webserver.UserSession
|
||||||
|
import space.mori.chzzk_bot.webserver.utils.DiscordGuildCache
|
||||||
|
|
||||||
fun Route.apiDiscordRoutes() {
|
fun Route.apiDiscordRoutes() {
|
||||||
val dispatcher: CoroutinesEventBus by inject(CoroutinesEventBus::class.java)
|
val dispatcher: CoroutinesEventBus by inject(CoroutinesEventBus::class.java)
|
||||||
@ -34,23 +29,12 @@ fun Route.apiDiscordRoutes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (user.discord == null) {
|
if (user.discord == null) {
|
||||||
val randomString = getRandomString(8)
|
call.respond(HttpStatusCode.NotFound)
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.Default).launch {
|
|
||||||
dispatcher.post(DiscordRegisterEvent(
|
|
||||||
user.token!!,
|
|
||||||
randomString
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
call.respond(HttpStatusCode.NotFound, DiscordRequireRegisterDTO(
|
|
||||||
user.token!!,
|
|
||||||
randomString
|
|
||||||
))
|
|
||||||
return@get
|
return@get
|
||||||
}
|
}
|
||||||
|
|
||||||
call.respond(HttpStatusCode.OK)
|
call.respond(HttpStatusCode.OK)
|
||||||
|
return@get
|
||||||
}
|
}
|
||||||
get {
|
get {
|
||||||
val session = call.sessions.get<UserSession>()
|
val session = call.sessions.get<UserSession>()
|
||||||
@ -63,14 +47,9 @@ fun Route.apiDiscordRoutes() {
|
|||||||
call.respond(HttpStatusCode.BadRequest, "User does not exist")
|
call.respond(HttpStatusCode.BadRequest, "User does not exist")
|
||||||
return@get
|
return@get
|
||||||
}
|
}
|
||||||
call.respond(HttpStatusCode.OK, session.discordGuildList)
|
|
||||||
|
call.respond(HttpStatusCode.OK, DiscordGuildCache.getCachedGuilds(session.discordGuildList))
|
||||||
return@get
|
return@get
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class DiscordRequireRegisterDTO(
|
|
||||||
val user: String,
|
|
||||||
val token: String
|
|
||||||
)
|
|
@ -0,0 +1,75 @@
|
|||||||
|
package space.mori.chzzk_bot.webserver.utils
|
||||||
|
|
||||||
|
import applicationHttpClient
|
||||||
|
import io.ktor.client.call.*
|
||||||
|
import io.ktor.client.request.*
|
||||||
|
import io.ktor.http.*
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import space.mori.chzzk_bot.webserver.DiscordGuildListAPI
|
||||||
|
import space.mori.chzzk_bot.webserver.dotenv
|
||||||
|
import java.time.Instant
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
object DiscordGuildCache {
|
||||||
|
private val cache = ConcurrentHashMap<String, CachedGuilds>()
|
||||||
|
private const val EXP_SECONDS = 600L
|
||||||
|
|
||||||
|
suspend fun getCachedGuilds(guildId: String): Guild? {
|
||||||
|
val now = Instant.now()
|
||||||
|
|
||||||
|
return if(cache.isNotEmpty() && cache[guildId]?.timestamp?.plusSeconds(EXP_SECONDS)?.isAfter(now) == true) {
|
||||||
|
cache[guildId]?.guild
|
||||||
|
} else {
|
||||||
|
fetchAllGuilds()
|
||||||
|
cache[guildId]?.guild
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getCachedGuilds(guildId: List<String>): List<Guild> {
|
||||||
|
return guildId.mapNotNull { getCachedGuilds(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun fetchGuilds(beforeGuildId: String? = null, limit: Int = 100): List<DiscordGuildListAPI> {
|
||||||
|
val result = applicationHttpClient.get("https://discord.com/api/users/@me/guilds") {
|
||||||
|
headers {
|
||||||
|
append(HttpHeaders.Authorization, "Bot ${dotenv["DISCORD_TOKEN"]}")
|
||||||
|
}
|
||||||
|
parameter("limit", limit)
|
||||||
|
if (beforeGuildId != null) {
|
||||||
|
parameter("before", beforeGuildId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.body<List<DiscordGuildListAPI>>()
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun fetchAllGuilds() {
|
||||||
|
var lastGuildId: String? = null
|
||||||
|
while (true) {
|
||||||
|
val guilds = fetchGuilds(lastGuildId)
|
||||||
|
if (guilds.isEmpty()) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
guilds.forEach {
|
||||||
|
cache[it.id] = CachedGuilds(
|
||||||
|
Guild(it.id, it.name, it.icon, it.banner)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
lastGuildId = guilds.last().id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class CachedGuilds(
|
||||||
|
val guild: Guild,
|
||||||
|
val timestamp: Instant = Instant.now()
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Guild(
|
||||||
|
val id: String,
|
||||||
|
val name: String,
|
||||||
|
val icon: String?,
|
||||||
|
val banner: String?,
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user