diff --git a/CHANGELOG.md b/CHANGELOG.md index cfa2fd6595..6ec5dae49a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,31 @@ * `closePollExactAfter` * `closePollAfter` +### 0.27.10 + +* `TelegramBotAPI-extensions-api`: + * Function `telegramBot(TelegramAPIUrlsKeeper)` was added +* `TelegramBotAPI-extensions-utils`: + * Extension `Route#includeWebhookHandlingInRouteWithFlows` was added + * A lot of extensions like `FlowsUpdatesFilter#textMessages` were added: + * `FlowsUpdatesFilter#animationMessages` + * `FlowsUpdatesFilter#audioMessages` + * `FlowsUpdatesFilter#contactMessages` + * `FlowsUpdatesFilter#diceMessages` + * `FlowsUpdatesFilter#documentMessages` + * `FlowsUpdatesFilter#gameMessages` + * `FlowsUpdatesFilter#invoiceMessages` + * `FlowsUpdatesFilter#locationMessages` + * `FlowsUpdatesFilter#photoMessages` + * `FlowsUpdatesFilter#imageMessages` + * `FlowsUpdatesFilter#pollMessages` + * `FlowsUpdatesFilter#stickerMessages` + * `FlowsUpdatesFilter#textMessages` + * `FlowsUpdatesFilter#venueMessages` + * `FlowsUpdatesFilter#videoMessages` + * `FlowsUpdatesFilter#videoNoteMessages` + * `FlowsUpdatesFilter#voiceMessages` + ### 0.27.9 * `Common` diff --git a/TelegramBotAPI-extensions-api/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/api/BotExtensions.kt b/TelegramBotAPI-extensions-api/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/api/BotExtensions.kt index ef586bcae8..2342fac9f9 100644 --- a/TelegramBotAPI-extensions-api/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/api/BotExtensions.kt +++ b/TelegramBotAPI-extensions-api/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/api/BotExtensions.kt @@ -12,7 +12,7 @@ import io.ktor.client.engine.HttpClientEngine */ fun telegramBot( urlsKeeper: TelegramAPIUrlsKeeper, - client: HttpClient + client: HttpClient = HttpClient() ): RequestsExecutor = KtorRequestsExecutor( urlsKeeper, client diff --git a/TelegramBotAPI-extensions-utils/README.md b/TelegramBotAPI-extensions-utils/README.md index b5b17083d1..6db9f5228c 100644 --- a/TelegramBotAPI-extensions-utils/README.md +++ b/TelegramBotAPI-extensions-utils/README.md @@ -1,14 +1,14 @@ -# TelegramBotAPI Util Extensions +# TelegramBotAPI Util Extensions -- [TelegramBotAPI Util Extensions](#telegrambotapi-util--extensions) - * [What is it?](#what-is-it-) - * [How to implement library?](#how-to-implement-library-) +- [TelegramBotAPI Util Extensions](#telegrambotapi-util-extensions) + * [What is it?](#what-is-it) + * [How to implement library?](#how-to-implement-library) + [Maven](#maven) + [Gradle](#gradle) - * [How to use?](#how-to-use-) + * [How to use?](#how-to-use) + [Updates](#updates) - [Long polling](#long-polling) - - [WebHooks (currently JVM-only)](#webhooks--currently-jvm-only-) + - [WebHooks (currently JVM-only)](#webhooks--currently-jvm-only) + [Filters](#filters) - [Sent messages](#sent-messages) * [Common messages](#common-messages) @@ -102,6 +102,9 @@ Anyway, in both of ways it will be useful to know that it is possible to create ```kotlin val internalChannelsSizes = 128 flowsUpdatesFilter(internalChannelsSizes/* default is 64 */) { + textMessages().onEach { + println("I have received text message: ${it.content}") + }.launchIn(someCoroutineScope) /* ... */ } ``` @@ -159,6 +162,8 @@ Besides, there are two additional opportunities: * Extension `Route#includeWebhookHandlingInRoute`, which allow you to include webhook processing inside your ktor application without creating of new one server (as it is happening in `startListenWebhooks`) + * Also, you can use `Route#includeWebhookHandlingInRouteWithFlows` to use it like `flowUpdatesFilter` fun, but apply + `FlowsUpdatesFilter` to the block * Extension `RequestsExecutor#setWebhookInfoAndStartListenWebhooks`. It is allow to set up full server (in fact, with `startListenWebhooks`), but also send `SetWebhook` request before and check that it was successful diff --git a/TelegramBotAPI-extensions-utils/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/utils/FlowsAggregation.kt b/TelegramBotAPI-extensions-utils/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/utils/FlowsAggregation.kt new file mode 100644 index 0000000000..37333b2cec --- /dev/null +++ b/TelegramBotAPI-extensions-utils/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/utils/FlowsAggregation.kt @@ -0,0 +1,20 @@ +package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.channels.BroadcastChannel +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.* + +fun aggregateFlows( + withScope: CoroutineScope, + vararg flows: Flow, + internalBufferSize: Int = Channel.BUFFERED +): Flow { + val bc = BroadcastChannel(internalBufferSize) + flows.forEach { + it.onEach { + safely { bc.send(it) } + }.launchIn(withScope) + } + return bc.asFlow() +} diff --git a/TelegramBotAPI-extensions-utils/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/utils/shortcuts/FlowsUpdatesFilter.kt b/TelegramBotAPI-extensions-utils/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/utils/shortcuts/FlowsUpdatesFilter.kt new file mode 100644 index 0000000000..8b02c3924f --- /dev/null +++ b/TelegramBotAPI-extensions-utils/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/utils/shortcuts/FlowsUpdatesFilter.kt @@ -0,0 +1,112 @@ +package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.shortcuts + +import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.aggregateFlows +import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.asContentMessagesFlow +import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.ContentMessage +import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.* +import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MessageContent +import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media.* +import com.github.insanusmokrassar.TelegramBotAPI.types.message.payments.InvoiceContent +import com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.FlowsUpdatesFilter +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.* + +inline fun filterForContentMessage(): suspend (ContentMessage<*>) -> ContentMessage? = { + if (it.content is T) { + it as ContentMessage + } else { + null + } +} + +/** + * @param scopeToIncludeChannels This parameter is required when you want to include [textMessages] for channels too. + * In this case will be created new channel which will agregate messages from [FlowsUpdatesFilter.messageFlow] and + * [FlowsUpdatesFilter.channelPostFlow]. In case it is null will be used [Flow]s mapping + */ +@Suppress("UNCHECKED_CAST") +inline fun FlowsUpdatesFilter.filterContentMessages( + scopeToIncludeChannels: CoroutineScope? = null +): Flow> { + val filter = filterForContentMessage() + return scopeToIncludeChannels ?.let { scope -> + aggregateFlows( + scope, + messageFlow.asContentMessagesFlow().mapNotNull(filter), + channelPostFlow.asContentMessagesFlow().mapNotNull(filter) + ) + } ?: messageFlow.asContentMessagesFlow().mapNotNull(filter) +} + +fun FlowsUpdatesFilter.animationMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.audioMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.contactMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.diceMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.documentMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.gameMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.invoiceMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.locationMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.photoMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) +/** + * Shortcut for [photoMessages] + */ +@Suppress("NOTHING_TO_INLINE") +inline fun FlowsUpdatesFilter.imageMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = photoMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.pollMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.stickerMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.textMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.venueMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.videoMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.videoNoteMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + +fun FlowsUpdatesFilter.voiceMessages( + scopeToIncludeChannels: CoroutineScope? = null +) = filterContentMessages(scopeToIncludeChannels) + + diff --git a/TelegramBotAPI-extensions-utils/src/jvmMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/utils/updates/retrieving/Webhook.kt b/TelegramBotAPI-extensions-utils/src/jvmMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/utils/updates/retrieving/Webhook.kt index 0434a385c9..45343c69f3 100644 --- a/TelegramBotAPI-extensions-utils/src/jvmMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/utils/updates/retrieving/Webhook.kt +++ b/TelegramBotAPI-extensions-utils/src/jvmMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/utils/updates/retrieving/Webhook.kt @@ -2,14 +2,14 @@ package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.retr import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestsExecutor import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.nonstrictJsonFormat +import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.flowsUpdatesFilter import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.MultipartFile import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.base.MultipartRequestImpl import com.github.insanusmokrassar.TelegramBotAPI.requests.webhook.SetWebhook import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.UpdateDeserializationStrategy -import com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.UpdateReceiver -import com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.UpdatesFilter +import com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.* import com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.webhook.WebhookPrivateKeyConfig import com.github.insanusmokrassar.TelegramBotAPI.utils.ExceptionHandler import com.github.insanusmokrassar.TelegramBotAPI.utils.handleSafely @@ -56,6 +56,16 @@ fun Route.includeWebhookHandlingInRoute( } } +fun Route.includeWebhookHandlingInRouteWithFlows( + scope: CoroutineScope, + exceptionsHandler: ExceptionHandler? = null, + block: FlowsUpdatesFilter.() -> Unit +) = includeWebhookHandlingInRoute( + scope, + exceptionsHandler, + flowsUpdatesFilter(block = block).asUpdateReceiver +) + /** * Setting up ktor server, set webhook info via [SetWebhook] request. * diff --git a/gradle.properties b/gradle.properties index 2920b51746..2dd30909ce 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,6 +9,6 @@ ktor_version=1.3.2 javax_activation_version=1.1.1 library_group=com.github.insanusmokrassar -library_version=0.27.9 +library_version=0.27.10 gradle_bintray_plugin_version=1.8.4