@file:Suppress("unused", "UNCHECKED_CAST") package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow import dev.inmo.tgbotapi.extensions.utils.* import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile 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.payments.InvoiceContent import dev.inmo.tgbotapi.utils.PreviewFeature typealias CommonMessageFilter = (suspend (CommonMessage) -> Boolean) @PreviewFeature internal suspend inline fun BehaviourContext.onContent( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = true, noinline additionalFilter: CommonMessageFilter? = null, noinline scenarioReceiver: BehaviourContextAndTypeReceiver> ) = flowsUpdatesFilter.expectFlow(bot) { if (includeMediaGroups) { it.asSentMediaGroupUpdate() ?.data ?.mapNotNull { if (it.content is T) { val adaptedMessage = it as CommonMessage if (additionalFilter == null || additionalFilter(adaptedMessage)) adaptedMessage else null } else { null } } ?.let { return@expectFlow it } } it.asBaseSentMessageUpdate() ?.data ?.asCommonMessage() ?.let { message -> if (message.content is T) { val adaptedMessage = message as CommonMessage if (additionalFilter == null || additionalFilter(adaptedMessage)) adaptedMessage else null } else { null } }.let(::listOfNotNull) }.subscribeSafelyWithoutExceptions(scope) { triggerMessage -> doInSubContextWithUpdatesFilter( updatesFilter = if (includeFilterByChatInBehaviourSubContext) { { it.sourceChat() ?.id ?.chatId == triggerMessage.chat.id.chatId } } else { null } ) { scenarioReceiver(triggerMessage) } } suspend fun BehaviourContext.onContentMessage( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onContact( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onDice( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onGame( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onLocation( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onPoll( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onText( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onVenue( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onAudioMediaGroup( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, true, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onDocumentMediaGroupContent( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onMediaCollection( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = false, additionalFilter: (suspend (CommonMessage>) -> Boolean)? = null, scenarioReceiver: BehaviourContextAndTypeReceiver>> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onMedia( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onAnimation( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onAudio( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = false, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onDocument( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = false, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onPhoto( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = false, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onSticker( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onVideo( includeFilterByChatInBehaviourSubContext: Boolean = true, includeMediaGroups: Boolean = false, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, includeMediaGroups, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onVideoNote( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onVoice( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver) suspend fun BehaviourContext.onInvoice( includeFilterByChatInBehaviourSubContext: Boolean = true, additionalFilter: CommonMessageFilter? = null, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onContent(includeFilterByChatInBehaviourSubContext, false, additionalFilter, scenarioReceiver)