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) + +