diff --git a/tgbotapi.behaviour_builder/api/tgbotapi.behaviour_builder.api b/tgbotapi.behaviour_builder/api/tgbotapi.behaviour_builder.api index 3d98dcfdf4..09dd2580e0 100644 --- a/tgbotapi.behaviour_builder/api/tgbotapi.behaviour_builder.api +++ b/tgbotapi.behaviour_builder/api/tgbotapi.behaviour_builder.api @@ -339,12 +339,12 @@ public final class dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/W public static final fun requireCommandAtStart (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow; public static final fun requireCommandsWithoutParams (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow; public static final fun requireSingleCommand (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow; - public static final fun waitCommandMessage (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/types/BotCommand;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow; - public static final fun waitCommandMessage (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ljava/lang/String;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow; - public static final fun waitCommandMessage (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Lkotlin/text/Regex;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow; - public static synthetic fun waitCommandMessage$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/types/BotCommand;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; - public static synthetic fun waitCommandMessage$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ljava/lang/String;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; - public static synthetic fun waitCommandMessage$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Lkotlin/text/Regex;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; + public static final fun waitCommandMessage (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/types/BotCommand;Ldev/inmo/tgbotapi/requests/abstracts/Request;ZLkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow; + public static final fun waitCommandMessage (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ljava/lang/String;Ldev/inmo/tgbotapi/requests/abstracts/Request;ZLkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow; + public static final fun waitCommandMessage (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Lkotlin/text/Regex;Ldev/inmo/tgbotapi/requests/abstracts/Request;ZLkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow; + public static synthetic fun waitCommandMessage$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/types/BotCommand;Ldev/inmo/tgbotapi/requests/abstracts/Request;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; + public static synthetic fun waitCommandMessage$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ljava/lang/String;Ldev/inmo/tgbotapi/requests/abstracts/Request;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; + public static synthetic fun waitCommandMessage$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Lkotlin/text/Regex;Ldev/inmo/tgbotapi/requests/abstracts/Request;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; } public final class dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitContentKt { @@ -490,12 +490,12 @@ public final class dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/W } public final class dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitDeepLinksKt { - public static final fun waitDeepLinks (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow; - public static final fun waitDeepLinks (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ljava/lang/String;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow; - public static final fun waitDeepLinks (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Lkotlin/text/Regex;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow; - public static synthetic fun waitDeepLinks$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; - public static synthetic fun waitDeepLinks$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ljava/lang/String;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; - public static synthetic fun waitDeepLinks$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Lkotlin/text/Regex;Ldev/inmo/tgbotapi/requests/abstracts/Request;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; + public static final fun waitDeepLinks (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;ZLkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow; + public static final fun waitDeepLinks (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ljava/lang/String;Ldev/inmo/tgbotapi/requests/abstracts/Request;ZLkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow; + public static final fun waitDeepLinks (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Lkotlin/text/Regex;Ldev/inmo/tgbotapi/requests/abstracts/Request;ZLkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow; + public static synthetic fun waitDeepLinks$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/requests/abstracts/Request;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; + public static synthetic fun waitDeepLinks$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ljava/lang/String;Ldev/inmo/tgbotapi/requests/abstracts/Request;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; + public static synthetic fun waitDeepLinks$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Lkotlin/text/Regex;Ldev/inmo/tgbotapi/requests/abstracts/Request;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; } public final class dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitDeletedBusinessMessagesKt { @@ -1610,6 +1610,7 @@ public abstract interface class dev/inmo/tgbotapi/extensions/behaviour_builder/u public final class dev/inmo/tgbotapi/extensions/behaviour_builder/utils/DefaultCustomBehaviourContextAndTypeReceiverKt { public static final fun botInfo (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun containsCommand (Ljava/util/List;Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Lkotlin/text/Regex;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun optionallyWithDefaultReceiver (Lkotlin/jvm/functions/Function3;ZLdev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextData;)Lkotlin/jvm/functions/Function3; public static final fun withDefaultReceiver (Lkotlin/jvm/functions/Function3;Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextData;)Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/DefaultCustomBehaviourContextAndTypeReceiver; } diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitCommandsMessages.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitCommandsMessages.kt index c9cd4bc4ea..d6e3f070ed 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitCommandsMessages.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitCommandsMessages.kt @@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext +import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.containsCommand import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.handlers_registrar.doWithRegistration import dev.inmo.tgbotapi.extensions.utils.* import dev.inmo.tgbotapi.extensions.utils.extensions.TelegramBotCommandsDefaults @@ -27,6 +28,7 @@ import kotlinx.coroutines.flow.* fun BehaviourContext.waitCommandMessage( commandRegex: Regex, initRequest: Request<*>? = null, + excludeCommandsToOtherBots: Boolean = true, errorFactory: NullableRequestBuilder<*> = { null } ) = channelFlow { triggersHolder.handleableCommandsHolder.doWithRegistration( @@ -34,6 +36,16 @@ fun BehaviourContext.waitCommandMessage( ) { waitTextMessage(initRequest, errorFactory).filter { it.content.textSources.any { it.botCommandTextSourceOrNull() ?.command ?.matches(commandRegex) == true } + }.let { + if (excludeCommandsToOtherBots) { + it.filter { + with(it.content.textSources) { + containsCommand(commandRegex) + } + } + } else { + it + } }.collect { send(it) } @@ -43,14 +55,16 @@ fun BehaviourContext.waitCommandMessage( fun BehaviourContext.waitCommandMessage( command: String, initRequest: Request<*>? = null, + excludeCommandsToOtherBots: Boolean = true, errorFactory: NullableRequestBuilder<*> = { null } -) = waitCommandMessage(Regex(command), initRequest, errorFactory) +) = waitCommandMessage(Regex(command), initRequest, excludeCommandsToOtherBots, errorFactory) fun BehaviourContext.waitCommandMessage( botCommand: BotCommand, initRequest: Request<*>? = null, + excludeCommandsToOtherBots: Boolean = true, errorFactory: NullableRequestBuilder<*> = { null } -) = waitCommandMessage(botCommand.command, initRequest, errorFactory) +) = waitCommandMessage(botCommand.command, initRequest, excludeCommandsToOtherBots, errorFactory) fun Flow>.requireCommandAtStart() = filter { it.content.textSources.firstOrNull() is BotCommandTextSource diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitDeepLinks.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitDeepLinks.kt index 4418e8fe57..fdbb5246b9 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitDeepLinks.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitDeepLinks.kt @@ -10,11 +10,13 @@ import kotlinx.coroutines.flow.* fun BehaviourContext.waitDeepLinks( initRequest: Request<*>? = null, + excludeCommandsToOtherBots: Boolean = true, errorFactory: NullableRequestBuilder<*> = { null }, ): Flow, String>> = waitCommandMessage( - "start", - initRequest, - errorFactory + command = "start", + initRequest = initRequest, + excludeCommandsToOtherBots = excludeCommandsToOtherBots, + errorFactory = errorFactory ) .requireSingleCommand() .requireCommandAtStart() @@ -25,13 +27,24 @@ fun BehaviourContext.waitDeepLinks( fun BehaviourContext.waitDeepLinks( regex: Regex, initRequest: Request<*>? = null, + excludeCommandsToOtherBots: Boolean = true, errorFactory: NullableRequestBuilder<*> = { null }, -): Flow, String>> = waitDeepLinks(initRequest, errorFactory).filter { +): Flow, String>> = waitDeepLinks( + initRequest = initRequest, + excludeCommandsToOtherBots = excludeCommandsToOtherBots, + errorFactory = errorFactory +).filter { regex.matches(it.second) } fun BehaviourContext.waitDeepLinks( deepLink: String, initRequest: Request<*>? = null, + excludeCommandsToOtherBots: Boolean = true, errorFactory: NullableRequestBuilder<*> = { null }, -): Flow, String>> = waitDeepLinks(Regex("^$deepLink$"), initRequest, errorFactory) +): Flow, String>> = waitDeepLinks( + regex = Regex(pattern = "^$deepLink$"), + initRequest = initRequest, + excludeCommandsToOtherBots = excludeCommandsToOtherBots, + errorFactory = errorFactory +) diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CommandHandling.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CommandHandling.kt index 1321b1a675..360669d2e6 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CommandHandling.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CommandHandling.kt @@ -6,6 +6,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CommonMessageFilterExcludeMediaGroups import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessageFilterByChat import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.botInfo +import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.containsCommand 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.behaviour_builder.utils.times @@ -46,19 +47,9 @@ internal fun BC.commandUncounted( }.let { if (excludeCommandsToOtherBots) { it * lambda@{ - it.content.textSources.forEach { - val command = it.botCommandTextSourceOrNull() ?.takeIf { - commandRegex.matches(it.command) - } ?: return@forEach - if (command.username == null) { - return@lambda true - } - val botInfo = botInfo() - if (botInfo == null || command.username == botInfo.username) { - return@lambda true - } + with(it.content.textSources) { + containsCommand(commandRegex) } - false } } else { it diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/DefaultCustomBehaviourContextAndTypeReceiver.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/DefaultCustomBehaviourContextAndTypeReceiver.kt index 99cc4395fd..d93a7afca9 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/DefaultCustomBehaviourContextAndTypeReceiver.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/DefaultCustomBehaviourContextAndTypeReceiver.kt @@ -5,8 +5,11 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextData import dev.inmo.tgbotapi.extensions.behaviour_builder.CustomBehaviourContextAndTypeReceiver import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.DefaultCustomBehaviourContextAndTypeReceiver.Companion.BOT_INFO_RECEIVER +import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.botInfo +import dev.inmo.tgbotapi.extensions.utils.botCommandTextSourceOrNull import dev.inmo.tgbotapi.requests.bot.GetMe import dev.inmo.tgbotapi.types.chat.ExtendedBot +import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList import dev.inmo.tgbotapi.types.update.abstracts.Update import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock @@ -28,6 +31,21 @@ suspend fun BehaviourContext.botInfo(): ExtendedBot? { } } +context(textSources: TextSourcesList, bc: BehaviourContext) +suspend fun containsCommand(commandRegex: Regex) = textSources.any { + val command = it.botCommandTextSourceOrNull() ?.takeIf { + commandRegex.matches(it.command) + } ?: return@any false + if (command.username == null) { + return@any true + } + val botInfo = bc.botInfo() + if (botInfo == null || command.username == botInfo.username) { + return@any true + } + false +} + @Warning("It is internal API and can be changed without notes") fun CustomBehaviourContextAndTypeReceiver.withDefaultReceiver( data: BehaviourContextData