diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ef218b4a5..23edc3b47f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,16 @@ __All the `tgbotapi.extensions.*` packages have been removed__ * `BehaviourBuilder`: * `SimpleFilter` now is a `fun interface` instead of just callback (fix of [#546](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/546)) +## 0.38.15 + +* `Common`: + * `Version`: + * `MicroUtils`: `0.9.20` -> `0.9.24` +* `Core`: + * Fixes in `MessageContent#serializationModule` +* `BehaviourBuilder`: + * Add triggers for `DataCallbackQuery` and subtypes with regex checking of data + ## 0.38.14 __This update contains including of [Telegram Bot API 6.0](https://core.telegram.org/bots/api-changelog#april-16-2022)__ diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext.kt index 6d99c2c291..2426853a51 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext.kt @@ -26,7 +26,7 @@ internal inline fun CustomBehaviourContextAndTwoTypesReceiver = { invoke(this, i1, it) } /** - * This class contains all necessary tools for work with bots and especially for [buildBehaviour] + * This class contains all necessary tools for work with bots and especially [buildBehaviour] * * @see DefaultBehaviourContext */ diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CallbackQueryTriggers.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CallbackQueryTriggers.kt index d5b61538ae..890923ba30 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CallbackQueryTriggers.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/CallbackQueryTriggers.kt @@ -7,6 +7,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CallbackQueryFilte import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByUserCallbackQueryMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory +import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus import dev.inmo.tgbotapi.extensions.utils.asCallbackQueryUpdate import dev.inmo.tgbotapi.types.queries.callback.* import dev.inmo.tgbotapi.types.update.abstracts.Update @@ -44,6 +45,62 @@ suspend fun BC.onDataCallbackQuery( scenarioReceiver ) +/** + * @param dataRegex Will be used with [initialFilter] as [initialFilter] for upstream [onDataCallbackQuery] to filter + * [DataCallbackQuery] with [DataCallbackQuery.data] [String.matches] to [dataRegex] + * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call + * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, + * this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage]. + * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own. + * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] + * to combinate several filters + * @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously + * in one "stream". Output of [markerFactory] will be used as a key for "stream" + * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that + * data + */ +suspend fun BC.onDataCallbackQuery( + dataRegex: Regex, + initialFilter: SimpleFilter? = null, + subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver? = CallbackQueryFilterByUser, + markerFactory: MarkerFactory = ByUserCallbackQueryMarkerFactory, + scenarioReceiver: CustomBehaviourContextAndTypeReceiver +) = onDataCallbackQuery( + initialFilter = initialFilter + { + it.data.matches(dataRegex) + }, + subcontextUpdatesFilter, + markerFactory, + scenarioReceiver +) + +/** + * @param data Will be converted to [Regex] via its constructor and pass it to upstream [onDataCallbackQuery] + * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call + * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, + * this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage]. + * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own. + * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] + * to combinate several filters + * @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously + * in one "stream". Output of [markerFactory] will be used as a key for "stream" + * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that + * data + */ +suspend fun BC.onDataCallbackQuery( + data: String, + initialFilter: SimpleFilter? = null, + subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver? = CallbackQueryFilterByUser, + markerFactory: MarkerFactory = ByUserCallbackQueryMarkerFactory, + scenarioReceiver: CustomBehaviourContextAndTypeReceiver +) = onDataCallbackQuery( + Regex(data), + initialFilter, + subcontextUpdatesFilter, + markerFactory, + scenarioReceiver +) + /** * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, @@ -116,6 +173,62 @@ suspend fun BC.onInlineMessageIdDataCallbackQuery( scenarioReceiver ) +/** + * @param dataRegex Will be used with [initialFilter] as [initialFilter] for upstream [onInlineMessageIdDataCallbackQuery] + * to filter [InlineMessageIdDataCallbackQuery] with [InlineMessageIdDataCallbackQuery.data] [String.matches] to [dataRegex] + * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call + * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, + * this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage]. + * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own. + * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] + * to combinate several filters + * @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously + * in one "stream". Output of [markerFactory] will be used as a key for "stream" + * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that + * data + */ +suspend fun BC.onInlineMessageIdDataCallbackQuery( + dataRegex: Regex, + initialFilter: SimpleFilter? = null, + subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver? = CallbackQueryFilterByUser, + markerFactory: MarkerFactory = ByUserCallbackQueryMarkerFactory, + scenarioReceiver: CustomBehaviourContextAndTypeReceiver +) = onInlineMessageIdDataCallbackQuery( + initialFilter = initialFilter + { + it.data.matches(dataRegex) + }, + subcontextUpdatesFilter, + markerFactory, + scenarioReceiver +) + +/** + * @param data Will be converted to [Regex] via its constructor and pass it to upstream [onInlineMessageIdDataCallbackQuery] + * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call + * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, + * this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage]. + * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own. + * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] + * to combinate several filters + * @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously + * in one "stream". Output of [markerFactory] will be used as a key for "stream" + * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that + * data + */ +suspend fun BC.onInlineMessageIdDataCallbackQuery( + data: String, + initialFilter: SimpleFilter? = null, + subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver? = CallbackQueryFilterByUser, + markerFactory: MarkerFactory = ByUserCallbackQueryMarkerFactory, + scenarioReceiver: CustomBehaviourContextAndTypeReceiver +) = onInlineMessageIdDataCallbackQuery( + Regex(data), + initialFilter, + subcontextUpdatesFilter, + markerFactory, + scenarioReceiver +) + /** * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, @@ -188,6 +301,62 @@ suspend fun BC.onMessageDataCallbackQuery( scenarioReceiver ) +/** + * @param dataRegex Will be used with [initialFilter] as [initialFilter] for upstream [onMessageDataCallbackQuery] to filter + * [MessageDataCallbackQuery] with [MessageDataCallbackQuery.data] [String.matches] to [dataRegex] + * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call + * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, + * this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage]. + * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own. + * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] + * to combinate several filters + * @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously + * in one "stream". Output of [markerFactory] will be used as a key for "stream" + * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that + * data + */ +suspend fun BC.onMessageDataCallbackQuery( + dataRegex: Regex, + initialFilter: SimpleFilter? = null, + subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver? = CallbackQueryFilterByUser, + markerFactory: MarkerFactory = ByUserCallbackQueryMarkerFactory, + scenarioReceiver: CustomBehaviourContextAndTypeReceiver +) = onMessageDataCallbackQuery( + initialFilter = initialFilter + { + it.data.matches(dataRegex) + }, + subcontextUpdatesFilter, + markerFactory, + scenarioReceiver +) + +/** + * @param data Will be converted to [Regex] via its constructor and pass it to upstream [onMessageDataCallbackQuery] + * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call + * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, + * this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage]. + * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own. + * Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times] + * to combinate several filters + * @param [markerFactory] Will be used to identify different "stream". [scenarioReceiver] will be called synchronously + * in one "stream". Output of [markerFactory] will be used as a key for "stream" + * @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that + * data + */ +suspend fun BC.onMessageDataCallbackQuery( + data: String, + initialFilter: SimpleFilter? = null, + subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver? = CallbackQueryFilterByUser, + markerFactory: MarkerFactory = ByUserCallbackQueryMarkerFactory, + scenarioReceiver: CustomBehaviourContextAndTypeReceiver +) = onMessageDataCallbackQuery( + Regex(data), + initialFilter, + subcontextUpdatesFilter, + markerFactory, + scenarioReceiver +) + /** * @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call * @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example, diff --git a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/SimpleFilter.kt b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/SimpleFilter.kt index d77514ce1e..11a6f24ddb 100644 --- a/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/SimpleFilter.kt +++ b/tgbotapi.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/utils/SimpleFilter.kt @@ -28,16 +28,20 @@ fun SimpleFilter.listNone() = SimpleFilter> { /** * Makes an AND (&&) operation between [this] and [other] */ -operator fun SimpleFilter.times(other: SimpleFilter) = SimpleFilter { - this(it) && other(it) -} +operator fun SimpleFilter?.times(other: SimpleFilter): SimpleFilter = this ?.let { + SimpleFilter { + this(it) && other(it) + } +} ?: other /** * Makes an OR (||) operation between [this] and [other] */ -operator fun SimpleFilter.plus(other: SimpleFilter) = SimpleFilter { - this(it) || other(it) -} +operator fun SimpleFilter?.plus(other: SimpleFilter): SimpleFilter = this ?.let { + SimpleFilter { + this(it) || other(it) + } +} ?: other /** * Reverse results of [this] diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/abstracts/MessageContent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/abstracts/MessageContent.kt index ed5545ffe5..0c5b7e8a89 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/abstracts/MessageContent.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/abstracts/MessageContent.kt @@ -20,8 +20,7 @@ interface MessageContent: ResendableContent { subclass(DiceContent::class) subclass(TextContent::class) - subclass(LiveLocationContent::class) - subclass(StaticLocationContent::class) + subclass(LocationContent::class, LocationContentSerializer) subclass(PhotoContent::class) subclass(VideoContent::class)