From 1cff6f616fbdd4b39d0763306a5146555d1bf5b7 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 10 Aug 2020 10:45:46 +0600 Subject: [PATCH 1/7] start 0.27.10 --- CHANGELOG.md | 2 ++ gradle.properties | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfa2fd6595..58c0f5ec36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,8 @@ * `closePollExactAfter` * `closePollAfter` +### 0.27.10 + ### 0.27.9 * `Common` 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 From e3bfc4472a40dcb25a4752e6abf73bada0477d72 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 10 Aug 2020 10:46:18 +0600 Subject: [PATCH 2/7] includeWebhookHandlingInRouteWithFlows --- CHANGELOG.md | 3 +++ TelegramBotAPI-extensions-utils/README.md | 2 ++ .../extensions/utils/updates/retrieving/Webhook.kt | 14 ++++++++++++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58c0f5ec36..1f40d9eb3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,9 @@ ### 0.27.10 +* `TelegramBotAPI-extensions-utils`: + * Extension `Route#includeWebhookHandlingInRouteWithFlows` was added + ### 0.27.9 * `Common` diff --git a/TelegramBotAPI-extensions-utils/README.md b/TelegramBotAPI-extensions-utils/README.md index b5b17083d1..3987598129 100644 --- a/TelegramBotAPI-extensions-utils/README.md +++ b/TelegramBotAPI-extensions-utils/README.md @@ -159,6 +159,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/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. * From ff2c70fc76406a1e38edc67c92fa5e682c73d26d Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 10 Aug 2020 11:41:46 +0600 Subject: [PATCH 3/7] FlowsUpdatesFiler extensions --- CHANGELOG.md | 18 +++ TelegramBotAPI-extensions-utils/README.md | 3 + .../utils/shortcuts/FlowsUpdatesFilter.kt | 125 ++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 TelegramBotAPI-extensions-utils/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/utils/shortcuts/FlowsUpdatesFilter.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f40d9eb3e..afdf6f6829 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,24 @@ * `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 diff --git a/TelegramBotAPI-extensions-utils/README.md b/TelegramBotAPI-extensions-utils/README.md index 3987598129..1a3bd51b2a 100644 --- a/TelegramBotAPI-extensions-utils/README.md +++ b/TelegramBotAPI-extensions-utils/README.md @@ -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}") + } /* ... */ } ``` 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..5c51f06b06 --- /dev/null +++ b/TelegramBotAPI-extensions-utils/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/utils/shortcuts/FlowsUpdatesFilter.kt @@ -0,0 +1,125 @@ +package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.shortcuts + +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.channels.BroadcastChannel +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.* + +/** + * @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> { + return scopeToIncludeChannels ?.let { scope -> + val bc = BroadcastChannel>(Channel.BUFFERED) + channelPostFlow.asContentMessagesFlow().mapNotNull { + if (it.content is T) { + it as ContentMessage + } else { + null + } + }.onEach { + bc.send(it) + }.launchIn(scope) + messageFlow.asContentMessagesFlow().mapNotNull { + if (it.content is T) { + it as ContentMessage + } else { + null + } + }.onEach { + bc.send(it) + }.launchIn(scope) + bc.asFlow() + } ?: messageFlow.asContentMessagesFlow().mapNotNull { + if (it.content is T) { + it as ContentMessage + } else { + null + } + } +} + +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) + + From 63b2bd61b5f298b6e1b01963dc9cb021d8a1ed3a Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 10 Aug 2020 11:53:54 +0600 Subject: [PATCH 4/7] add aggregation of flows --- .../extensions/utils/FlowsAggregation.kt | 20 +++++++++ .../utils/shortcuts/FlowsUpdatesFilter.kt | 45 +++++++------------ 2 files changed, 36 insertions(+), 29 deletions(-) create mode 100644 TelegramBotAPI-extensions-utils/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/extensions/utils/FlowsAggregation.kt 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 index 5c51f06b06..8b02c3924f 100644 --- 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 @@ -1,5 +1,6 @@ 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.* @@ -8,10 +9,16 @@ 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.channels.BroadcastChannel -import kotlinx.coroutines.channels.Channel 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 @@ -21,34 +28,14 @@ import kotlinx.coroutines.flow.* inline fun FlowsUpdatesFilter.filterContentMessages( scopeToIncludeChannels: CoroutineScope? = null ): Flow> { + val filter = filterForContentMessage() return scopeToIncludeChannels ?.let { scope -> - val bc = BroadcastChannel>(Channel.BUFFERED) - channelPostFlow.asContentMessagesFlow().mapNotNull { - if (it.content is T) { - it as ContentMessage - } else { - null - } - }.onEach { - bc.send(it) - }.launchIn(scope) - messageFlow.asContentMessagesFlow().mapNotNull { - if (it.content is T) { - it as ContentMessage - } else { - null - } - }.onEach { - bc.send(it) - }.launchIn(scope) - bc.asFlow() - } ?: messageFlow.asContentMessagesFlow().mapNotNull { - if (it.content is T) { - it as ContentMessage - } else { - null - } - } + aggregateFlows( + scope, + messageFlow.asContentMessagesFlow().mapNotNull(filter), + channelPostFlow.asContentMessagesFlow().mapNotNull(filter) + ) + } ?: messageFlow.asContentMessagesFlow().mapNotNull(filter) } fun FlowsUpdatesFilter.animationMessages( From 1758d80020dc99bcea165e1dffc3986628796a8c Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 10 Aug 2020 13:38:19 +0600 Subject: [PATCH 5/7] new telegramBot --- CHANGELOG.md | 2 ++ .../TelegramBotAPI/extensions/api/BotExtensions.kt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afdf6f6829..6ec5dae49a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,8 @@ ### 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: 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 From 48e946c2d0cb97f2aa0f698b162ed1fc9585dfaa Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 10 Aug 2020 20:00:45 +0600 Subject: [PATCH 6/7] add a simple fix in readme --- TelegramBotAPI-extensions-utils/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TelegramBotAPI-extensions-utils/README.md b/TelegramBotAPI-extensions-utils/README.md index 1a3bd51b2a..fef3caf2d2 100644 --- a/TelegramBotAPI-extensions-utils/README.md +++ b/TelegramBotAPI-extensions-utils/README.md @@ -104,7 +104,7 @@ val internalChannelsSizes = 128 flowsUpdatesFilter(internalChannelsSizes/* default is 64 */) { textMessages().onEach { println("I have received text message: ${it.content}") - } + }.launchIn(someCoroutineScope) /* ... */ } ``` From 8f882e98254f0a7de5a22f94d1f20adff2403af4 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 10 Aug 2020 20:02:11 +0600 Subject: [PATCH 7/7] fix links in toc of extensions readme --- TelegramBotAPI-extensions-utils/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/TelegramBotAPI-extensions-utils/README.md b/TelegramBotAPI-extensions-utils/README.md index fef3caf2d2..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)