mirror of
				https://github.com/InsanusMokrassar/TelegramBotAPI.git
				synced 2025-10-25 17:20:07 +00:00 
			
		
		
		
	add workarounds for reactions
This commit is contained in:
		| @@ -0,0 +1,31 @@ | |||||||
|  | package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations | ||||||
|  |  | ||||||
|  | import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext | ||||||
|  | import dev.inmo.tgbotapi.extensions.utils.chatMessageReactionUpdatedUpdateOrNull | ||||||
|  | import dev.inmo.tgbotapi.requests.abstracts.Request | ||||||
|  | import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated | ||||||
|  | import dev.inmo.tgbotapi.utils.RiskFeature | ||||||
|  | import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage | ||||||
|  | import kotlinx.coroutines.flow.Flow | ||||||
|  |  | ||||||
|  | @RiskFeature(lowLevelRiskFeatureMessage) | ||||||
|  | suspend inline fun <reified O : ChatMessageReactionUpdated> BehaviourContext.waitChatMessageReactionUpdated( | ||||||
|  |     initRequest: Request<*>? = null, | ||||||
|  |     noinline errorFactory: NullableRequestBuilder<*> = { null } | ||||||
|  | ): Flow<O> = expectFlow( | ||||||
|  |     initRequest, | ||||||
|  |     errorFactory | ||||||
|  | ) { | ||||||
|  |     (it.chatMessageReactionUpdatedUpdateOrNull() ?.data as? O).let(::listOfNotNull) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | suspend fun BehaviourContext.waitChatMessageReactionUpdatedByUser( | ||||||
|  |     initRequest: Request<*>? = null, | ||||||
|  |     errorFactory: NullableRequestBuilder<*> = { null } | ||||||
|  | ) = waitChatMessageReactionUpdated<ChatMessageReactionUpdated.ByUser>(initRequest, errorFactory) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | suspend fun BehaviourContext.waitChatMessageReactionUpdatedByChat( | ||||||
|  |     initRequest: Request<*>? = null, | ||||||
|  |     errorFactory: NullableRequestBuilder<*> = { null } | ||||||
|  | ) = waitChatMessageReactionUpdated<ChatMessageReactionUpdated.ByChat>(initRequest, errorFactory) | ||||||
| @@ -0,0 +1,21 @@ | |||||||
|  | package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations | ||||||
|  |  | ||||||
|  | import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext | ||||||
|  | import dev.inmo.tgbotapi.extensions.utils.chatMessageReactionUpdatedUpdateOrNull | ||||||
|  | import dev.inmo.tgbotapi.extensions.utils.chatMessageReactionsCountUpdatedUpdateOrNull | ||||||
|  | import dev.inmo.tgbotapi.requests.abstracts.Request | ||||||
|  | import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated | ||||||
|  | import dev.inmo.tgbotapi.types.chat.ChatMessageReactionsCountUpdated | ||||||
|  | import dev.inmo.tgbotapi.utils.RiskFeature | ||||||
|  | import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage | ||||||
|  | import kotlinx.coroutines.flow.Flow | ||||||
|  |  | ||||||
|  | suspend inline fun BehaviourContext.waitChatMessageReactionsCountUpdated( | ||||||
|  |     initRequest: Request<*>? = null, | ||||||
|  |     noinline errorFactory: NullableRequestBuilder<*> = { null } | ||||||
|  | ): Flow<ChatMessageReactionsCountUpdated> = expectFlow( | ||||||
|  |     initRequest, | ||||||
|  |     errorFactory | ||||||
|  | ) { | ||||||
|  |     (it.chatMessageReactionsCountUpdatedUpdateOrNull() ?.data).let(::listOfNotNull) | ||||||
|  | } | ||||||
| @@ -0,0 +1,94 @@ | |||||||
|  | @file:Suppress("unused") | ||||||
|  |  | ||||||
|  | package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling | ||||||
|  |  | ||||||
|  | import dev.inmo.tgbotapi.extensions.behaviour_builder.* | ||||||
|  | import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter | ||||||
|  | import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatIdChatMessageReactionUpdatedMarkerFactory | ||||||
|  | import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByIdPollMarkerFactory | ||||||
|  | import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory | ||||||
|  | import dev.inmo.tgbotapi.extensions.utils.chatMessageReactionUpdatedUpdateOrNull | ||||||
|  | import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated | ||||||
|  | import dev.inmo.tgbotapi.types.polls.* | ||||||
|  | import dev.inmo.tgbotapi.types.update.abstracts.Update | ||||||
|  |  | ||||||
|  | internal suspend inline fun <BC : BehaviourContext, reified T : ChatMessageReactionUpdated> BC.onChatMessageReactionUpdated( | ||||||
|  |     initialFilter: SimpleFilter<T>? = null, | ||||||
|  |     noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, T, Update>? = null, | ||||||
|  |     markerFactory: MarkerFactory<in T, Any> = ByChatIdChatMessageReactionUpdatedMarkerFactory, | ||||||
|  |     noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, T> | ||||||
|  | ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) { | ||||||
|  |     (it.chatMessageReactionUpdatedUpdateOrNull() ?.data as? T) ?.let(::listOfNotNull) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @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 : BehaviourContext> BC.onChatMessageReactionUpdatedByUser( | ||||||
|  |     initialFilter: SimpleFilter<ChatMessageReactionUpdated.ByUser>? = null, | ||||||
|  |     subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatMessageReactionUpdated.ByUser, Update>? = null, | ||||||
|  |     markerFactory: MarkerFactory<in ChatMessageReactionUpdated.ByUser, Any> = ByChatIdChatMessageReactionUpdatedMarkerFactory, | ||||||
|  |     scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatMessageReactionUpdated.ByUser> | ||||||
|  | ) = onChatMessageReactionUpdated( | ||||||
|  |     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 <BC : BehaviourContext> BC.onChatMessageReactionUpdatedByChat( | ||||||
|  |     initialFilter: SimpleFilter<ChatMessageReactionUpdated.ByChat>? = null, | ||||||
|  |     subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatMessageReactionUpdated.ByChat, Update>? = null, | ||||||
|  |     markerFactory: MarkerFactory<in ChatMessageReactionUpdated.ByChat, Any> = ByChatIdChatMessageReactionUpdatedMarkerFactory, | ||||||
|  |     scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatMessageReactionUpdated.ByChat> | ||||||
|  | ) = onChatMessageReactionUpdated( | ||||||
|  |     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 <BC : BehaviourContext> BC.onChatMessageReactionUpdatedUnknown( | ||||||
|  |     initialFilter: SimpleFilter<ChatMessageReactionUpdated.Unknown>? = null, | ||||||
|  |     subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatMessageReactionUpdated.Unknown, Update>? = null, | ||||||
|  |     markerFactory: MarkerFactory<in ChatMessageReactionUpdated.Unknown, Any> = ByChatIdChatMessageReactionUpdatedMarkerFactory, | ||||||
|  |     scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatMessageReactionUpdated.Unknown> | ||||||
|  | ) = onChatMessageReactionUpdated( | ||||||
|  |     initialFilter, | ||||||
|  |     subcontextUpdatesFilter, | ||||||
|  |     markerFactory, | ||||||
|  |     scenarioReceiver | ||||||
|  | ) | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | package dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories | ||||||
|  |  | ||||||
|  | import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated | ||||||
|  |  | ||||||
|  | object ByChatIdChatMessageReactionUpdatedMarkerFactory : MarkerFactory<ChatMessageReactionUpdated, Any> { | ||||||
|  |     override suspend fun invoke(data: ChatMessageReactionUpdated) = data.chat.id | ||||||
|  | } | ||||||
| @@ -196,6 +196,7 @@ const val tgWebAppStartParamField = "tgWebAppStartParam" | |||||||
| const val chatIdField = "chat_id" | const val chatIdField = "chat_id" | ||||||
| const val senderChatIdField = "sender_chat_id" | const val senderChatIdField = "sender_chat_id" | ||||||
| const val messageIdField = "message_id" | const val messageIdField = "message_id" | ||||||
|  | const val actorChatField = "actor_chat" | ||||||
| const val messageThreadIdField = "message_thread_id" | const val messageThreadIdField = "message_thread_id" | ||||||
| const val mediaGroupIdField = "media_group_id" | const val mediaGroupIdField = "media_group_id" | ||||||
| const val updateIdField = "update_id" | const val updateIdField = "update_id" | ||||||
| @@ -461,6 +462,9 @@ const val fromField = "from" | |||||||
| const val userChatIdField = "user_chat_id" | const val userChatIdField = "user_chat_id" | ||||||
| const val userField = "user" | const val userField = "user" | ||||||
| const val dateField = "date" | const val dateField = "date" | ||||||
|  | const val reactionsField = "reactions" | ||||||
|  | const val oldReactionField = "old_reaction" | ||||||
|  | const val newReactionField = "new_reaction" | ||||||
| const val chatField = "chat" | const val chatField = "chat" | ||||||
| const val usernameField = "username" | const val usernameField = "username" | ||||||
| const val bioField = "bio" | const val bioField = "bio" | ||||||
| @@ -524,6 +528,7 @@ const val shippingQueryIdField = "shipping_query_id" | |||||||
| const val preCheckoutQueryIdField = "pre_checkout_query_id" | const val preCheckoutQueryIdField = "pre_checkout_query_id" | ||||||
| const val shippingOptionsField = "shipping_options" | const val shippingOptionsField = "shipping_options" | ||||||
| const val countryCodeField = "country_code" | const val countryCodeField = "country_code" | ||||||
|  | const val totalCountField = "total_count" | ||||||
| const val stateField = "state" | const val stateField = "state" | ||||||
| const val cityField = "city" | const val cityField = "city" | ||||||
| const val firstStreetLineField = "street_line1" | const val firstStreetLineField = "street_line1" | ||||||
|   | |||||||
| @@ -14,8 +14,29 @@ const val UPDATE_POLL_ANSWER = "poll_answer" | |||||||
| const val UPDATE_MY_CHAT_MEMBER = "my_chat_member" | const val UPDATE_MY_CHAT_MEMBER = "my_chat_member" | ||||||
| const val UPDATE_CHAT_MEMBER = "chat_member" | const val UPDATE_CHAT_MEMBER = "chat_member" | ||||||
| const val UPDATE_CHAT_JOIN_REQUEST = "chat_join_request" | const val UPDATE_CHAT_JOIN_REQUEST = "chat_join_request" | ||||||
|  | const val UPDATE_MESSAGE_REACTION = "message_reaction" | ||||||
|  | const val UPDATE_MESSAGE_REACTION_COUNT = "message_reaction_count" | ||||||
|  |  | ||||||
| val ALL_UPDATES_LIST = listOf( | val ALL_UPDATES_LIST = listOf( | ||||||
|  |     UPDATE_MESSAGE, | ||||||
|  |     UPDATE_EDITED_MESSAGE, | ||||||
|  |     UPDATE_CHANNEL_POST, | ||||||
|  |     UPDATE_EDITED_CHANNEL_POST, | ||||||
|  |     UPDATE_CHOSEN_INLINE_RESULT, | ||||||
|  |     UPDATE_INLINE_QUERY, | ||||||
|  |     UPDATE_CALLBACK_QUERY, | ||||||
|  |     UPDATE_SHIPPING_QUERY, | ||||||
|  |     UPDATE_PRE_CHECKOUT_QUERY, | ||||||
|  |     UPDATE_POLL, | ||||||
|  |     UPDATE_POLL_ANSWER, | ||||||
|  |     UPDATE_MY_CHAT_MEMBER, | ||||||
|  |     UPDATE_CHAT_MEMBER, | ||||||
|  |     UPDATE_CHAT_JOIN_REQUEST, | ||||||
|  |     UPDATE_MESSAGE_REACTION, | ||||||
|  |     UPDATE_MESSAGE_REACTION_COUNT | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | val ALL_UPDATES_LIST_WITHOUT_REACTIONS = listOf( | ||||||
|     UPDATE_MESSAGE, |     UPDATE_MESSAGE, | ||||||
|     UPDATE_EDITED_MESSAGE, |     UPDATE_EDITED_MESSAGE, | ||||||
|     UPDATE_CHANNEL_POST, |     UPDATE_CHANNEL_POST, | ||||||
|   | |||||||
| @@ -0,0 +1,162 @@ | |||||||
|  | package dev.inmo.tgbotapi.types.chat | ||||||
|  |  | ||||||
|  | import dev.inmo.tgbotapi.types.* | ||||||
|  | import dev.inmo.tgbotapi.types.reactions.Reaction | ||||||
|  | import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded | ||||||
|  | import kotlinx.serialization.KSerializer | ||||||
|  | import kotlinx.serialization.SerialName | ||||||
|  | import kotlinx.serialization.Serializable | ||||||
|  | import kotlinx.serialization.descriptors.SerialDescriptor | ||||||
|  | import kotlinx.serialization.encoding.Decoder | ||||||
|  | import kotlinx.serialization.encoding.Encoder | ||||||
|  | import kotlinx.serialization.json.JsonDecoder | ||||||
|  | import kotlinx.serialization.json.JsonElement | ||||||
|  |  | ||||||
|  | @Serializable(ChatMessageReactionUpdated.Companion::class) | ||||||
|  | @ClassCastsIncluded | ||||||
|  | sealed interface ChatMessageReactionUpdated { | ||||||
|  |     val chat: PreviewChat | ||||||
|  |     val messageId: MessageIdentifier | ||||||
|  |     val reactedUser: PreviewUser? | ||||||
|  |     val reactedChat: PreviewChat? | ||||||
|  |     val date: TelegramDate | ||||||
|  |     val old: List<Reaction> | ||||||
|  |     val new: List<Reaction> | ||||||
|  |  | ||||||
|  |     @Serializable(Companion::class) | ||||||
|  |     data class ByUser( | ||||||
|  |         @SerialName(chatField) | ||||||
|  |         override val chat: PreviewChat, | ||||||
|  |         @SerialName(messageIdField) | ||||||
|  |         override val messageId: MessageIdentifier, | ||||||
|  |         @SerialName(userField) | ||||||
|  |         override val reactedUser: PreviewUser, | ||||||
|  |         @Serializable(TelegramDateSerializer::class) | ||||||
|  |         @SerialName(dateField) | ||||||
|  |         override val date: TelegramDate, | ||||||
|  |         @SerialName(oldReactionField) | ||||||
|  |         override val old: List<Reaction>, | ||||||
|  |         @SerialName(newReactionField) | ||||||
|  |         override val new: List<Reaction> | ||||||
|  |     ) : ChatMessageReactionUpdated { | ||||||
|  |         override val reactedChat: PreviewChat? | ||||||
|  |             get() = null | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Serializable(Companion::class) | ||||||
|  |     data class ByChat( | ||||||
|  |         @SerialName(chatField) | ||||||
|  |         override val chat: PreviewChat, | ||||||
|  |         @SerialName(messageIdField) | ||||||
|  |         override val messageId: MessageIdentifier, | ||||||
|  |         @SerialName(actorChatField) | ||||||
|  |         override val reactedChat: PreviewChat, | ||||||
|  |         @Serializable(TelegramDateSerializer::class) | ||||||
|  |         @SerialName(dateField) | ||||||
|  |         override val date: TelegramDate, | ||||||
|  |         @SerialName(oldReactionField) | ||||||
|  |         override val old: List<Reaction>, | ||||||
|  |         @SerialName(newReactionField) | ||||||
|  |         override val new: List<Reaction> | ||||||
|  |     ) : ChatMessageReactionUpdated { | ||||||
|  |         override val reactedUser: PreviewUser? | ||||||
|  |             get() = null | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Serializable(Companion::class) | ||||||
|  |     data class Unknown( | ||||||
|  |         @SerialName(chatField) | ||||||
|  |         override val chat: PreviewChat, | ||||||
|  |         @SerialName(messageIdField) | ||||||
|  |         override val messageId: MessageIdentifier, | ||||||
|  |         @SerialName(actorChatField) | ||||||
|  |         override val reactedChat: PreviewChat?, | ||||||
|  |         @SerialName(userField) | ||||||
|  |         override val reactedUser: PreviewUser?, | ||||||
|  |         @Serializable(TelegramDateSerializer::class) | ||||||
|  |         @SerialName(dateField) | ||||||
|  |         override val date: TelegramDate, | ||||||
|  |         @SerialName(oldReactionField) | ||||||
|  |         override val old: List<Reaction>, | ||||||
|  |         @SerialName(newReactionField) | ||||||
|  |         override val new: List<Reaction>, | ||||||
|  |         val source: JsonElement? | ||||||
|  |     ) : ChatMessageReactionUpdated | ||||||
|  |  | ||||||
|  |     @Serializable | ||||||
|  |     data class Surrogate internal constructor( | ||||||
|  |         @SerialName(chatField) | ||||||
|  |         val chat: PreviewChat, | ||||||
|  |         @SerialName(messageIdField) | ||||||
|  |         val messageId: MessageIdentifier, | ||||||
|  |         @SerialName(userField) | ||||||
|  |         val reactedUser: PreviewUser? = null, | ||||||
|  |         @SerialName(actorChatField) | ||||||
|  |         val reactedChat: PreviewChat? = null, | ||||||
|  |         @Serializable(TelegramDateSerializer::class) | ||||||
|  |         @SerialName(dateField) | ||||||
|  |         val date: TelegramDate, | ||||||
|  |         @SerialName(oldReactionField) | ||||||
|  |         val old: List<Reaction>, | ||||||
|  |         @SerialName(newReactionField) | ||||||
|  |         val new: List<Reaction> | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     companion object : KSerializer<ChatMessageReactionUpdated> { | ||||||
|  |         override val descriptor: SerialDescriptor | ||||||
|  |             get() = Surrogate.serializer().descriptor | ||||||
|  |  | ||||||
|  |         override fun deserialize(decoder: Decoder): ChatMessageReactionUpdated { | ||||||
|  |             val (surrogate, jsonElement) = if (decoder is JsonDecoder) { | ||||||
|  |                 val jsonElement = decoder.decodeJsonElement() | ||||||
|  |                 decoder.json.decodeFromJsonElement(Surrogate.serializer(), jsonElement) to jsonElement | ||||||
|  |             } else { | ||||||
|  |                 Surrogate.serializer().deserialize(decoder) to null | ||||||
|  |             } | ||||||
|  |             return when { | ||||||
|  |                 surrogate.reactedUser != null -> ByUser( | ||||||
|  |                     surrogate.chat, | ||||||
|  |                     surrogate.messageId, | ||||||
|  |                     surrogate.reactedUser, | ||||||
|  |                     surrogate.date, | ||||||
|  |                     surrogate.old, | ||||||
|  |                     surrogate.new | ||||||
|  |                 ) | ||||||
|  |                 surrogate.reactedChat != null -> ByChat( | ||||||
|  |                     surrogate.chat, | ||||||
|  |                     surrogate.messageId, | ||||||
|  |                     surrogate.reactedChat, | ||||||
|  |                     surrogate.date, | ||||||
|  |                     surrogate.old, | ||||||
|  |                     surrogate.new | ||||||
|  |                 ) | ||||||
|  |                 else -> Unknown( | ||||||
|  |                     surrogate.chat, | ||||||
|  |                     surrogate.messageId, | ||||||
|  |                     surrogate.reactedUser, | ||||||
|  |                     surrogate.reactedChat, | ||||||
|  |                     surrogate.date, | ||||||
|  |                     surrogate.old, | ||||||
|  |                     surrogate.new, | ||||||
|  |                     jsonElement | ||||||
|  |                 ) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         override fun serialize(encoder: Encoder, value: ChatMessageReactionUpdated) { | ||||||
|  |             if (value is Unknown && value.source != null) { | ||||||
|  |                 JsonElement.serializer().serialize(encoder, value.source) | ||||||
|  |             } else { | ||||||
|  |                 Surrogate( | ||||||
|  |                     value.chat, | ||||||
|  |                     value.messageId, | ||||||
|  |                     value.reactedUser, | ||||||
|  |                     value.reactedChat, | ||||||
|  |                     value.date, | ||||||
|  |                     value.old, | ||||||
|  |                     value.new | ||||||
|  |                 ) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,19 @@ | |||||||
|  | package dev.inmo.tgbotapi.types.chat | ||||||
|  |  | ||||||
|  | import dev.inmo.tgbotapi.types.* | ||||||
|  | import dev.inmo.tgbotapi.types.reactions.ReactionsCount | ||||||
|  | import kotlinx.serialization.SerialName | ||||||
|  | import kotlinx.serialization.Serializable | ||||||
|  |  | ||||||
|  | @Serializable | ||||||
|  | data class ChatMessageReactionsCountUpdated( | ||||||
|  |     @SerialName(chatField) | ||||||
|  |     val chat: PreviewChat, | ||||||
|  |     @SerialName(messageIdField) | ||||||
|  |     val messageId: MessageIdentifier, | ||||||
|  |     @Serializable(TelegramDateSerializer::class) | ||||||
|  |     @SerialName(dateField) | ||||||
|  |     val date: TelegramDate, | ||||||
|  |     @SerialName(reactionsField) | ||||||
|  |     val reactions: List<ReactionsCount> | ||||||
|  | ) | ||||||
| @@ -13,7 +13,7 @@ import kotlinx.serialization.encoding.Encoder | |||||||
| import kotlinx.serialization.json.JsonDecoder | import kotlinx.serialization.json.JsonDecoder | ||||||
| import kotlinx.serialization.json.JsonElement | import kotlinx.serialization.json.JsonElement | ||||||
|  |  | ||||||
| @Serializable | @Serializable(Reaction.Companion::class) | ||||||
| @ClassCastsIncluded | @ClassCastsIncluded | ||||||
| sealed interface Reaction { | sealed interface Reaction { | ||||||
|     val type: String |     val type: String | ||||||
|   | |||||||
| @@ -0,0 +1,14 @@ | |||||||
|  | package dev.inmo.tgbotapi.types.reactions | ||||||
|  |  | ||||||
|  | import dev.inmo.tgbotapi.types.totalCountField | ||||||
|  | import dev.inmo.tgbotapi.types.typeField | ||||||
|  | import kotlinx.serialization.SerialName | ||||||
|  | import kotlinx.serialization.Serializable | ||||||
|  |  | ||||||
|  | @Serializable | ||||||
|  | data class ReactionsCount( | ||||||
|  |     @SerialName(typeField) | ||||||
|  |     val reaction: Reaction, | ||||||
|  |     @SerialName(totalCountField) | ||||||
|  |     val count: Int | ||||||
|  | ) | ||||||
| @@ -0,0 +1,12 @@ | |||||||
|  | package dev.inmo.tgbotapi.types.update | ||||||
|  |  | ||||||
|  | import dev.inmo.tgbotapi.types.UpdateIdentifier | ||||||
|  | import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated | ||||||
|  | import dev.inmo.tgbotapi.types.update.abstracts.Update | ||||||
|  | import kotlinx.serialization.Serializable | ||||||
|  |  | ||||||
|  | @Serializable | ||||||
|  | data class ChatMessageReactionUpdatedUpdate( | ||||||
|  |     override val updateId: UpdateIdentifier, | ||||||
|  |     override val data: ChatMessageReactionUpdated | ||||||
|  | ) : Update | ||||||
| @@ -0,0 +1,13 @@ | |||||||
|  | package dev.inmo.tgbotapi.types.update | ||||||
|  |  | ||||||
|  | import dev.inmo.tgbotapi.types.UpdateIdentifier | ||||||
|  | import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated | ||||||
|  | import dev.inmo.tgbotapi.types.chat.ChatMessageReactionsCountUpdated | ||||||
|  | import dev.inmo.tgbotapi.types.update.abstracts.Update | ||||||
|  | import kotlinx.serialization.Serializable | ||||||
|  |  | ||||||
|  | @Serializable | ||||||
|  | data class ChatMessageReactionsCountUpdatedUpdate( | ||||||
|  |     override val updateId: UpdateIdentifier, | ||||||
|  |     override val data: ChatMessageReactionsCountUpdated | ||||||
|  | ) : Update | ||||||
| @@ -5,6 +5,8 @@ import dev.inmo.tgbotapi.types.queries.callback.RawCallbackQuery | |||||||
| import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.RawChosenInlineResult | import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.RawChosenInlineResult | ||||||
| import dev.inmo.tgbotapi.types.InlineQueries.query.RawInlineQuery | import dev.inmo.tgbotapi.types.InlineQueries.query.RawInlineQuery | ||||||
| import dev.inmo.tgbotapi.types.chat.ChatJoinRequest | import dev.inmo.tgbotapi.types.chat.ChatJoinRequest | ||||||
|  | import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated | ||||||
|  | import dev.inmo.tgbotapi.types.chat.ChatMessageReactionsCountUpdated | ||||||
| import dev.inmo.tgbotapi.types.chat.member.ChatMemberUpdated | import dev.inmo.tgbotapi.types.chat.member.ChatMemberUpdated | ||||||
| import dev.inmo.tgbotapi.types.message.abstracts.* | import dev.inmo.tgbotapi.types.message.abstracts.* | ||||||
| import dev.inmo.tgbotapi.types.payments.PreCheckoutQuery | import dev.inmo.tgbotapi.types.payments.PreCheckoutQuery | ||||||
| @@ -38,7 +40,9 @@ internal data class RawUpdate constructor( | |||||||
|     private val poll_answer: PollAnswer? = null, |     private val poll_answer: PollAnswer? = null, | ||||||
|     private val my_chat_member: ChatMemberUpdated? = null, |     private val my_chat_member: ChatMemberUpdated? = null, | ||||||
|     private val chat_member: ChatMemberUpdated? = null, |     private val chat_member: ChatMemberUpdated? = null, | ||||||
|     private val chat_join_request: ChatJoinRequest? = null |     private val chat_join_request: ChatJoinRequest? = null, | ||||||
|  |     private val message_reaction: ChatMessageReactionUpdated? = null, | ||||||
|  |     private val message_reaction_count: ChatMessageReactionsCountUpdated? = null | ||||||
| ) { | ) { | ||||||
|     private var initedUpdate: Update? = null |     private var initedUpdate: Update? = null | ||||||
|     /** |     /** | ||||||
| @@ -65,6 +69,8 @@ internal data class RawUpdate constructor( | |||||||
|                 my_chat_member != null -> MyChatMemberUpdatedUpdate(updateId, my_chat_member) |                 my_chat_member != null -> MyChatMemberUpdatedUpdate(updateId, my_chat_member) | ||||||
|                 chat_member != null -> CommonChatMemberUpdatedUpdate(updateId, chat_member) |                 chat_member != null -> CommonChatMemberUpdatedUpdate(updateId, chat_member) | ||||||
|                 chat_join_request != null -> ChatJoinRequestUpdate(updateId, chat_join_request) |                 chat_join_request != null -> ChatJoinRequestUpdate(updateId, chat_join_request) | ||||||
|  |                 message_reaction != null -> ChatMessageReactionUpdatedUpdate(updateId, message_reaction) | ||||||
|  |                 message_reaction_count != null -> ChatMessageReactionsCountUpdatedUpdate(updateId, message_reaction_count) | ||||||
|                 else -> UnknownUpdate( |                 else -> UnknownUpdate( | ||||||
|                     updateId, |                     updateId, | ||||||
|                     raw |                     raw | ||||||
|   | |||||||
| @@ -37,6 +37,8 @@ interface FlowsUpdatesFilter : UpdatesFilter { | |||||||
|     val chatMemberUpdatesFlow: Flow<CommonChatMemberUpdatedUpdate> |     val chatMemberUpdatesFlow: Flow<CommonChatMemberUpdatedUpdate> | ||||||
|     val myChatMemberUpdatesFlow: Flow<MyChatMemberUpdatedUpdate> |     val myChatMemberUpdatesFlow: Flow<MyChatMemberUpdatedUpdate> | ||||||
|     val chatJoinRequestUpdateFlow: Flow<ChatJoinRequestUpdate> |     val chatJoinRequestUpdateFlow: Flow<ChatJoinRequestUpdate> | ||||||
|  |     val chatMessageReactionUpdatedUpdateFlow: Flow<ChatMessageReactionUpdatedUpdate> | ||||||
|  |     val chatMessageReactionsCountUpdatedUpdateFlow: Flow<ChatMessageReactionsCountUpdatedUpdate> | ||||||
|     val unknownUpdatesFlow: Flow<UnknownUpdate> |     val unknownUpdatesFlow: Flow<UnknownUpdate> | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -55,6 +57,8 @@ abstract class AbstractFlowsUpdatesFilter : FlowsUpdatesFilter { | |||||||
|     override val chatMemberUpdatesFlow: Flow<CommonChatMemberUpdatedUpdate> by lazy { allUpdatesFlow.filterIsInstance() } |     override val chatMemberUpdatesFlow: Flow<CommonChatMemberUpdatedUpdate> by lazy { allUpdatesFlow.filterIsInstance() } | ||||||
|     override val myChatMemberUpdatesFlow: Flow<MyChatMemberUpdatedUpdate> by lazy { allUpdatesFlow.filterIsInstance() } |     override val myChatMemberUpdatesFlow: Flow<MyChatMemberUpdatedUpdate> by lazy { allUpdatesFlow.filterIsInstance() } | ||||||
|     override val chatJoinRequestUpdateFlow: Flow<ChatJoinRequestUpdate> by lazy { allUpdatesFlow.filterIsInstance() } |     override val chatJoinRequestUpdateFlow: Flow<ChatJoinRequestUpdate> by lazy { allUpdatesFlow.filterIsInstance() } | ||||||
|  |     override val chatMessageReactionUpdatedUpdateFlow: Flow<ChatMessageReactionUpdatedUpdate> by lazy { allUpdatesFlow.filterIsInstance() } | ||||||
|  |     override val chatMessageReactionsCountUpdatedUpdateFlow: Flow<ChatMessageReactionsCountUpdatedUpdate> by lazy { allUpdatesFlow.filterIsInstance() } | ||||||
|     override val unknownUpdatesFlow: Flow<UnknownUpdate> by lazy { allUpdatesFlow.filterIsInstance() } |     override val unknownUpdatesFlow: Flow<UnknownUpdate> by lazy { allUpdatesFlow.filterIsInstance() } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -112,6 +112,7 @@ import dev.inmo.tgbotapi.types.chat.Bot | |||||||
| import dev.inmo.tgbotapi.types.chat.ChannelChat | import dev.inmo.tgbotapi.types.chat.ChannelChat | ||||||
| import dev.inmo.tgbotapi.types.chat.Chat | import dev.inmo.tgbotapi.types.chat.Chat | ||||||
| import dev.inmo.tgbotapi.types.chat.ChatJoinRequest | import dev.inmo.tgbotapi.types.chat.ChatJoinRequest | ||||||
|  | import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated | ||||||
| import dev.inmo.tgbotapi.types.chat.CommonBot | import dev.inmo.tgbotapi.types.chat.CommonBot | ||||||
| import dev.inmo.tgbotapi.types.chat.CommonUser | import dev.inmo.tgbotapi.types.chat.CommonUser | ||||||
| import dev.inmo.tgbotapi.types.chat.ExtendedBot | import dev.inmo.tgbotapi.types.chat.ExtendedBot | ||||||
| @@ -423,6 +424,8 @@ import dev.inmo.tgbotapi.types.request.UserShared | |||||||
| import dev.inmo.tgbotapi.types.update.CallbackQueryUpdate | import dev.inmo.tgbotapi.types.update.CallbackQueryUpdate | ||||||
| import dev.inmo.tgbotapi.types.update.ChannelPostUpdate | import dev.inmo.tgbotapi.types.update.ChannelPostUpdate | ||||||
| import dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate | import dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate | ||||||
|  | import dev.inmo.tgbotapi.types.update.ChatMessageReactionUpdatedUpdate | ||||||
|  | import dev.inmo.tgbotapi.types.update.ChatMessageReactionsCountUpdatedUpdate | ||||||
| import dev.inmo.tgbotapi.types.update.ChosenInlineResultUpdate | import dev.inmo.tgbotapi.types.update.ChosenInlineResultUpdate | ||||||
| import dev.inmo.tgbotapi.types.update.CommonChatMemberUpdatedUpdate | import dev.inmo.tgbotapi.types.update.CommonChatMemberUpdatedUpdate | ||||||
| import dev.inmo.tgbotapi.types.update.EditChannelPostUpdate | import dev.inmo.tgbotapi.types.update.EditChannelPostUpdate | ||||||
| @@ -2112,6 +2115,36 @@ public inline fun Chat.unknownChatTypeOrThrow(): UnknownChatType = this as | |||||||
| public inline fun <T> Chat.ifUnknownChatType(block: (UnknownChatType) -> T): T? = | public inline fun <T> Chat.ifUnknownChatType(block: (UnknownChatType) -> T): T? = | ||||||
|     unknownChatTypeOrNull() ?.let(block) |     unknownChatTypeOrNull() ?.let(block) | ||||||
|  |  | ||||||
|  | public inline fun ChatMessageReactionUpdated.byChatOrNull(): ChatMessageReactionUpdated.ByChat? = | ||||||
|  |     this as? dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated.ByChat | ||||||
|  |  | ||||||
|  | public inline fun ChatMessageReactionUpdated.byChatOrThrow(): ChatMessageReactionUpdated.ByChat = | ||||||
|  |     this as dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated.ByChat | ||||||
|  |  | ||||||
|  | public inline fun <T> | ||||||
|  |     ChatMessageReactionUpdated.ifByChat(block: (ChatMessageReactionUpdated.ByChat) -> T): T? = | ||||||
|  |     byChatOrNull() ?.let(block) | ||||||
|  |  | ||||||
|  | public inline fun ChatMessageReactionUpdated.byUserOrNull(): ChatMessageReactionUpdated.ByUser? = | ||||||
|  |     this as? dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated.ByUser | ||||||
|  |  | ||||||
|  | public inline fun ChatMessageReactionUpdated.byUserOrThrow(): ChatMessageReactionUpdated.ByUser = | ||||||
|  |     this as dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated.ByUser | ||||||
|  |  | ||||||
|  | public inline fun <T> | ||||||
|  |     ChatMessageReactionUpdated.ifByUser(block: (ChatMessageReactionUpdated.ByUser) -> T): T? = | ||||||
|  |     byUserOrNull() ?.let(block) | ||||||
|  |  | ||||||
|  | public inline fun ChatMessageReactionUpdated.unknownOrNull(): ChatMessageReactionUpdated.Unknown? = | ||||||
|  |     this as? dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated.Unknown | ||||||
|  |  | ||||||
|  | public inline fun ChatMessageReactionUpdated.unknownOrThrow(): ChatMessageReactionUpdated.Unknown = | ||||||
|  |     this as dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated.Unknown | ||||||
|  |  | ||||||
|  | public inline fun <T> | ||||||
|  |     ChatMessageReactionUpdated.ifUnknown(block: (ChatMessageReactionUpdated.Unknown) -> T): T? = | ||||||
|  |     unknownOrNull() ?.let(block) | ||||||
|  |  | ||||||
| public inline fun DiceAnimationType.cubeDiceAnimationTypeOrNull(): CubeDiceAnimationType? = this as? | public inline fun DiceAnimationType.cubeDiceAnimationTypeOrNull(): CubeDiceAnimationType? = this as? | ||||||
|     dev.inmo.tgbotapi.types.dice.CubeDiceAnimationType |     dev.inmo.tgbotapi.types.dice.CubeDiceAnimationType | ||||||
|  |  | ||||||
| @@ -4567,6 +4600,28 @@ public inline fun Update.chatJoinRequestUpdateOrThrow(): ChatJoinRequestUpdate = | |||||||
| public inline fun <T> Update.ifChatJoinRequestUpdate(block: (ChatJoinRequestUpdate) -> T): T? = | public inline fun <T> Update.ifChatJoinRequestUpdate(block: (ChatJoinRequestUpdate) -> T): T? = | ||||||
|     chatJoinRequestUpdateOrNull() ?.let(block) |     chatJoinRequestUpdateOrNull() ?.let(block) | ||||||
|  |  | ||||||
|  | public inline fun Update.chatMessageReactionUpdatedUpdateOrNull(): ChatMessageReactionUpdatedUpdate? | ||||||
|  |     = this as? dev.inmo.tgbotapi.types.update.ChatMessageReactionUpdatedUpdate | ||||||
|  |  | ||||||
|  | public inline fun Update.chatMessageReactionUpdatedUpdateOrThrow(): ChatMessageReactionUpdatedUpdate | ||||||
|  |     = this as dev.inmo.tgbotapi.types.update.ChatMessageReactionUpdatedUpdate | ||||||
|  |  | ||||||
|  | public inline fun <T> | ||||||
|  |     Update.ifChatMessageReactionUpdatedUpdate(block: (ChatMessageReactionUpdatedUpdate) -> T): T? = | ||||||
|  |     chatMessageReactionUpdatedUpdateOrNull() ?.let(block) | ||||||
|  |  | ||||||
|  | public inline fun Update.chatMessageReactionsCountUpdatedUpdateOrNull(): | ||||||
|  |     ChatMessageReactionsCountUpdatedUpdate? = this as? | ||||||
|  |     dev.inmo.tgbotapi.types.update.ChatMessageReactionsCountUpdatedUpdate | ||||||
|  |  | ||||||
|  | public inline fun Update.chatMessageReactionsCountUpdatedUpdateOrThrow(): | ||||||
|  |     ChatMessageReactionsCountUpdatedUpdate = this as | ||||||
|  |     dev.inmo.tgbotapi.types.update.ChatMessageReactionsCountUpdatedUpdate | ||||||
|  |  | ||||||
|  | public inline fun <T> | ||||||
|  |     Update.ifChatMessageReactionsCountUpdatedUpdate(block: (ChatMessageReactionsCountUpdatedUpdate) -> T): | ||||||
|  |     T? = chatMessageReactionsCountUpdatedUpdateOrNull() ?.let(block) | ||||||
|  |  | ||||||
| public inline fun Update.chosenInlineResultUpdateOrNull(): ChosenInlineResultUpdate? = this as? | public inline fun Update.chosenInlineResultUpdateOrNull(): ChosenInlineResultUpdate? = this as? | ||||||
|     dev.inmo.tgbotapi.types.update.ChosenInlineResultUpdate |     dev.inmo.tgbotapi.types.update.ChosenInlineResultUpdate | ||||||
|  |  | ||||||
|   | |||||||
| @@ -40,6 +40,8 @@ fun Update.sourceChatWithConverters( | |||||||
|     editChannelPostUpdateConverter: (EditChannelPostUpdate) -> Chat? = { it.data.chat }, |     editChannelPostUpdateConverter: (EditChannelPostUpdate) -> Chat? = { it.data.chat }, | ||||||
|     editMessageUpdateConverter: (EditMessageUpdate) -> Chat? = { it.data.chat }, |     editMessageUpdateConverter: (EditMessageUpdate) -> Chat? = { it.data.chat }, | ||||||
|     myChatMemberUpdatedUpdateConverter: (MyChatMemberUpdatedUpdate) -> Chat? = { it.data.chat }, |     myChatMemberUpdatedUpdateConverter: (MyChatMemberUpdatedUpdate) -> Chat? = { it.data.chat }, | ||||||
|  |     chatMessageReactionUpdatedUpdateConverter: (ChatMessageReactionUpdatedUpdate) -> Chat? = { it.data.chat }, | ||||||
|  |     chatMessageReactionsCountUpdatedUpdateConverter: (ChatMessageReactionsCountUpdatedUpdate) -> Chat? = { it.data.chat }, | ||||||
|     commonChatMemberUpdatedUpdateConverter: (CommonChatMemberUpdatedUpdate) -> Chat? = { it.data.chat } |     commonChatMemberUpdatedUpdateConverter: (CommonChatMemberUpdatedUpdate) -> Chat? = { it.data.chat } | ||||||
| ): Chat? = when (this) { | ): Chat? = when (this) { | ||||||
|     is BaseMessageUpdate -> baseMessageUpdateConverter(this) |     is BaseMessageUpdate -> baseMessageUpdateConverter(this) | ||||||
| @@ -57,6 +59,8 @@ fun Update.sourceChatWithConverters( | |||||||
|     is EditMessageUpdate -> editMessageUpdateConverter(this) |     is EditMessageUpdate -> editMessageUpdateConverter(this) | ||||||
|     is MyChatMemberUpdatedUpdate -> myChatMemberUpdatedUpdateConverter(this) |     is MyChatMemberUpdatedUpdate -> myChatMemberUpdatedUpdateConverter(this) | ||||||
|     is CommonChatMemberUpdatedUpdate -> commonChatMemberUpdatedUpdateConverter(this) |     is CommonChatMemberUpdatedUpdate -> commonChatMemberUpdatedUpdateConverter(this) | ||||||
|  |     is ChatMessageReactionUpdatedUpdate -> chatMessageReactionUpdatedUpdateConverter(this) | ||||||
|  |     is ChatMessageReactionsCountUpdatedUpdate -> chatMessageReactionsCountUpdatedUpdateConverter(this) | ||||||
|     else -> { |     else -> { | ||||||
|         when (val data = data) { |         when (val data = data) { | ||||||
|             is FromUser -> data.from |             is FromUser -> data.from | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user