1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2024-06-03 00:15:27 +00:00
tgbotapi/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt

106 lines
3.7 KiB
Kotlin
Raw Normal View History

2020-10-04 11:06:30 +00:00
package dev.inmo.tgbotapi.bot.Ktor
2018-12-26 08:07:24 +00:00
import dev.inmo.micro_utils.coroutines.safely
2020-10-04 11:06:30 +00:00
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
import dev.inmo.tgbotapi.bot.Ktor.base.*
2020-11-17 10:06:25 +00:00
import dev.inmo.tgbotapi.bot.TelegramBot
2020-10-04 11:06:30 +00:00
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
2021-01-09 14:59:37 +00:00
import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
2020-10-04 11:06:30 +00:00
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.Response
import dev.inmo.tgbotapi.utils.*
2018-12-26 08:07:24 +00:00
import io.ktor.client.HttpClient
import io.ktor.client.features.*
2020-01-15 06:28:06 +00:00
import io.ktor.client.statement.readText
2019-02-21 06:21:33 +00:00
import kotlinx.serialization.json.Json
2018-12-26 08:07:24 +00:00
2020-11-17 10:06:25 +00:00
class KtorRequestsExecutorBuilder(
var telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
) {
var client: HttpClient = HttpClient()
var callsFactories: List<KtorCallFactory> = emptyList()
var excludeDefaultFactories: Boolean = false
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter()
var jsonFormatter: Json = nonstrictJsonFormat
fun build() = KtorRequestsExecutor(telegramAPIUrlsKeeper, client, callsFactories, excludeDefaultFactories, requestsLimiter, jsonFormatter)
}
inline fun telegramBot(
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
): TelegramBot = KtorRequestsExecutorBuilder(telegramAPIUrlsKeeper).apply(builder).build()
2020-11-17 10:18:58 +00:00
/**
* Shortcut for [telegramBot]
*/
@Suppress("NOTHING_TO_INLINE")
inline fun telegramBot(
token: String,
apiUrl: String = telegramBotAPIDefaultUrl,
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), builder)
2018-12-26 08:07:24 +00:00
class KtorRequestsExecutor(
2019-07-25 08:25:18 +00:00
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
2020-03-17 15:24:04 +00:00
client: HttpClient = HttpClient(),
2018-12-26 08:07:24 +00:00
callsFactories: List<KtorCallFactory> = emptyList(),
2019-01-24 02:36:44 +00:00
excludeDefaultFactories: Boolean = false,
2020-11-11 05:23:24 +00:00
private val requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter(),
2020-03-22 07:37:01 +00:00
private val jsonFormatter: Json = nonstrictJsonFormat
2019-07-25 08:25:18 +00:00
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
2018-12-26 08:07:24 +00:00
private val callsFactories: List<KtorCallFactory> = callsFactories.run {
if (!excludeDefaultFactories) {
this + listOf(SimpleRequestCallFactory(), MultipartRequestCallFactory(), DownloadFileRequestCallFactory)
2018-12-26 08:07:24 +00:00
} else {
this
}
}
2020-03-17 15:24:04 +00:00
private val client = client.config {
if (client.feature(HttpTimeout) == null) {
install(HttpTimeout)
}
2020-03-17 15:24:04 +00:00
}
2020-03-17 15:24:04 +00:00
override suspend fun <T : Any> execute(request: Request<T>): T {
return safely(
{ e ->
throw if (e is ClientRequestException) {
2021-01-09 13:00:41 +00:00
val content = e.response.readText()
2020-08-18 06:50:11 +00:00
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
newRequestException(
responseObject,
content,
"Can't get result object from $content"
)
} else {
e
}
}
) {
requestsLimiter.limit {
2020-08-23 15:43:58 +00:00
var result: T? = null
for (potentialFactory in callsFactories) {
result = potentialFactory.makeCall(
client,
2020-08-23 15:43:58 +00:00
telegramAPIUrlsKeeper,
request,
jsonFormatter
)
2020-08-23 15:43:58 +00:00
if (result != null) {
break
2019-12-13 17:54:02 +00:00
}
}
2020-03-17 15:24:04 +00:00
2020-08-23 15:43:58 +00:00
result ?: error("Can't execute request: $request")
2019-12-13 17:54:02 +00:00
}
2018-12-26 08:07:24 +00:00
}
}
2019-07-22 23:46:19 +00:00
override fun close() {
client.close()
}
2018-12-26 08:07:24 +00:00
}