From ece6a917ede9be8671d1a24cbced80753447dbbc Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 11 Apr 2022 11:59:37 +0600 Subject: [PATCH 1/8] start 0.38.13 --- CHANGELOG.md | 2 ++ gradle.properties | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9aff62aa7b..c880f4c995 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # TelegramBotAPI changelog +## 0.38.13 + ## 0.38.12 * `Common`: diff --git a/gradle.properties b/gradle.properties index b0173ec17b..bedc4306ce 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,6 +20,6 @@ javax_activation_version=1.1.1 dokka_version=1.6.10 library_group=dev.inmo -library_version=0.38.12 +library_version=0.38.13 github_release_plugin_version=2.2.12 From 863c872f35db125cc16e79343b0407adae494ab1 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 11 Apr 2022 12:46:33 +0600 Subject: [PATCH 2/8] start to add pipelines and fix mention creation --- CHANGELOG.md | 3 + .../inmo/tgbotapi/bot/Ktor/KtorCallFactory.kt | 1 + .../tgbotapi/bot/Ktor/KtorRequestsExecutor.kt | 15 ++++- .../bot/ktor/KtorPipelineStepsHolder.kt | 63 +++++++++++++++++++ .../textsources/TextMentionTextSource.kt | 7 ++- .../textsources/TextSourcesOrElse.kt | 17 +++++ 6 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextSourcesOrElse.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index c880f4c995..fc0eeb7b71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## 0.38.13 +* `Core`: + * Fixes in `mention` creation + ## 0.38.12 * `Common`: diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorCallFactory.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorCallFactory.kt index 859f7a4113..10d89d744c 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorCallFactory.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorCallFactory.kt @@ -1,5 +1,6 @@ package dev.inmo.tgbotapi.bot.Ktor +import dev.inmo.micro_utils.common.Optional import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper import io.ktor.client.HttpClient diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt index ebbc38bebb..16168229f7 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt @@ -5,6 +5,7 @@ import dev.inmo.tgbotapi.bot.BaseRequestsExecutor import dev.inmo.tgbotapi.bot.Ktor.base.* import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.exceptions.newRequestException +import dev.inmo.tgbotapi.bot.ktor.KtorPipelineStepsHolder import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter import dev.inmo.tgbotapi.requests.abstracts.Request @@ -56,7 +57,8 @@ class KtorRequestsExecutor( callsFactories: List = emptyList(), excludeDefaultFactories: Boolean = false, private val requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter(), - private val jsonFormatter: Json = nonstrictJsonFormat + private val jsonFormatter: Json = nonstrictJsonFormat, + private val pipelineStepsHolder: KtorPipelineStepsHolder = TODO() ) : BaseRequestsExecutor(telegramAPIUrlsKeeper) { private val callsFactories: List = callsFactories.run { if (!excludeDefaultFactories) { @@ -75,6 +77,8 @@ class KtorRequestsExecutor( override suspend fun execute(request: Request): T { return safely( { e -> + pipelineStepsHolder.onRequestException(request, e) ?.let { return@safely it } + throw if (e is ClientRequestException) { val content = e.response.readText() val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content) @@ -88,21 +92,28 @@ class KtorRequestsExecutor( } } ) { + pipelineStepsHolder.onBeforeSearchCallFactory(request, callsFactories) requestsLimiter.limit { var result: T? = null + lateinit var factoryHandledRequest: KtorCallFactory for (potentialFactory in callsFactories) { + pipelineStepsHolder.onBeforeCallFactoryMakeCall(request, potentialFactory) result = potentialFactory.makeCall( client, telegramAPIUrlsKeeper, request, jsonFormatter ) + result = pipelineStepsHolder.onAfterCallFactoryMakeCall(result, request, potentialFactory) if (result != null) { + factoryHandledRequest = potentialFactory break } } - result ?: error("Can't execute request: $request") + result ?.let { + pipelineStepsHolder.onRequestResultPresented(it, request, factoryHandledRequest, callsFactories) + } ?: pipelineStepsHolder.onRequestResultAbsent(request, callsFactories) ?: error("Can't execute request: $request") } } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt new file mode 100644 index 0000000000..f5b499e244 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt @@ -0,0 +1,63 @@ +package dev.inmo.tgbotapi.bot.ktor + +import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory +import dev.inmo.tgbotapi.requests.abstracts.Request + +interface KtorPipelineStepsHolder { + /** + * 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 + */ + suspend fun onRequestException( + request: Request, + t: Throwable + ): T? = null + + /** + * Will always be called before requests executor will check all [callsFactories] for an opportunity to make call of + * [request] + */ + suspend fun onBeforeSearchCallFactory( + request: Request<*>, + callsFactories: List + ) {} + + /** + * Will always be called before [potentialFactory] will try to make [request] + */ + suspend fun onBeforeCallFactoryMakeCall( + request: Request<*>, + potentialFactory: KtorCallFactory + ) {} + + /** + * Will always be called after [potentialFactory] has tried to make [request] and got some [result]. If returns + * value - that value will be returned from [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead + */ + suspend fun onAfterCallFactoryMakeCall( + result: T?, + request: Request, + potentialFactory: KtorCallFactory + ): T? = result + + /** + * Will be called when [resultCallFactory] is the [KtorCallFactory] from [callsFactories] which has successfully + * handled [request] and returned [result]. If returns value - that value will be returned from + * [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead + */ + suspend fun onRequestResultPresented( + result: T, + request: Request, + resultCallFactory: KtorCallFactory, + callsFactories: List + ): T? = result + + /** + * Will be called when there is no [KtorCallFactory] from [callsFactories] which may handle [request]. If returns + * value - that value will be returned from [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead + */ + suspend fun onRequestResultAbsent( + request: Request, + callsFactories: List + ): T? = null +} diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextMentionTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextMentionTextSource.kt index 495b18c2c9..359c296b3c 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextMentionTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextMentionTextSource.kt @@ -33,7 +33,12 @@ inline fun mention(parts: TextSourcesList, id: Identifier) = mention(parts, User @Suppress("NOTHING_TO_INLINE") inline fun Identifier.mention(parts: TextSourcesList) = mention(parts, this) @Suppress("NOTHING_TO_INLINE") -inline fun mention(user: User, vararg parts: TextSource) = mention(parts.toList(), user) +inline fun mention(user: User, vararg parts: TextSource) = mention( + textSourcesOrElseTextSource(parts.toList()) { + RegularTextSource("${user.lastName} ${user.firstName}") + }, + user +) @Suppress("NOTHING_TO_INLINE") inline fun mention(text: String, user: User) = mention(user, regular(text)) @Suppress("NOTHING_TO_INLINE") diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextSourcesOrElse.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextSourcesOrElse.kt new file mode 100644 index 0000000000..68643b5f34 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextSourcesOrElse.kt @@ -0,0 +1,17 @@ +package dev.inmo.tgbotapi.types.MessageEntity.textsources + +import dev.inmo.tgbotapi.utils.RiskFeature +import kotlin.js.JsName +import kotlin.jvm.JvmName + +@RiskFeature +inline fun textSourcesOrElse( + textSources: TextSourcesList, + block: () -> TextSourcesList +): TextSourcesList = textSources.takeIf { it.isNotEmpty() } ?: block() + +@RiskFeature +inline fun textSourcesOrElseTextSource( + textSources: TextSourcesList, + block: () -> TextSource +): TextSourcesList = textSources.takeIf { it.isNotEmpty() } ?: listOf(block()) From 81ad55b19f9b5db9a6ef63ea3ef1d3b0e9842c1f Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 11 Apr 2022 14:41:02 +0600 Subject: [PATCH 3/8] add KtorPipelineStepsHolder#onRequestReturnResult --- .../tgbotapi/bot/Ktor/KtorRequestsExecutor.kt | 77 ++++++++++--------- .../bot/ktor/KtorPipelineStepsHolder.kt | 16 +++- 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt index 16168229f7..c05d98fc14 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt @@ -75,46 +75,51 @@ class KtorRequestsExecutor( } override suspend fun execute(request: Request): T { - return safely( - { e -> - pipelineStepsHolder.onRequestException(request, e) ?.let { return@safely it } + return runCatching { + safely( + { e -> + pipelineStepsHolder.onRequestException(request, e) ?.let { return@safely it } - throw if (e is ClientRequestException) { - val content = e.response.readText() - val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content) - newRequestException( - responseObject, - content, - "Can't get result object from $content" - ) - } else { - e - } - } - ) { - pipelineStepsHolder.onBeforeSearchCallFactory(request, callsFactories) - requestsLimiter.limit { - var result: T? = null - lateinit var factoryHandledRequest: KtorCallFactory - for (potentialFactory in callsFactories) { - pipelineStepsHolder.onBeforeCallFactoryMakeCall(request, potentialFactory) - result = potentialFactory.makeCall( - client, - telegramAPIUrlsKeeper, - request, - jsonFormatter - ) - result = pipelineStepsHolder.onAfterCallFactoryMakeCall(result, request, potentialFactory) - if (result != null) { - factoryHandledRequest = potentialFactory - break + throw if (e is ClientRequestException) { + val content = e.response.readText() + val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content) + newRequestException( + responseObject, + content, + "Can't get result object from $content" + ) + } else { + e } - } - result ?.let { - pipelineStepsHolder.onRequestResultPresented(it, request, factoryHandledRequest, callsFactories) - } ?: pipelineStepsHolder.onRequestResultAbsent(request, callsFactories) ?: error("Can't execute request: $request") + } + ) { + pipelineStepsHolder.onBeforeSearchCallFactory(request, callsFactories) + requestsLimiter.limit { + var result: T? = null + lateinit var factoryHandledRequest: KtorCallFactory + for (potentialFactory in callsFactories) { + pipelineStepsHolder.onBeforeCallFactoryMakeCall(request, potentialFactory) + result = potentialFactory.makeCall( + client, + telegramAPIUrlsKeeper, + request, + jsonFormatter + ) + result = pipelineStepsHolder.onAfterCallFactoryMakeCall(result, request, potentialFactory) + if (result != null) { + factoryHandledRequest = potentialFactory + break + } + } + + result ?.let { + pipelineStepsHolder.onRequestResultPresented(it, request, factoryHandledRequest, callsFactories) + } ?: pipelineStepsHolder.onRequestResultAbsent(request, callsFactories) ?: error("Can't execute request: $request") + } } + }.let { + pipelineStepsHolder.onRequestReturnResult(it, request, callsFactories) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt index f5b499e244..b1e8eb9db5 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt @@ -34,7 +34,7 @@ interface KtorPipelineStepsHolder { * Will always be called after [potentialFactory] has tried to make [request] and got some [result]. If returns * value - that value will be returned from [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead */ - suspend fun onAfterCallFactoryMakeCall( + suspend fun onAfterCallFactoryMakeCall( result: T?, request: Request, potentialFactory: KtorCallFactory @@ -45,7 +45,7 @@ interface KtorPipelineStepsHolder { * handled [request] and returned [result]. If returns value - that value will be returned from * [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead */ - suspend fun onRequestResultPresented( + suspend fun onRequestResultPresented( result: T, request: Request, resultCallFactory: KtorCallFactory, @@ -56,8 +56,18 @@ interface KtorPipelineStepsHolder { * Will be called when there is no [KtorCallFactory] from [callsFactories] which may handle [request]. If returns * value - that value will be returned from [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead */ - suspend fun onRequestResultAbsent( + suspend fun onRequestResultAbsent( request: Request, callsFactories: List ): T? = null + + /** + * This step will be called when the [result] has been retrieved (or exception has happened). If returns value - + * that value will be returned from [dev.inmo.tgbotapi.bot.RequestsExecutor.execute] instead + */ + suspend fun onRequestReturnResult( + result: Result, + request: Request, + callsFactories: List + ): T = result.getOrThrow() } From 1089c716f3870ad1500968dc4f093d4a74d621c4 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 11 Apr 2022 21:00:56 +0600 Subject: [PATCH 4/8] deprecate StorageFileInfo --- CHANGELOG.md | 1 + .../tgbotapi/requests/abstracts/InputFile.kt | 4 +-- .../dev/inmo/tgbotapi/utils/StorageFile.kt | 30 +++++++++++++++---- .../inmo/tgbotapi/utils/StorageFileFactory.kt | 2 +- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc0eeb7b71..5e78c0d740 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * `Core`: * Fixes in `mention` creation + * Deprecate `StorageFileInfo` ## 0.38.12 diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt index 8c71b6c6c8..4e5949aa6d 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt @@ -61,9 +61,9 @@ object InputFileSerializer : KSerializer { @Serializable(InputFileSerializer::class) data class MultipartFile ( val file: StorageFile, - val filename: String = file.storageFileInfo.fileName + val filename: String = file.fileName ) : InputFile() { - override val fileId: String = file.storageFileInfo.generateCustomName() + override val fileId: String = file.generateCustomName() } @Suppress("NOTHING_TO_INLINE", "unused") diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/StorageFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/StorageFile.kt index 2296e232dd..a0dfe6e0ab 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/StorageFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/StorageFile.kt @@ -1,6 +1,8 @@ package dev.inmo.tgbotapi.utils import com.benasher44.uuid.uuid4 +import dev.inmo.micro_utils.common.MPPFile +import dev.inmo.micro_utils.common.filename import io.ktor.utils.io.* import io.ktor.utils.io.core.ByteReadPacket import io.ktor.utils.io.core.Input @@ -13,6 +15,7 @@ import kotlinx.serialization.Serializable * @param fileName This filename will be used in telegram system as name of file */ @Serializable +@Deprecated("Will be removed soon") data class StorageFileInfo( val fileName: String ) { @@ -25,18 +28,35 @@ data class StorageFileInfo( /** * Contains info about file, which potentially can be sent to telegram system. * - * @param storageFileInfo Information about this file + * @param fileName Filename * @param inputSource Lambda which able to allocate [Input] for uploading/manipulating data * * @see StorageFileInfo * @see asStorageFile */ data class StorageFile( - val storageFileInfo: StorageFileInfo, + val fileName: String, private val inputSource: () -> Input ) { val input: Input get() = inputSource() + @Deprecated("This field will be removed soon. Use fileName instead of StorageFileInfo") + val storageFileInfo: StorageFileInfo + get() = StorageFileInfo(fileName) + + /** + * This methods is required for random generation of name for keeping warranties about unique file name + */ + fun generateCustomName() = "${uuid4()}.${fileName.fileExtension}" + + @Deprecated("This constructor will be removed soon. Use constructor with fileName instead of StorageFileInfo") + constructor( + storageFileInfo: StorageFileInfo, + inputSource: () -> Input + ) : this( + storageFileInfo.fileName, + inputSource + ) } @Suppress("NOTHING_TO_INLINE") @@ -44,7 +64,7 @@ inline fun StorageFile( fileName: String, bytes: ByteArray ) = StorageFile( - StorageFileInfo(fileName) + fileName ) { ByteReadPacket(bytes) } @@ -54,8 +74,8 @@ suspend inline fun StorageFile( fileName: String, byteReadChannel: ByteReadChannel ) = StorageFile( - StorageFileInfo(fileName), - byteReadChannel.asInput().let { { it } } + fileName, + inputSource = byteReadChannel.asInput().let { { it } } ) @Suppress("NOTHING_TO_INLINE", "unused") diff --git a/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/StorageFileFactory.kt b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/StorageFileFactory.kt index 9d26befaeb..2ceb51562f 100644 --- a/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/StorageFileFactory.kt +++ b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/StorageFileFactory.kt @@ -7,7 +7,7 @@ import java.nio.file.Files fun StorageFile( file: File ) = StorageFile( - StorageFileInfo(file.name) + file.name ) { file.inputStream().asInput() } From a404a6c59cc31a3d8c02e46a0d0000fca61a1cbc Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 11 Apr 2022 21:56:47 +0600 Subject: [PATCH 5/8] fixes in DownloadFIleChannelRequestCallFactory --- .../base/DownloadFileChannelRequestCallFactory.kt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt index 3532ec5217..46cf0c1aec 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt @@ -1,6 +1,6 @@ package dev.inmo.tgbotapi.bot.Ktor.base -import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions +import dev.inmo.micro_utils.coroutines.* import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory import dev.inmo.tgbotapi.requests.DownloadFileStream import dev.inmo.tgbotapi.requests.abstracts.Request @@ -25,13 +25,16 @@ object DownloadFileChannelRequestCallFactory : KtorCallFactory { val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath) ByteReadChannelAllocator { - val scope = CoroutineScope(coroutineContext) + val scope = CoroutineScope(currentCoroutineContext() + SupervisorJob()) val outChannel = ByteChannel() - scope.launchSafelyWithoutExceptions { - client.get(fullUrl).execute { httpResponse -> - val channel: ByteReadChannel = httpResponse.receive() - channel.copyAndClose(outChannel) + scope.launch { + runCatchingSafely { + client.get(fullUrl).execute { httpResponse -> + val channel: ByteReadChannel = httpResponse.receive() + channel.copyAndClose(outChannel) + } } + scope.cancel() } outChannel } as T From 08ef146daa771bb72d9b62db684a9d16880c6d7e Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 13 Apr 2022 23:12:32 +0600 Subject: [PATCH 6/8] Update gradle.properties --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index bedc4306ce..d4204d7431 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ klock_version=2.7.0 uuid_version=0.4.0 ktor_version=1.6.8 -micro_utils_version=0.9.19 +micro_utils_version=0.9.20 javax_activation_version=1.1.1 From ff2d1615dabcd6afc99a59a723ba3cdb3de4bdf8 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sat, 16 Apr 2022 23:58:24 +0600 Subject: [PATCH 7/8] replace TODO for pipelineStepsHolder with default realization --- .../kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt | 2 +- .../dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt index c05d98fc14..c168c982c5 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt @@ -58,7 +58,7 @@ class KtorRequestsExecutor( excludeDefaultFactories: Boolean = false, private val requestsLimiter: RequestLimiter = ExceptionsOnlyLimiter(), private val jsonFormatter: Json = nonstrictJsonFormat, - private val pipelineStepsHolder: KtorPipelineStepsHolder = TODO() + private val pipelineStepsHolder: KtorPipelineStepsHolder = KtorPipelineStepsHolder ) : BaseRequestsExecutor(telegramAPIUrlsKeeper) { private val callsFactories: List = callsFactories.run { if (!excludeDefaultFactories) { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt index b1e8eb9db5..725a2a8bc6 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/ktor/KtorPipelineStepsHolder.kt @@ -70,4 +70,6 @@ interface KtorPipelineStepsHolder { request: Request, callsFactories: List ): T = result.getOrThrow() + + companion object : KtorPipelineStepsHolder } From a87c21273d653e11a7d4da9820345f75b6283bcd Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sun, 17 Apr 2022 00:22:00 +0600 Subject: [PATCH 8/8] BehaviourContext#on*Message extensions --- CHANGELOG.md | 2 + .../expectations/WaitContent.kt | 7 +- .../expectations/WaitContentMessage.kt | 281 ++++++++++++++++++ .../triggers_handling/ContentTriggers.kt | 50 ++-- 4 files changed, 312 insertions(+), 28 deletions(-) create mode 100644 tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContentMessage.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e78c0d740..6b177dc752 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ * `Core`: * Fixes in `mention` creation * Deprecate `StorageFileInfo` +* `BehaviourBuilder`: + * In the expectations a lot of `on*Message` extensions have been added (like `onContentMessage`). These extensions could be useful when with the `Content` its message info is important ## 0.38.12 diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContent.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContent.kt index 44dbd7d524..5960fd0c4a 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContent.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContent.kt @@ -23,7 +23,7 @@ import kotlinx.coroutines.flow.toList typealias CommonMessageToContentMapper = suspend CommonMessage.() -> T? -private suspend fun BehaviourContext.waitCommonMessage( +private suspend fun BehaviourContext.waitCommonContent( count: Int = 1, initRequest: Request<*>? = null, includeMediaGroups: Boolean = true, @@ -77,7 +77,7 @@ private suspend inline fun BehaviourContext.waitCon noinline errorFactory: NullableRequestBuilder<*> = { null }, noinline filter: SimpleFilter>? = null, noinline mapper: CommonMessageToContentMapper? = null -) : List = waitCommonMessage( +) : List = waitCommonContent( count, initRequest, includeMediaGroups, @@ -90,7 +90,8 @@ private suspend inline fun BehaviourContext.waitCon contentConverter(mapper) ).toList() -suspend fun BehaviourContext.waitContentMessage( + +suspend fun BehaviourContext.waitContent( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContentMessage.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContentMessage.kt new file mode 100644 index 0000000000..914087e158 --- /dev/null +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContentMessage.kt @@ -0,0 +1,281 @@ +@file:Suppress("unused") + +package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations + +import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions +import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext +import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter +import dev.inmo.tgbotapi.extensions.utils.withContent +import dev.inmo.tgbotapi.requests.abstracts.Request +import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage +import dev.inmo.tgbotapi.types.message.content.* +import dev.inmo.tgbotapi.types.message.content.abstracts.* +import dev.inmo.tgbotapi.types.message.content.media.* +import dev.inmo.tgbotapi.types.message.content.media.AudioMediaGroupContent +import dev.inmo.tgbotapi.types.message.content.media.DocumentMediaGroupContent +import dev.inmo.tgbotapi.types.message.content.media.MediaGroupContent +import dev.inmo.tgbotapi.types.message.content.media.VisualMediaGroupContent +import dev.inmo.tgbotapi.types.message.payments.InvoiceContent +import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate +import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.toList + +typealias CommonMessageToCommonMessageMapper = suspend CommonMessage.() -> CommonMessage? + +internal suspend fun BehaviourContext.waitCommonMessage( + count: Int = 1, + initRequest: Request<*>? = null, + includeMediaGroups: Boolean = true, + errorFactory: NullableRequestBuilder<*> = { null }, + filter: SimpleFilter>? = null, + mapper: suspend CommonMessage.() -> CommonMessage? +): Flow> = expectFlow( + initRequest, + count, + errorFactory +) { + val messages = when (it) { + is SentMediaGroupUpdate -> { + if (includeMediaGroups) { + it.data.map { it as CommonMessage } + } else { + emptyList() + } + } + is BaseSentMessageUpdate -> listOf(it.data) + else -> return@expectFlow emptyList() + } + messages.mapNotNull { message -> + val asCommonMessage = message as CommonMessage + if (filter == null || filter(asCommonMessage)) { + asCommonMessage.mapper() + } else { + null + } + } +} + +internal inline fun contentMessageConverter( + noinline mapper: CommonMessageToCommonMessageMapper? = null +): suspend CommonMessage.() -> CommonMessage? = mapper ?.let { + { + if (content is T) { + @Suppress("UNCHECKED_CAST") + val message = (this as CommonMessage) + safelyWithoutExceptions { mapper(message) } + } else { + null + } + } +} ?: { + @Suppress("UNCHECKED_CAST") + if (content is T) this as CommonMessage else null +} + +private suspend inline fun BehaviourContext.waitContentMessage( + count: Int = 1, + initRequest: Request<*>? = null, + includeMediaGroups: Boolean = true, + noinline errorFactory: NullableRequestBuilder<*> = { null }, + noinline filter: SimpleFilter>? = null, + noinline mapper: CommonMessageToCommonMessageMapper? = null +) : List> = waitCommonMessage( + count, + initRequest, + includeMediaGroups, + errorFactory, + filter ?.let { + { + it.withContent() ?.let { filter(it) } == true + } + }, + contentMessageConverter(mapper) +).toList() + +suspend fun BehaviourContext.waitContentMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = true, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitContactMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitDiceMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitGameMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitLocationMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitLiveLocationMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitStaticLocationMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitPollMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitTextMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitVenueMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitAudioMediaGroupContentMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = true, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitDocumentMediaGroupContentMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = true, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitMediaMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = false, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitAnyMediaGroupContentMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = true, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitVisualMediaGroupContentMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = true, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitTextedMediaContentMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = true, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitAnimationMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitAudioMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = false, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitDocumentMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = false, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitPhotoMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = false, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitStickerMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitVideoMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + includeMediaGroups: Boolean = false, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, includeMediaGroups, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitVideoNoteMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitVoiceMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitInvoiceMessage( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: CommonMessageToCommonMessageMapper? = null +) = waitContentMessage(count, initRequest, false, errorFactory, filter, mapper) diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ContentTriggers.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ContentTriggers.kt index d6d0b019d2..4f51259fb4 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ContentTriggers.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/ContentTriggers.kt @@ -24,7 +24,7 @@ import dev.inmo.tgbotapi.types.update.abstracts.Update typealias CommonMessageFilter = SimpleFilter> inline fun CommonMessageFilter(noinline block: CommonMessageFilter) = block -internal suspend inline fun BC.onContent( +internal suspend inline fun BC.onContentMessageWithType( noinline initialFilter: CommonMessageFilter? = null, noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update>? = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, @@ -57,7 +57,7 @@ suspend fun BC.onContentMessage( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -81,7 +81,7 @@ suspend fun BC.onContact( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -105,7 +105,7 @@ suspend fun BC.onDice( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -129,7 +129,7 @@ suspend fun BC.onGame( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -153,7 +153,7 @@ suspend fun BC.onLocation( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -177,7 +177,7 @@ suspend fun BC.onLiveLocation( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -201,7 +201,7 @@ suspend fun BC.onStaticLocation( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -225,7 +225,7 @@ suspend fun BC.onPoll( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -249,7 +249,7 @@ suspend fun BC.onText( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -273,7 +273,7 @@ suspend fun BC.onVenue( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -297,7 +297,7 @@ suspend fun BC.onAudioMediaGroup( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -321,7 +321,7 @@ suspend fun BC.onDocumentMediaGroupContent( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -345,7 +345,7 @@ suspend fun BC.onTextedMediaContent( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -369,7 +369,7 @@ suspend fun BC.onMediaCollection( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver>, Update> = MessageFilterByChat, markerFactory: MarkerFactory>, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver>> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -393,7 +393,7 @@ suspend fun BC.onMedia( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -417,7 +417,7 @@ suspend fun BC.onAnimation( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -441,7 +441,7 @@ suspend fun BC.onAudio( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -465,7 +465,7 @@ suspend fun BC.onDocument( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -489,7 +489,7 @@ suspend fun BC.onPhoto( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -513,7 +513,7 @@ suspend fun BC.onSticker( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -537,7 +537,7 @@ suspend fun BC.onVideo( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -561,7 +561,7 @@ suspend fun BC.onVideoNote( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -585,7 +585,7 @@ suspend fun BC.onVoice( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory, @@ -609,7 +609,7 @@ suspend fun BC.onInvoice( subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver, Update> = MessageFilterByChat, markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: CustomBehaviourContextAndTypeReceiver> -) = onContent( +) = onContentMessageWithType( initialFilter, subcontextUpdatesFilter, markerFactory,