diff --git a/CHANGELOG.md b/CHANGELOG.md index b75bec0e50..4781e0e399 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ * `PayInlineKeyboardButton#pay` now is deprecated * `RowBuilder` and `MatrixBuilder` now are open and available for extending * `MatrixBuilder#matrix` will return read-only new list instead of original internal `mutMatrix` + * Introduced new type of events `SuccessfulPaymentEvent` instead of putting of payment inside of message + * New type of events union: `CommonGroupEvent` * `Utils`: * Two new dsl: * `inlineKeyboard` for creating `InlineKeyboardMarkup` diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/DeleteChatPhoto.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/DeleteChatPhoto.kt index db88fc3dac..88401cc144 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/DeleteChatPhoto.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/DeleteChatPhoto.kt @@ -1,5 +1,5 @@ package dev.inmo.tgbotapi.types.message.ChatEvents -import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonEvent +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonGroupEvent -class DeleteChatPhoto: CommonEvent +class DeleteChatPhoto: CommonGroupEvent diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/LeftChatMember.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/LeftChatMember.kt index 22a9def5f3..682ff86a91 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/LeftChatMember.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/LeftChatMember.kt @@ -1,8 +1,8 @@ package dev.inmo.tgbotapi.types.message.ChatEvents import dev.inmo.tgbotapi.types.User -import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonEvent +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonGroupEvent data class LeftChatMember( val user: User -) : CommonEvent +) : CommonGroupEvent diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/NewChatPhoto.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/NewChatPhoto.kt index a12f00ec52..34640e408c 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/NewChatPhoto.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/NewChatPhoto.kt @@ -1,8 +1,8 @@ package dev.inmo.tgbotapi.types.message.ChatEvents import dev.inmo.tgbotapi.types.files.Photo -import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonEvent +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonGroupEvent data class NewChatPhoto( val photo: Photo -): CommonEvent +): CommonGroupEvent diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/NewChatTitle.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/NewChatTitle.kt index 3b1eaf6533..6ed5a469f6 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/NewChatTitle.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/NewChatTitle.kt @@ -1,7 +1,7 @@ package dev.inmo.tgbotapi.types.message.ChatEvents -import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonEvent +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonGroupEvent data class NewChatTitle( val title: String -): CommonEvent +): CommonGroupEvent diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/ProximityAlertTriggered.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/ProximityAlertTriggered.kt index e502522020..25604f2238 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/ProximityAlertTriggered.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/ProximityAlertTriggered.kt @@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.types.message.ChatEvents import dev.inmo.tgbotapi.types.Meters import dev.inmo.tgbotapi.types.User -import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonEvent +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonGroupEvent import kotlinx.serialization.Serializable /** @@ -14,4 +14,4 @@ data class ProximityAlertTriggered( val traveler: User, val watcher: User, val distance: Meters -) : CommonEvent +) : CommonGroupEvent diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/abstracts/CommonEvent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/abstracts/CommonEvent.kt index feb9af40ff..0228be76e6 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/abstracts/CommonEvent.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/abstracts/CommonEvent.kt @@ -1,3 +1,3 @@ package dev.inmo.tgbotapi.types.message.ChatEvents.abstracts -interface CommonEvent : ChannelEvent, GroupEvent, SupergroupEvent \ No newline at end of file +interface CommonEvent : CommonGroupEvent, PrivateEvent diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/abstracts/CommonGroupEvent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/abstracts/CommonGroupEvent.kt new file mode 100644 index 0000000000..6432af9b0e --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/abstracts/CommonGroupEvent.kt @@ -0,0 +1,3 @@ +package dev.inmo.tgbotapi.types.message.ChatEvents.abstracts + +interface CommonGroupEvent : ChannelEvent, GroupEvent, SupergroupEvent diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/abstracts/PrivateEvent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/abstracts/PrivateEvent.kt new file mode 100644 index 0000000000..b241669b98 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/abstracts/PrivateEvent.kt @@ -0,0 +1,3 @@ +package dev.inmo.tgbotapi.types.message.ChatEvents.abstracts + +interface PrivateEvent : ChatEvent diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/abstracts/VoiceChatEvent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/abstracts/VoiceChatEvent.kt index 289fc5daac..33cf8c7a99 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/abstracts/VoiceChatEvent.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChatEvents/abstracts/VoiceChatEvent.kt @@ -1,3 +1,3 @@ package dev.inmo.tgbotapi.types.message.ChatEvents.abstracts -interface VoiceChatEvent : CommonEvent +interface VoiceChatEvent : CommonGroupEvent diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/PrivateEventMessage.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/PrivateEventMessage.kt new file mode 100644 index 0000000000..86a9a51845 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/PrivateEventMessage.kt @@ -0,0 +1,15 @@ +package dev.inmo.tgbotapi.types.message + +import com.soywiz.klock.DateTime +import dev.inmo.tgbotapi.types.MessageIdentifier +import dev.inmo.tgbotapi.types.chat.abstracts.ChannelChat +import dev.inmo.tgbotapi.types.chat.abstracts.PrivateChat +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PrivateEvent +import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage + +data class PrivateEventMessage( + override val messageId: MessageIdentifier, + override val chat: PrivateChat, + override val chatEvent: T, + override val date: DateTime +) : ChatEventMessage diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/PrivateMessageImpl.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/PrivateMessageImpl.kt index 75a928c049..599fce4c76 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/PrivateMessageImpl.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/PrivateMessageImpl.kt @@ -7,7 +7,7 @@ import dev.inmo.tgbotapi.types.chat.abstracts.Chat import dev.inmo.tgbotapi.types.message.abstracts.Message import dev.inmo.tgbotapi.types.message.abstracts.PrivateContentMessage import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent -import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentInfo +import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent data class PrivateContentMessageImpl( override val messageId: MessageIdentifier, @@ -20,5 +20,7 @@ data class PrivateContentMessageImpl( override val replyTo: Message?, override val replyMarkup: InlineKeyboardMarkup?, override val senderBot: CommonBot?, - val paymentInfo: SuccessfulPaymentInfo? -) : PrivateContentMessage +) : PrivateContentMessage { + @Deprecated("This value will always be null. You may get SuccessfulPayment as one of ChatEvents") + val paymentInfo: SuccessfulPaymentEvent? = null +} diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt index 086b33b792..c17051fd19 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/RawMessage.kt @@ -17,8 +17,7 @@ import dev.inmo.tgbotapi.types.message.abstracts.UnknownMessageType import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent import dev.inmo.tgbotapi.types.message.content.media.* -import dev.inmo.tgbotapi.types.message.payments.InvoiceContent -import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentInfo +import dev.inmo.tgbotapi.types.message.payments.* import dev.inmo.tgbotapi.types.passport.PassportData import dev.inmo.tgbotapi.types.payments.Invoice import dev.inmo.tgbotapi.types.payments.SuccessfulPayment @@ -197,18 +196,11 @@ internal data class RawMessage( channel_chat_created -> ChannelChatCreated() pinned_message != null -> PinnedMessage(pinned_message.asMessage) proximity_alert_triggered != null -> proximity_alert_triggered + successful_payment != null -> SuccessfulPaymentEvent(successful_payment) else -> null } } - private val paymentInfo: SuccessfulPaymentInfo? by lazy { - when { - successful_payment != null -> SuccessfulPaymentInfo(successful_payment) - else -> null - } - } - - val asMessage: Message by lazy { try { chatEvent?.let { chatEvent -> @@ -233,6 +225,12 @@ internal data class RawMessage( chatEvent as? ChannelEvent ?: throwWrongChatEvent(ChannelEvent::class, chatEvent), date.asDate ) + is PrivateChat -> PrivateEventMessage( + messageId, + chat, + chatEvent as? PrivateEvent ?: throwWrongChatEvent(PrivateEvent::class, chatEvent), + date.asDate + ) else -> error("Expected one of the public chats, but was $chat (in extracting of chat event message)") } } ?: content?.let { content -> @@ -335,8 +333,7 @@ internal data class RawMessage( forwarded, reply_to_message?.asMessage, reply_markup, - via_bot, - paymentInfo + via_bot ) else -> error("Unknown type of chat: $chat") } @@ -359,7 +356,7 @@ internal data class RawMessage( } } - private fun throwWrongChatEvent(expected: KClass<*>, but: ChatEvent): CommonEvent { + private fun throwWrongChatEvent(expected: KClass<*>, but: ChatEvent): Nothing { error("Wrong type of chat event: expected $expected, but was $but") } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/payments/SuccessfulPaymentEvent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/payments/SuccessfulPaymentEvent.kt new file mode 100644 index 0000000000..e981ab08a4 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/payments/SuccessfulPaymentEvent.kt @@ -0,0 +1,11 @@ +package dev.inmo.tgbotapi.types.message.payments + +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.CommonEvent +import dev.inmo.tgbotapi.types.message.payments.abstracts.PaymentInfo +import dev.inmo.tgbotapi.types.payments.SuccessfulPayment + +@Deprecated("Renamed", ReplaceWith("SuccessfulPaymentEvent", "dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent")) +typealias SuccessfulPaymentInfo = SuccessfulPaymentEvent +data class SuccessfulPaymentEvent( + val payment: SuccessfulPayment +) : PaymentInfo, CommonEvent diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/payments/SuccessfulPaymentInfo.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/payments/SuccessfulPaymentInfo.kt deleted file mode 100644 index 50a1620155..0000000000 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/payments/SuccessfulPaymentInfo.kt +++ /dev/null @@ -1,8 +0,0 @@ -package dev.inmo.tgbotapi.types.message.payments - -import dev.inmo.tgbotapi.types.message.payments.abstracts.PaymentInfo -import dev.inmo.tgbotapi.types.payments.SuccessfulPayment - -data class SuccessfulPaymentInfo( - val payment: SuccessfulPayment -) : PaymentInfo diff --git a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEventAction.kt b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEventAction.kt index c0f7d534be..96b5de3c83 100644 --- a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEventAction.kt +++ b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitEventAction.kt @@ -11,6 +11,7 @@ import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.* import dev.inmo.tgbotapi.types.message.ChatEvents.voice.* import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage +import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent import kotlinx.coroutines.flow.toList typealias EventMessageToEventMapper = suspend ChatEventMessage.() -> T? @@ -72,6 +73,14 @@ suspend fun BehaviourContext.waitChannelEvents( mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitPrivateEvents( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: EventMessageToEventMapper? = null +) = waitEvents(count, initRequest, errorFactory, filter, mapper) + suspend fun BehaviourContext.waitChatEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, @@ -117,6 +126,14 @@ suspend fun BehaviourContext.waitMessageAutoDeleteTimerChangedEvents( mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) + +suspend fun BehaviourContext.waitCommonGroupEvents( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: EventMessageToEventMapper? = null +) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitCommonEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, @@ -124,6 +141,7 @@ suspend fun BehaviourContext.waitCommonEvents( filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) + suspend fun BehaviourContext.waitGroupEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, @@ -209,3 +227,10 @@ suspend fun BehaviourContext.waitSupergroupChatCreatedEvents( filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) +suspend fun BehaviourContext.waitSuccessfulPaymentEvents( + initRequest: Request<*>? = null, + errorFactory: NullableRequestBuilder<*> = { null }, + count: Int = 1, + filter: SimpleFilter>? = null, + mapper: EventMessageToEventMapper? = null +) = waitEvents(count, initRequest, errorFactory, filter, mapper) diff --git a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/EventTriggers.kt b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/EventTriggers.kt index 52876f5374..1ee51b3c6c 100644 --- a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/EventTriggers.kt +++ b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/EventTriggers.kt @@ -13,6 +13,7 @@ import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.* import dev.inmo.tgbotapi.types.message.ChatEvents.voice.* import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage +import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent import dev.inmo.tgbotapi.types.update.abstracts.Update internal suspend inline fun BehaviourContext.onEvent( @@ -43,6 +44,25 @@ suspend fun BehaviourContext.onChannelEvent( scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(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, + * 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 BehaviourContext.onPrivateEvent( + initialFilter: SimpleFilter>? = null, + subcontextUpdatesFilter: BehaviourContextAndTwoTypesReceiver, Update>? = MessageFilterByChat, + markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, + scenarioReceiver: BehaviourContextAndTypeReceiver> +) = onEvent(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, @@ -157,6 +177,25 @@ suspend fun BehaviourContext.onMessageAutoDeleteTimerChangedEvent( scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(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, + * 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 BehaviourContext.onCommonGroupEvent( + initialFilter: SimpleFilter>? = null, + subcontextUpdatesFilter: BehaviourContextAndTwoTypesReceiver, Update>? = MessageFilterByChat, + markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, + scenarioReceiver: BehaviourContextAndTypeReceiver> +) = onEvent(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, @@ -403,3 +442,22 @@ suspend fun BehaviourContext.onSupergroupChatCreated( markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, scenarioReceiver: BehaviourContextAndTypeReceiver> ) = onEvent(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, + * 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 BehaviourContext.onSuccessfulPayment( + initialFilter: SimpleFilter>? = null, + subcontextUpdatesFilter: BehaviourContextAndTwoTypesReceiver, Update>? = MessageFilterByChat, + markerFactory: MarkerFactory, Any> = ByChatMessageMarkerFactory, + scenarioReceiver: BehaviourContextAndTypeReceiver> +) = onEvent(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver) diff --git a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt index c56c3c44f3..61e18f89c6 100644 --- a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt +++ b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt @@ -1092,6 +1092,15 @@ inline fun Message.asGroupEventMessage(): GroupEventMessage? = this @PreviewFeature inline fun Message.requireGroupEventMessage(): GroupEventMessage = this as GroupEventMessage +@PreviewFeature +inline fun Message.whenPrivateEventMessage(block: (PrivateEventMessage) -> T) = asPrivateEventMessage() ?.let(block) + +@PreviewFeature +inline fun Message.asPrivateEventMessage(): PrivateEventMessage? = this as? PrivateEventMessage + +@PreviewFeature +inline fun Message.requirePrivateEventMessage(): PrivateEventMessage = this as PrivateEventMessage + @PreviewFeature inline fun Message.whenGroupContentMessage(block: (GroupContentMessage) -> T) = asGroupContentMessage() ?.let(block) @@ -3034,13 +3043,13 @@ inline fun ChatEvent.asChannelEvent(): ChannelEvent? = this as? ChannelEvent inline fun ChatEvent.requireChannelEvent(): ChannelEvent = this as ChannelEvent @PreviewFeature -inline fun ChatEvent.whenCommonEvent(block: (CommonEvent) -> T) = asCommonEvent() ?.let(block) +inline fun ChatEvent.whenCommonEvent(block: (CommonGroupEvent) -> T) = asCommonEvent() ?.let(block) @PreviewFeature -inline fun ChatEvent.asCommonEvent(): CommonEvent? = this as? CommonEvent +inline fun ChatEvent.asCommonEvent(): CommonGroupEvent? = this as? CommonGroupEvent @PreviewFeature -inline fun ChatEvent.requireCommonEvent(): CommonEvent = this as CommonEvent +inline fun ChatEvent.requireCommonEvent(): CommonGroupEvent = this as CommonGroupEvent @PreviewFeature inline fun ChatEvent.whenGroupEvent(block: (GroupEvent) -> T) = asGroupEvent() ?.let(block) diff --git a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/EventsShortcuts.kt b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/EventsShortcuts.kt index e51288d803..6746cb2e15 100644 --- a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/EventsShortcuts.kt +++ b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/EventsShortcuts.kt @@ -6,7 +6,10 @@ import dev.inmo.micro_utils.coroutines.plus import dev.inmo.tgbotapi.types.message.ChannelEventMessage import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.* +import dev.inmo.tgbotapi.types.message.PrivateEventMessage import dev.inmo.tgbotapi.types.message.abstracts.* +import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent +import dev.inmo.tgbotapi.types.payments.SuccessfulPayment import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter import dev.inmo.tgbotapi.utils.RiskFeature import kotlinx.coroutines.flow.Flow @@ -32,6 +35,11 @@ inline fun FlowsUpdatesFilter.supergroupEvents(): Flow it.data as? SupergroupEventMessage<*> } +@RiskFeature("Use with caution") +inline fun FlowsUpdatesFilter.privateEvents(): Flow> = messagesFlow.mapNotNull { + it.data as? PrivateEventMessage<*> +} + @RiskFeature("Use with caution") inline fun > Flow>.filterByChatEvent(): Flow = mapNotNull { if (it.chatEvent is T) it as? O else null @@ -51,6 +59,8 @@ inline fun Flow>.newChannelTitleEvents() = filterChannelEven inline fun FlowsUpdatesFilter.newChannelTitleEvents() = filterChannelEvents() inline fun Flow>.newChannelPinnedMessageEvents() = filterChannelEvents() inline fun FlowsUpdatesFilter.newChannelPinnedMessageEvents() = filterChannelEvents() +inline fun Flow>.successfulPaymentInChannelEvents() = filterChannelEvents() +inline fun FlowsUpdatesFilter.successfulPaymentInChannelEvents() = filterChannelEvents() inline fun Flow>.channelEvents() = filterChannelEvents() @RiskFeature("Use with caution") @@ -73,6 +83,8 @@ inline fun Flow>.newGroupPinnedMessageEvents() = filterGroup inline fun FlowsUpdatesFilter.newGroupPinnedMessageEvents() = filterGroupEvents() inline fun Flow>.proximityAlertTriggeredInGroupEvents() = filterGroupEvents() inline fun FlowsUpdatesFilter.proximityAlertTriggeredInGroupEvents() = filterGroupEvents() +inline fun Flow>.successfulPaymentInGroupEvents() = filterGroupEvents() +inline fun FlowsUpdatesFilter.successfulPaymentInGroupEvents() = filterGroupEvents() inline fun Flow>.groupEvents() = filterGroupEvents() @@ -96,4 +108,16 @@ inline fun Flow>.newSupergroupPinnedMessageEvents() = filter inline fun FlowsUpdatesFilter.newSupergroupPinnedMessageEvents() = filterSupergroupEvents() inline fun Flow>.proximityAlertTriggeredInSupergroupEvents() = filterSupergroupEvents() inline fun FlowsUpdatesFilter.proximityAlertTriggeredInSupergroupEvents() = filterSupergroupEvents() +inline fun Flow>.successfulPaymentInSupergroupEvents() = filterSupergroupEvents() +inline fun FlowsUpdatesFilter.successfulPaymentInSupergroupEvents() = filterSupergroupEvents() inline fun Flow>.supergroupEvents() = filterSupergroupEvents() + +@RiskFeature("Use with caution") +inline fun Flow>.filterPrivateEvents() = filterByChatEvent>() +@RiskFeature("Use with caution") +inline fun FlowsUpdatesFilter.filterPrivateEvents() = privateEvents().filterByChatEvent>() +inline fun Flow>.successfulPaymentInPrivateEvents() = filterPrivateEvents() +inline fun FlowsUpdatesFilter.successfulPaymentInPrivateEvents() = filterPrivateEvents() +inline fun Flow>.newPrivatePinnedMessageEvents() = filterPrivateEvents() +inline fun FlowsUpdatesFilter.newPrivatePinnedMessageEvents() = filterPrivateEvents() +inline fun Flow>.privateEvents() = filterPrivateEvents()