mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-11-22 00:03:48 +00:00
start adding middlewares
This commit is contained in:
parent
7398e53b85
commit
a7f4ab36c6
@ -24,7 +24,7 @@ expect class KtorRequestsExecutor internal constructor(
|
|||||||
excludeDefaultFactories: Boolean,
|
excludeDefaultFactories: Boolean,
|
||||||
requestsLimiter: RequestLimiter,
|
requestsLimiter: RequestLimiter,
|
||||||
jsonFormatter: Json,
|
jsonFormatter: Json,
|
||||||
pipelineStepsHolder: KtorPipelineStepsHolder,
|
pipelineStepsHolder: TelegramBotPipelinesHandler,
|
||||||
logger: KSLog,
|
logger: KSLog,
|
||||||
diff: Unit // just a diff property to know where constructor and where calling function with defaults
|
diff: Unit // just a diff property to know where constructor and where calling function with defaults
|
||||||
) : BaseRequestsExecutor {
|
) : BaseRequestsExecutor {
|
||||||
@ -39,7 +39,7 @@ fun KtorRequestsExecutor(
|
|||||||
excludeDefaultFactories: Boolean = false,
|
excludeDefaultFactories: Boolean = false,
|
||||||
requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter,
|
requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter,
|
||||||
jsonFormatter: Json = nonstrictJsonFormat,
|
jsonFormatter: Json = nonstrictJsonFormat,
|
||||||
pipelineStepsHolder: KtorPipelineStepsHolder = KtorPipelineStepsHolder,
|
pipelineStepsHolder: TelegramBotPipelinesHandler = TelegramBotPipelinesHandler,
|
||||||
logger: KSLog = DefaultKTgBotAPIKSLog,
|
logger: KSLog = DefaultKTgBotAPIKSLog,
|
||||||
) = KtorRequestsExecutor(
|
) = KtorRequestsExecutor(
|
||||||
telegramAPIUrlsKeeper = telegramAPIUrlsKeeper,
|
telegramAPIUrlsKeeper = telegramAPIUrlsKeeper,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package dev.inmo.tgbotapi.bot.ktor
|
package dev.inmo.tgbotapi.bot.ktor
|
||||||
|
|
||||||
import dev.inmo.kslog.common.KSLog
|
import dev.inmo.kslog.common.KSLog
|
||||||
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.bot.ktor.base.*
|
import dev.inmo.tgbotapi.bot.ktor.base.*
|
||||||
import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter
|
import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter
|
||||||
@ -27,7 +26,7 @@ class KtorRequestsExecutorBuilder(
|
|||||||
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter
|
var requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter
|
||||||
var jsonFormatter: Json = nonstrictJsonFormat
|
var jsonFormatter: Json = nonstrictJsonFormat
|
||||||
var logger: KSLog = DefaultKTgBotAPIKSLog
|
var logger: KSLog = DefaultKTgBotAPIKSLog
|
||||||
var pipelineStepsHolder: KtorPipelineStepsHolder = KtorPipelineStepsHolder
|
var pipelineStepsHolder: TelegramBotPipelinesHandler = TelegramBotPipelinesHandler
|
||||||
|
|
||||||
fun build() = KtorRequestsExecutor(
|
fun build() = KtorRequestsExecutor(
|
||||||
telegramAPIUrlsKeeper,
|
telegramAPIUrlsKeeper,
|
||||||
|
@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.bot.ktor
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
|
|
||||||
interface KtorPipelineStepsHolder {
|
interface TelegramBotPipelinesHandler {
|
||||||
/**
|
/**
|
||||||
* Will be called when any exception will happen due to the [request] handling. If returns value - that value
|
* Will be called when any exception will happen due to the [request] handling. If returns value - that value
|
||||||
* will be returned from [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead
|
* will be returned from [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead
|
||||||
@ -68,7 +68,10 @@ interface KtorPipelineStepsHolder {
|
|||||||
result: Result<T>,
|
result: Result<T>,
|
||||||
request: Request<T>,
|
request: Request<T>,
|
||||||
callsFactories: List<KtorCallFactory>
|
callsFactories: List<KtorCallFactory>
|
||||||
): T = result.getOrThrow()
|
): Result<T> = result.getOrThrow()
|
||||||
|
|
||||||
companion object : KtorPipelineStepsHolder
|
companion object : TelegramBotPipelinesHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Renamed", ReplaceWith("TelegramBotPipelinesHandler", "dev.inmo.tgbotapi.bot.ktor.TelegramBotPipelinesHandler"))
|
||||||
|
typealias KtorPipelineStepsHolder = TelegramBotPipelinesHandler
|
@ -1,7 +1,6 @@
|
|||||||
package dev.inmo.tgbotapi.bot.ktor.base
|
package dev.inmo.tgbotapi.bot.ktor.base
|
||||||
|
|
||||||
import dev.inmo.kslog.common.*
|
import dev.inmo.kslog.common.*
|
||||||
import dev.inmo.micro_utils.coroutines.defaultSafelyExceptionHandler
|
|
||||||
import dev.inmo.micro_utils.coroutines.runCatchingSafely
|
import dev.inmo.micro_utils.coroutines.runCatchingSafely
|
||||||
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
||||||
import dev.inmo.tgbotapi.bot.exceptions.BotException
|
import dev.inmo.tgbotapi.bot.exceptions.BotException
|
||||||
@ -9,15 +8,12 @@ import dev.inmo.tgbotapi.bot.exceptions.CommonBotException
|
|||||||
import dev.inmo.tgbotapi.bot.exceptions.GetUpdatesConflict
|
import dev.inmo.tgbotapi.bot.exceptions.GetUpdatesConflict
|
||||||
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
|
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
|
||||||
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
|
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
|
||||||
import dev.inmo.tgbotapi.bot.ktor.KtorPipelineStepsHolder
|
import dev.inmo.tgbotapi.bot.ktor.TelegramBotPipelinesHandler
|
||||||
import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutor
|
|
||||||
import dev.inmo.tgbotapi.bot.ktor.createTelegramBotDefaultKtorCallRequestsFactories
|
import dev.inmo.tgbotapi.bot.ktor.createTelegramBotDefaultKtorCallRequestsFactories
|
||||||
import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter
|
|
||||||
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
|
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.types.Response
|
import dev.inmo.tgbotapi.types.Response
|
||||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||||
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
|
|
||||||
import io.ktor.client.*
|
import io.ktor.client.*
|
||||||
import io.ktor.client.plugins.*
|
import io.ktor.client.plugins.*
|
||||||
import io.ktor.client.statement.*
|
import io.ktor.client.statement.*
|
||||||
@ -30,7 +26,7 @@ class DefaultKtorRequestsExecutor internal constructor(
|
|||||||
excludeDefaultFactories: Boolean,
|
excludeDefaultFactories: Boolean,
|
||||||
private val requestsLimiter: RequestLimiter,
|
private val requestsLimiter: RequestLimiter,
|
||||||
private val jsonFormatter: Json,
|
private val jsonFormatter: Json,
|
||||||
private val pipelineStepsHolder: KtorPipelineStepsHolder,
|
private val pipelineStepsHolder: TelegramBotPipelinesHandler,
|
||||||
private val logger: KSLog,
|
private val logger: KSLog,
|
||||||
diff: Unit
|
diff: Unit
|
||||||
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
|
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
|
||||||
@ -110,7 +106,7 @@ class DefaultKtorRequestsExecutor internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ?.let { Result.failure(it) } ?: it
|
} ?.let { Result.failure(it) } ?: it
|
||||||
pipelineStepsHolder.onRequestReturnResult(result, request, callsFactories).also {
|
pipelineStepsHolder.onRequestReturnResult(result, request, callsFactories).getOrThrow().also {
|
||||||
logger.v { "Result of handling $request: $it" }
|
logger.v { "Result of handling $request: $it" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,10 @@ import dev.inmo.kslog.common.KSLog
|
|||||||
import dev.inmo.micro_utils.coroutines.runCatchingSafely
|
import dev.inmo.micro_utils.coroutines.runCatchingSafely
|
||||||
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
||||||
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
|
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
|
||||||
import dev.inmo.tgbotapi.bot.ktor.KtorPipelineStepsHolder
|
import dev.inmo.tgbotapi.bot.ktor.TelegramBotPipelinesHandler
|
||||||
import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutor
|
|
||||||
import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter
|
|
||||||
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
|
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||||
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
|
|
||||||
import io.ktor.client.*
|
import io.ktor.client.*
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
@ -47,7 +44,7 @@ class MultipleClientKtorRequestsExecutor (
|
|||||||
excludeDefaultFactories: Boolean,
|
excludeDefaultFactories: Boolean,
|
||||||
requestsLimiter: RequestLimiter,
|
requestsLimiter: RequestLimiter,
|
||||||
jsonFormatter: Json,
|
jsonFormatter: Json,
|
||||||
pipelineStepsHolder: KtorPipelineStepsHolder,
|
pipelineStepsHolder: TelegramBotPipelinesHandler,
|
||||||
requestExecutorsCount: Int,
|
requestExecutorsCount: Int,
|
||||||
logger: KSLog,
|
logger: KSLog,
|
||||||
clientFactory: () -> HttpClient
|
clientFactory: () -> HttpClient
|
||||||
@ -82,7 +79,7 @@ class MultipleClientKtorRequestsExecutor (
|
|||||||
excludeDefaultFactories: Boolean,
|
excludeDefaultFactories: Boolean,
|
||||||
requestsLimiter: RequestLimiter,
|
requestsLimiter: RequestLimiter,
|
||||||
jsonFormatter: Json,
|
jsonFormatter: Json,
|
||||||
pipelineStepsHolder: KtorPipelineStepsHolder,
|
pipelineStepsHolder: TelegramBotPipelinesHandler,
|
||||||
logger: KSLog,
|
logger: KSLog,
|
||||||
diff: Unit
|
diff: Unit
|
||||||
) : this(
|
) : this(
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
package dev.inmo.tgbotapi.bot.ktor.middlewares
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
|
||||||
|
import dev.inmo.tgbotapi.bot.ktor.TelegramBotPipelinesHandler
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
|
|
||||||
|
class TelegramBotMiddleware(
|
||||||
|
internal val onRequestException: (suspend (request: Request<*>, t: Throwable?) -> Any?)? = null,
|
||||||
|
internal val onBeforeSearchCallFactory: (suspend (request: Request<*>, callsFactories: List<KtorCallFactory>) -> Unit)? = null,
|
||||||
|
internal val onBeforeCallFactoryMakeCall: (suspend (request: Request<*>, potentialFactory: KtorCallFactory) -> Unit)? = null,
|
||||||
|
internal val onAfterCallFactoryMakeCall: (suspend (result: Any?, request: Request<*>, potentialFactory: KtorCallFactory) -> Any?)? = null,
|
||||||
|
internal val onRequestResultPresented: (suspend (result: Any?, request: Request<*>, resultCallFactory: KtorCallFactory, callsFactories: List<KtorCallFactory>) -> Any?)? = null,
|
||||||
|
internal val onRequestResultAbsent: (suspend (request: Request<*>, callsFactories: List<KtorCallFactory>) -> Any?)? = null,
|
||||||
|
internal val onRequestReturnResult: (suspend (result: Result<*>, request: Request<*>, callsFactories: List<KtorCallFactory>) -> Result<Any?>?)? = null,
|
||||||
|
) : TelegramBotPipelinesHandler {
|
||||||
|
object ResultAbsence : Throwable()
|
||||||
|
override suspend fun <T : Any> onRequestException(request: Request<T>, t: Throwable): T? {
|
||||||
|
return onRequestException ?.invoke(request, t) as? T
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onBeforeSearchCallFactory(request: Request<*>, callsFactories: List<KtorCallFactory>) {
|
||||||
|
onBeforeSearchCallFactory ?.invoke(request, callsFactories)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onBeforeCallFactoryMakeCall(request: Request<*>, potentialFactory: KtorCallFactory) {
|
||||||
|
onBeforeCallFactoryMakeCall ?.invoke(request, potentialFactory)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun <T : Any> onAfterCallFactoryMakeCall(
|
||||||
|
result: T?,
|
||||||
|
request: Request<T>,
|
||||||
|
potentialFactory: KtorCallFactory
|
||||||
|
): T? {
|
||||||
|
return onAfterCallFactoryMakeCall ?.invoke(result, request, potentialFactory) as? T
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun <T : Any> onRequestResultPresented(
|
||||||
|
result: T,
|
||||||
|
request: Request<T>,
|
||||||
|
resultCallFactory: KtorCallFactory,
|
||||||
|
callsFactories: List<KtorCallFactory>
|
||||||
|
): T? {
|
||||||
|
return onRequestResultPresented ?.invoke(result, request, resultCallFactory, callsFactories) as? T
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun <T : Any> onRequestResultAbsent(
|
||||||
|
request: Request<T>,
|
||||||
|
callsFactories: List<KtorCallFactory>
|
||||||
|
): T? {
|
||||||
|
return onRequestResultAbsent ?.invoke(request, callsFactories) as? T
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun <T : Any> onRequestReturnResult(
|
||||||
|
result: Result<T>,
|
||||||
|
request: Request<T>,
|
||||||
|
callsFactories: List<KtorCallFactory>
|
||||||
|
): Result<T> {
|
||||||
|
return onRequestReturnResult ?.invoke(result, request, callsFactories) as? Result<T> ?: Result.failure(ResultAbsence)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun build(block: TelegramBotMiddlewareBuilder.() -> Unit): TelegramBotMiddleware = TelegramBotMiddlewareBuilder().apply(block).build()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package dev.inmo.tgbotapi.bot.ktor.middlewares
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
|
||||||
|
import dev.inmo.tgbotapi.bot.ktor.TelegramBotPipelinesHandler
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
|
|
||||||
|
class TelegramBotMiddlewareBuilder {
|
||||||
|
var onRequestException: (suspend (request: Request<*>, t: Throwable?) -> Any?)? = null
|
||||||
|
var onBeforeSearchCallFactory: (suspend (request: Request<*>, callsFactories: List<KtorCallFactory>) -> Unit)? = null
|
||||||
|
var onBeforeCallFactoryMakeCall: (suspend (request: Request<*>, potentialFactory: KtorCallFactory) -> Unit)? = null
|
||||||
|
var onAfterCallFactoryMakeCall: (suspend (result: Any?, request: Request<*>, potentialFactory: KtorCallFactory) -> Any?)? = null
|
||||||
|
var onRequestResultPresented: (suspend (result: Any?, request: Request<*>, resultCallFactory: KtorCallFactory, callsFactories: List<KtorCallFactory>) -> Any?)? = null
|
||||||
|
var onRequestResultAbsent: (suspend (request: Request<*>, callsFactories: List<KtorCallFactory>) -> Any?)? = null
|
||||||
|
var onRequestReturnResult: (suspend (result: Result<*>, request: Request<*>, callsFactories: List<KtorCallFactory>) -> Result<Any?>?)? = null
|
||||||
|
|
||||||
|
|
||||||
|
fun build(): TelegramBotMiddleware {
|
||||||
|
return TelegramBotMiddleware(
|
||||||
|
onRequestException = onRequestException,
|
||||||
|
onBeforeSearchCallFactory = onBeforeSearchCallFactory,
|
||||||
|
onBeforeCallFactoryMakeCall = onBeforeCallFactoryMakeCall,
|
||||||
|
onAfterCallFactoryMakeCall = onAfterCallFactoryMakeCall,
|
||||||
|
onRequestResultPresented = onRequestResultPresented,
|
||||||
|
onRequestResultAbsent = onRequestResultAbsent,
|
||||||
|
onRequestReturnResult = onRequestReturnResult
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun from(middleware: TelegramBotMiddleware, additionalSetup: TelegramBotMiddlewareBuilder.() -> Unit): TelegramBotMiddleware {
|
||||||
|
return TelegramBotMiddlewareBuilder().apply {
|
||||||
|
onRequestException = middleware.onRequestException
|
||||||
|
onBeforeSearchCallFactory = middleware.onBeforeSearchCallFactory
|
||||||
|
onBeforeCallFactoryMakeCall = middleware.onBeforeCallFactoryMakeCall
|
||||||
|
onAfterCallFactoryMakeCall = middleware.onAfterCallFactoryMakeCall
|
||||||
|
onRequestResultPresented = middleware.onRequestResultPresented
|
||||||
|
onRequestResultAbsent = middleware.onRequestResultAbsent
|
||||||
|
onRequestReturnResult = middleware.onRequestReturnResult
|
||||||
|
additionalSetup()
|
||||||
|
}.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package dev.inmo.tgbotapi.bot.ktor.middlewares
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
|
||||||
|
import dev.inmo.tgbotapi.bot.ktor.TelegramBotPipelinesHandler
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
|
|
||||||
|
class TelegramBotMiddlewaresPipelinesHandler(
|
||||||
|
private val middlewares: List<TelegramBotMiddleware>
|
||||||
|
) : TelegramBotPipelinesHandler {
|
||||||
|
override suspend fun <T : Any> onRequestException(request: Request<T>, t: Throwable): T? {
|
||||||
|
return super.onRequestException(request, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onBeforeSearchCallFactory(request: Request<*>, callsFactories: List<KtorCallFactory>) {
|
||||||
|
super.onBeforeSearchCallFactory(request, callsFactories)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onBeforeCallFactoryMakeCall(request: Request<*>, potentialFactory: KtorCallFactory) {
|
||||||
|
super.onBeforeCallFactoryMakeCall(request, potentialFactory)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun <T : Any> onAfterCallFactoryMakeCall(
|
||||||
|
result: T?,
|
||||||
|
request: Request<T>,
|
||||||
|
potentialFactory: KtorCallFactory
|
||||||
|
): T? {
|
||||||
|
return super.onAfterCallFactoryMakeCall(result, request, potentialFactory)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun <T : Any> onRequestResultPresented(
|
||||||
|
result: T,
|
||||||
|
request: Request<T>,
|
||||||
|
resultCallFactory: KtorCallFactory,
|
||||||
|
callsFactories: List<KtorCallFactory>
|
||||||
|
): T? {
|
||||||
|
return super.onRequestResultPresented(result, request, resultCallFactory, callsFactories)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun <T : Any> onRequestResultAbsent(
|
||||||
|
request: Request<T>,
|
||||||
|
callsFactories: List<KtorCallFactory>
|
||||||
|
): T? {
|
||||||
|
return super.onRequestResultAbsent(request, callsFactories)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun <T : Any> onRequestReturnResult(
|
||||||
|
result: Result<T>,
|
||||||
|
request: Request<T>,
|
||||||
|
callsFactories: List<KtorCallFactory>
|
||||||
|
): Result<T> {
|
||||||
|
return super.onRequestReturnResult(result, request, callsFactories)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user