From 83304023a602751c228b9c2a62edeeca026bf3ef Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 8 Sep 2021 19:57:22 +0600 Subject: [PATCH 1/7] start 0.35.8 --- CHANGELOG.md | 2 ++ gradle.properties | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f206cda756..9e22ead329 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # TelegramBotAPI changelog +## 0.35.8 + ## 0.35.7 * `Common`: diff --git a/gradle.properties b/gradle.properties index e22eff9a7a..e6d1b3b47c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,6 +17,6 @@ micro_utils_version=0.5.24 javax_activation_version=1.1.1 library_group=dev.inmo -library_version=0.35.7 +library_version=0.35.8 github_release_plugin_version=2.2.12 From 3a61b522ab28f09af75031ba60de403c4c00ccad Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 8 Sep 2021 19:59:29 +0600 Subject: [PATCH 2/7] update dependencies --- CHANGELOG.md | 5 +++++ gradle.properties | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e22ead329..2902c4104e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## 0.35.8 +* `Common`: + * `Version`: + * `MicroUtils`: `0.5.24` -> `0.5.25` + * `UUID`: `0.3.0` -> `0.3.1` + ## 0.35.7 * `Common`: diff --git a/gradle.properties b/gradle.properties index e6d1b3b47c..b6933b5929 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,10 +9,10 @@ kotlin_version=1.5.30 kotlin_coroutines_version=1.5.2 kotlin_serialisation_runtime_version=1.2.2 klock_version=2.4.1 -uuid_version=0.3.0 +uuid_version=0.3.1 ktor_version=1.6.3 -micro_utils_version=0.5.24 +micro_utils_version=0.5.25 javax_activation_version=1.1.1 From 5d6ba0f59e9bc42d1c5790c0999c9a0a1db10c94 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 8 Sep 2021 20:05:53 +0600 Subject: [PATCH 3/7] MultipartRequestCallFactory improvements --- CHANGELOG.md | 3 +++ .../inmo/tgbotapi/bot/Ktor/base/MultipartRequestCallFactory.kt | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2902c4104e..b7b09333cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ * `Version`: * `MicroUtils`: `0.5.24` -> `0.5.25` * `UUID`: `0.3.0` -> `0.3.1` +* `Core`: + * `MultipartRequestCallFactory` now will use file name as multipart `filename` parameter instead of generated + filename ## 0.35.7 diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/MultipartRequestCallFactory.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/MultipartRequestCallFactory.kt index 2d42d15ea9..fab01c75fb 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/MultipartRequestCallFactory.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/MultipartRequestCallFactory.kt @@ -24,7 +24,7 @@ class MultipartRequestCallFactory : AbstractRequestCallFactory() { is MultipartFile -> appendInput( key, Headers.build { - append(HttpHeaders.ContentDisposition, "filename=${value.fileId}") + append(HttpHeaders.ContentDisposition, "filename=${value.filename}") }, block = value.file::input ) From 807952201b451b228e923cb263d59f62f07805cf Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 8 Sep 2021 20:58:44 +0600 Subject: [PATCH 4/7] MPPFile#asMultipartFile --- CHANGELOG.md | 1 + .../dev/inmo/tgbotapi/requests/abstracts/InputFile.kt | 4 ++++ .../requests/abstracts/MPPFileMultipartFileActual.kt | 8 ++++++++ .../requests/abstracts/MPPFileMultipartFileActual.kt | 5 +++++ 4 files changed, 18 insertions(+) create mode 100644 tgbotapi.core/src/jsMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/MPPFileMultipartFileActual.kt create mode 100644 tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/MPPFileMultipartFileActual.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index b7b09333cd..65be07c582 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * `Core`: * `MultipartRequestCallFactory` now will use file name as multipart `filename` parameter instead of generated filename + * New extension `MPPFile#asMultipartFile` ## 0.35.7 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 b306112118..027b2effa7 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 @@ -1,7 +1,9 @@ package dev.inmo.tgbotapi.requests.abstracts +import dev.inmo.micro_utils.common.MPPFile import dev.inmo.tgbotapi.utils.* import io.ktor.utils.io.ByteReadChannel +import io.ktor.utils.io.core.Input import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.* @@ -75,3 +77,5 @@ suspend inline fun ByteReadChannel.asMultipartFile( suspend inline fun ByteReadChannelAllocator.asMultipartFile( fileName: String ) = this.invoke().asMultipartFile(fileName) + +expect suspend fun MPPFile.asMultipartFile(): MultipartFile diff --git a/tgbotapi.core/src/jsMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/MPPFileMultipartFileActual.kt b/tgbotapi.core/src/jsMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/MPPFileMultipartFileActual.kt new file mode 100644 index 0000000000..b3cd16f998 --- /dev/null +++ b/tgbotapi.core/src/jsMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/MPPFileMultipartFileActual.kt @@ -0,0 +1,8 @@ +package dev.inmo.tgbotapi.requests.abstracts + +import dev.inmo.micro_utils.common.* +import io.ktor.utils.io.ByteReadChannel + +actual suspend fun MPPFile.asMultipartFile(): MultipartFile = ByteReadChannel(bytes()).asMultipartFile( + filename.name +) diff --git a/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/MPPFileMultipartFileActual.kt b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/MPPFileMultipartFileActual.kt new file mode 100644 index 0000000000..bc2ab9874e --- /dev/null +++ b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/MPPFileMultipartFileActual.kt @@ -0,0 +1,5 @@ +package dev.inmo.tgbotapi.requests.abstracts + +import dev.inmo.micro_utils.common.MPPFile + +actual suspend fun MPPFile.asMultipartFile(): MultipartFile = toInputFile() From ee81f49a750b5fc9bb4050947419d5db857b72ce Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 8 Sep 2021 21:13:42 +0600 Subject: [PATCH 5/7] add docs for InputFile --- .../dev/inmo/tgbotapi/requests/abstracts/InputFile.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) 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 027b2effa7..834437b25f 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 @@ -10,6 +10,17 @@ import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +/** + * Common type for all files in Telegram Bot API which can be sent via requests like [dev.inmo.tgbotapi.requests.send.media.SendDocument]. + * You may use methods like [MPPFile.asMultipartFile] when you want to send files from your file system, but you should + * remember about [restrictions][https://core.telegram.org/bots/api#sending-files] in Telegram for bots. In case you + * wish to send file by its url, use [FileId] and pass your url as [FileId.fileId] + * + * @see MPPFile.asMultipartFile + * @see ByteArray.asMultipartFile + * @see ByteReadChannel.asMultipartFile + * @see ByteReadChannelAllocator.asMultipartFile + */ @Serializable(InputFileSerializer::class) sealed class InputFile { abstract val fileId: String From 0fec35f0dcda6a206af11b9f2c1be7ad6553276e Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 8 Sep 2021 21:31:43 +0600 Subject: [PATCH 6/7] BehaviourContext#commandWithArgs and BehaviourContext#onCommandWithArgs --- CHANGELOG.md | 2 + .../behaviour_builder/BehaviourContext.kt | 1 + .../triggers_handling/CommandHandling.kt | 55 ++++++++++++++++++- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65be07c582..662be960ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ * `MultipartRequestCallFactory` now will use file name as multipart `filename` parameter instead of generated filename * New extension `MPPFile#asMultipartFile` +* `Behaviour Builder`: + * New extensions `BehaviourContext#commandWithArgs` and `BehaviourContext#onCommandWithArgs` ## 0.35.7 diff --git a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext.kt b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext.kt index c92ff63c62..35fab43c78 100644 --- a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext.kt +++ b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext.kt @@ -10,6 +10,7 @@ import kotlinx.coroutines.flow.filter typealias BehaviourContextReceiver = suspend BehaviourContext.() -> T typealias BehaviourContextAndTypeReceiver = suspend BehaviourContext.(I) -> T +typealias BehaviourContextAndTwoTypesReceiver = suspend BehaviourContext.(I1, I2) -> T /** * This class contains all necessary tools for work with bots and especially for [buildBehaviour] diff --git a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CommandHandling.kt b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CommandHandling.kt index 9e90a3cd70..fa81c759df 100644 --- a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CommandHandling.kt +++ b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CommandHandling.kt @@ -1,10 +1,10 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling -import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext -import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTypeReceiver +import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatMessageMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory import dev.inmo.tgbotapi.extensions.utils.asBotCommandTextSource +import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage import dev.inmo.tgbotapi.types.message.content.TextContent import kotlinx.coroutines.Job @@ -33,6 +33,7 @@ suspend fun BehaviourContext.command( markerFactory, scenarioReceiver ) + suspend fun BehaviourContext.command( command: String, requireOnlyCommandInMessage: Boolean = true, @@ -59,3 +60,53 @@ suspend inline fun BehaviourContext.onCommand( markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, noinline scenarioReceiver: BehaviourContextAndTypeReceiver> ): Job = onCommand(command.toRegex(), requireOnlyCommandInMessage, includeFilterByChatInBehaviourSubContext, additionalFilter, markerFactory, scenarioReceiver) + +suspend fun BehaviourContext.commandWithArgs( + commandRegex: Regex, + includeFilterByChatInBehaviourSubContext: Boolean = true, + additionalFilter: CommonMessageFilter? = null, + markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, + scenarioReceiver: BehaviourContextAndTwoTypesReceiver, Array> +) = command( + commandRegex, + requireOnlyCommandInMessage = false, + includeFilterByChatInBehaviourSubContext = includeFilterByChatInBehaviourSubContext, + additionalFilter = additionalFilter, + markerFactory = markerFactory +) { + val args = it.parseCommandsWithParams().let { commandsWithArgs -> + val key = commandsWithArgs.keys.firstOrNull { it.matches(commandRegex) } ?: return@let null + commandsWithArgs[key] + } ?: emptyArray() + scenarioReceiver(it, args) +} + +suspend fun BehaviourContext.commandWithArgs( + command: String, + includeFilterByChatInBehaviourSubContext: Boolean = true, + additionalFilter: CommonMessageFilter? = null, + markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, + scenarioReceiver: BehaviourContextAndTwoTypesReceiver, Array> +) = commandWithArgs( + command.toRegex(), + includeFilterByChatInBehaviourSubContext = includeFilterByChatInBehaviourSubContext, + additionalFilter = additionalFilter, + markerFactory = markerFactory, + scenarioReceiver = scenarioReceiver +) + +suspend inline fun BehaviourContext.onCommandWithArgs( + commandRegex: Regex, + includeFilterByChatInBehaviourSubContext: Boolean = true, + noinline additionalFilter: CommonMessageFilter? = null, + markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, + noinline scenarioReceiver: BehaviourContextAndTwoTypesReceiver, Array> +): Job = commandWithArgs(commandRegex, includeFilterByChatInBehaviourSubContext, additionalFilter, markerFactory, scenarioReceiver) + +suspend inline fun BehaviourContext.onCommandWithArgs( + command: String, + includeFilterByChatInBehaviourSubContext: Boolean = true, + noinline additionalFilter: CommonMessageFilter? = null, + markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, + noinline scenarioReceiver: BehaviourContextAndTwoTypesReceiver, Array> +): Job = onCommandWithArgs(command.toRegex(), includeFilterByChatInBehaviourSubContext, additionalFilter, markerFactory, scenarioReceiver) From 7af5ab17b7e35d79325cfe08a63a891db85ba8ff Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 8 Sep 2021 22:19:08 +0600 Subject: [PATCH 7/7] Fixes in TelegramBot#withAction --- CHANGELOG.md | 2 ++ .../extensions/api/send/SendActionDSL.kt | 24 ++++++++----------- .../utils/shortcuts/RequestsExecutor.kt | 5 ++-- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 662be960ed..122e6c1ac6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ * `MultipartRequestCallFactory` now will use file name as multipart `filename` parameter instead of generated filename * New extension `MPPFile#asMultipartFile` +* `API` + * Fixes in `TelegramBot#withAction` * `Behaviour Builder`: * New extensions `BehaviourContext#commandWithArgs` and `BehaviourContext#onCommandWithArgs` diff --git a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendActionDSL.kt b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendActionDSL.kt index 652eaf6ba4..024abedfff 100644 --- a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendActionDSL.kt +++ b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/SendActionDSL.kt @@ -1,13 +1,13 @@ package dev.inmo.tgbotapi.extensions.api.send -import dev.inmo.micro_utils.coroutines.safely -import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions +import dev.inmo.micro_utils.coroutines.* import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.requests.send.SendAction import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.actions.* import dev.inmo.tgbotapi.types.chat.abstracts.Chat import kotlinx.coroutines.* +import kotlin.coroutines.coroutineContext private const val refreshTime: MilliSeconds = (botActionActualityTime - 1) * 1000L typealias TelegramBotActionCallback = suspend TelegramBot.() -> T @@ -16,21 +16,17 @@ suspend fun TelegramBot.withAction( actionRequest: SendAction, block: TelegramBotActionCallback ): T { - val botActionJob = supervisorScope { - launch { - while (isActive) { - delay(refreshTime) - safelyWithoutExceptions { - execute(actionRequest) - } + val botActionJob = CoroutineScope(coroutineContext).launch { + while (isActive) { + delay(refreshTime) + safelyWithoutExceptions { + execute(actionRequest) } } } - return try { - safely { block() } - } finally { - botActionJob.cancel() - } + val result = safelyWithResult { block() } + botActionJob.cancel() + return result.getOrThrow() } suspend fun TelegramBot.withAction( diff --git a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/RequestsExecutor.kt b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/RequestsExecutor.kt index f3ba0f62e7..f71350ad97 100644 --- a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/RequestsExecutor.kt +++ b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/RequestsExecutor.kt @@ -4,6 +4,7 @@ import dev.inmo.micro_utils.coroutines.safely import dev.inmo.tgbotapi.bot.RequestsExecutor import dev.inmo.tgbotapi.requests.abstracts.Request import kotlinx.coroutines.* +import kotlin.coroutines.coroutineContext fun RequestsExecutor.executeAsync( request: Request, @@ -16,9 +17,7 @@ fun RequestsExecutor.executeAsync( suspend fun RequestsExecutor.executeAsync( request: Request -): Deferred = coroutineScope { - executeAsync(request, this) -} +): Deferred = executeAsync(request, CoroutineScope(coroutineContext)) suspend fun RequestsExecutor.executeUnsafe( request: Request,