Merge pull request #71 from dalbodeule/develop

avoid discord limits.
This commit is contained in:
JinU Choi 2024-08-14 18:13:41 +09:00 committed by GitHub
commit 61b27ade29
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 56 additions and 0 deletions

View File

@ -19,12 +19,14 @@ 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 io.ktor.server.websocket.* import io.ktor.server.websocket.*
import kotlinx.coroutines.delay
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import space.mori.chzzk_bot.common.services.UserService import space.mori.chzzk_bot.common.services.UserService
import space.mori.chzzk_bot.webserver.routes.* import space.mori.chzzk_bot.webserver.routes.*
import space.mori.chzzk_bot.webserver.utils.CachedGuilds import space.mori.chzzk_bot.webserver.utils.CachedGuilds
import space.mori.chzzk_bot.webserver.utils.DiscordGuildCache import space.mori.chzzk_bot.webserver.utils.DiscordGuildCache
import space.mori.chzzk_bot.webserver.utils.DiscordRatelimits
import space.mori.chzzk_bot.webserver.utils.Guild import space.mori.chzzk_bot.webserver.utils.Guild
import java.time.Duration import java.time.Duration
@ -287,21 +289,41 @@ data class DiscordGuildListAPI(
) )
suspend fun getDiscordUser(accessToken: String): DiscordMeAPI? { suspend fun getDiscordUser(accessToken: String): DiscordMeAPI? {
while(!DiscordRatelimits.getRateLimit()) {
delay(DiscordRatelimits.getRateReset())
}
val response: HttpResponse = applicationHttpClient.get("https://discord.com/api/oauth2/@me") { val response: HttpResponse = applicationHttpClient.get("https://discord.com/api/oauth2/@me") {
headers { headers {
append(HttpHeaders.Authorization, "Bearer $accessToken") append(HttpHeaders.Authorization, "Bearer $accessToken")
} }
} }
val rateLimit = response.headers["X-RateLimit-Limit"]?.toIntOrNull()
val remaining = response.headers["X-RateLimit-Remaining"]?.toIntOrNull()
val resetAfter = response.headers["X-RateLimit-Reset-After"]?.toDoubleOrNull()?.toLong()
DiscordRatelimits.setRateLimit(rateLimit, remaining, resetAfter)
return response.body<DiscordMeAPI?>() return response.body<DiscordMeAPI?>()
} }
suspend fun getUserGuilds(accessToken: String): List<DiscordGuildListAPI> { suspend fun getUserGuilds(accessToken: String): List<DiscordGuildListAPI> {
while(!DiscordRatelimits.getRateLimit()) {
delay(DiscordRatelimits.getRateReset())
}
val response = applicationHttpClient.get("https://discord.com/api/users/@me/guilds") { val response = applicationHttpClient.get("https://discord.com/api/users/@me/guilds") {
headers { headers {
append(HttpHeaders.Authorization, "Bearer $accessToken") append(HttpHeaders.Authorization, "Bearer $accessToken")
} }
} }
val rateLimit = response.headers["X-RateLimit-Limit"]?.toIntOrNull()
val remaining = response.headers["X-RateLimit-Remaining"]?.toIntOrNull()
val resetAfter = response.headers["X-RateLimit-Reset-After"]?.toDoubleOrNull()?.toLong()
DiscordRatelimits.setRateLimit(rateLimit, remaining, resetAfter)
return response.body<List<DiscordGuildListAPI>>() return response.body<List<DiscordGuildListAPI>>()
} }

View File

@ -41,12 +41,21 @@ object DiscordGuildCache {
} }
} }
val rateLimit = result.headers["X-RateLimit-Limit"]?.toIntOrNull()
val remaining = result.headers["X-RateLimit-Remaining"]?.toIntOrNull()
val resetAfter = result.headers["X-RateLimit-Reset-After"]?.toDoubleOrNull()?.toLong()
DiscordRatelimits.setRateLimit(rateLimit, remaining, resetAfter)
return result.body<List<DiscordGuildListAPI>>() return result.body<List<DiscordGuildListAPI>>()
} }
private suspend fun fetchAllGuilds() { private suspend fun fetchAllGuilds() {
var lastGuildId: String? = null var lastGuildId: String? = null
while (true) { while (true) {
while(!DiscordRatelimits.getRateLimit()) {
delay(DiscordRatelimits.getRateReset())
}
val guilds = fetchGuilds(lastGuildId) val guilds = fetchGuilds(lastGuildId)
if (guilds.isEmpty()) { if (guilds.isEmpty()) {
break break

View File

@ -0,0 +1,25 @@
package space.mori.chzzk_bot.webserver.utils
object DiscordRatelimits {
private var rateLimit = RateLimit(0, 0, 0L)
fun getRateLimit(): Boolean {
return rateLimit.remainin != 0
}
fun getRateReset() = rateLimit.resetAfter
private fun setRateLimit(rateLimit: RateLimit) {
this.rateLimit = rateLimit
}
fun setRateLimit(limit: Int?, remaining: Int?, resetAfter: Long?) {
return setRateLimit(RateLimit(limit ?: 0, remaining ?: 0, resetAfter ?: 0L))
}
}
data class RateLimit(
val limit: Int,
val remainin: Int,
val resetAfter: Long,
)