add boosts support

This commit is contained in:
InsanusMokrassar 2024-01-04 11:38:30 +06:00
parent 57f53813c8
commit fb9ff653ef
27 changed files with 567 additions and 13 deletions

View File

@ -0,0 +1,19 @@
package dev.inmo.tgbotapi.extensions.api.get
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.get.GetUserChatBoosts
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.UserId
import dev.inmo.tgbotapi.types.chat.Chat
suspend fun TelegramBot.getUserChatBoosts(
chatId: ChatIdentifier,
userId: UserId
) = execute(
GetUserChatBoosts(chatId = chatId, userId = userId)
)
suspend fun TelegramBot.getUserChatBoosts(
chat: Chat,
userId: UserId
) = getUserChatBoosts(chatId = chat.id, userId = userId)

View File

@ -0,0 +1,17 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.chatBoostRemovedUpdateOrNull
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.boosts.ChatBoostRemoved
import kotlinx.coroutines.flow.Flow
suspend fun BehaviourContext.waitChatBoostRemoved(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
): Flow<ChatBoostRemoved> = expectFlow(
initRequest,
errorFactory
) {
it.chatBoostRemovedUpdateOrNull() ?.data.let(::listOfNotNull)
}

View File

@ -0,0 +1,17 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.utils.chatBoostUpdatedUpdateOrNull
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.types.boosts.ChatBoostUpdated
import kotlinx.coroutines.flow.Flow
suspend fun BehaviourContext.waitChatBoostUpdated(
initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }
): Flow<ChatBoostUpdated> = expectFlow(
initRequest,
errorFactory
) {
it.chatBoostUpdatedUpdateOrNull() ?.data.let(::listOfNotNull)
}

View File

@ -0,0 +1,34 @@
@file:Suppress("unused")
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.behaviour_builder.CustomBehaviourContextAndTwoTypesReceiver
import dev.inmo.tgbotapi.extensions.behaviour_builder.CustomBehaviourContextAndTypeReceiver
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByIdChatBoostRemovedMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
import dev.inmo.tgbotapi.extensions.utils.chatBoostRemovedUpdateOrNull
import dev.inmo.tgbotapi.types.boosts.ChatBoostRemoved
import dev.inmo.tgbotapi.types.update.abstracts.Update
/**
* @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.onChatBoostRemoved(
initialFilter: SimpleFilter<ChatBoostRemoved>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatBoostRemoved, Update>? = null,
markerFactory: MarkerFactory<ChatBoostRemoved, Any> = ByIdChatBoostRemovedMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatBoostRemoved>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
(it.chatBoostRemovedUpdateOrNull() ?.data) ?.let(::listOfNotNull)
}

View File

@ -0,0 +1,34 @@
@file:Suppress("unused")
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.behaviour_builder.CustomBehaviourContextAndTwoTypesReceiver
import dev.inmo.tgbotapi.extensions.behaviour_builder.CustomBehaviourContextAndTypeReceiver
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByIdChatBoostUpdatedMarkerFactory
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
import dev.inmo.tgbotapi.extensions.utils.chatBoostUpdatedUpdateOrNull
import dev.inmo.tgbotapi.types.boosts.ChatBoostUpdated
import dev.inmo.tgbotapi.types.update.abstracts.Update
/**
* @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.onChatBoostUpdated(
initialFilter: SimpleFilter<ChatBoostUpdated>? = null,
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, ChatBoostUpdated, Update>? = null,
markerFactory: MarkerFactory<ChatBoostUpdated, Any> = ByIdChatBoostUpdatedMarkerFactory,
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, ChatBoostUpdated>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, scenarioReceiver) {
(it.chatBoostUpdatedUpdateOrNull() ?.data) ?.let(::listOfNotNull)
}

View File

@ -0,0 +1,9 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories
import dev.inmo.tgbotapi.types.boosts.ChatBoostRemoved
import dev.inmo.tgbotapi.types.boosts.ChatBoostUpdated
import dev.inmo.tgbotapi.types.polls.PollAnswer
object ByIdChatBoostRemovedMarkerFactory : MarkerFactory<ChatBoostRemoved, Any> {
override suspend fun invoke(data: ChatBoostRemoved) = data.chat.id
}

View File

@ -0,0 +1,8 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories
import dev.inmo.tgbotapi.types.boosts.ChatBoostUpdated
import dev.inmo.tgbotapi.types.polls.PollAnswer
object ByIdChatBoostUpdatedMarkerFactory : MarkerFactory<ChatBoostUpdated, Any> {
override suspend fun invoke(data: ChatBoostUpdated) = data.chat.id
}

View File

@ -0,0 +1,10 @@
package dev.inmo.tgbotapi.abstracts
import dev.inmo.tgbotapi.types.MessageId
/**
* All inheritors of this interface have [messageId] field and related to this [messageId]
*/
interface WithMessageId {
val messageId: MessageId
}

View File

@ -0,0 +1,3 @@
package dev.inmo.tgbotapi.abstracts
interface WithPreviewChatAndMessageId : WithPreviewChat, WithMessageId

View File

@ -1,7 +1,5 @@
package dev.inmo.tgbotapi.abstracts.types
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.abstracts.WithMessageId
interface MessageAction: ChatRequest {
val messageId: MessageId
}
interface MessageAction : ChatRequest, WithMessageId

View File

@ -0,0 +1,24 @@
package dev.inmo.tgbotapi.requests.get
import dev.inmo.tgbotapi.abstracts.types.ChatRequest
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.boosts.UserChatBoosts
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationStrategy
@Serializable
data class GetUserChatBoosts(
@SerialName(chatIdField)
override val chatId: ChatIdentifier,
@SerialName(userIdField)
val userId: UserId
) : SimpleRequest<UserChatBoosts>, ChatRequest {
override fun method(): String = "getUserChatBoosts"
override val resultDeserializer: DeserializationStrategy<UserChatBoosts>
get() = UserChatBoosts.serializer()
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
}

View File

@ -202,6 +202,7 @@ const val tgWebAppStartParamField = "tgWebAppStartParam"
const val chatIdField = "chat_id"
const val senderChatIdField = "sender_chat_id"
const val messageIdField = "message_id"
const val giveawayMessageIdField = "giveaway_message_id"
const val messageIdsField = "message_ids"
const val actorChatField = "actor_chat"
const val messageThreadIdField = "message_thread_id"
@ -609,6 +610,7 @@ const val secretField = "secret"
const val errorsField = "errors"
const val sourceField = "source"
const val isUnclaimedField = "is_unclaimed"
const val fieldNameField = "field_name"
const val dataHashField = "data_hash"
const val fileHashField = "file_hash"
@ -634,3 +636,10 @@ const val buttonTextField = "button_text"
const val webAppField = "web_app"
const val webAppNameField = "web_app_name"
const val menuButtonField = "menu_button"
const val boostIdField = "boost_id"
const val boostField = "boost"
const val addDateField = "add_date"
const val expirationDateField = "expiration_date"
const val removeDateField = "remove_date"
const val boostsField = "boosts"

View File

@ -0,0 +1,10 @@
package dev.inmo.tgbotapi.types.boosts
import kotlinx.serialization.Serializable
import kotlin.jvm.JvmInline
@Serializable
@JvmInline
value class BoostId(
val string: String
)

View File

@ -0,0 +1,17 @@
package dev.inmo.tgbotapi.types.boosts
import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class ChatBoost(
@SerialName(boostIdField)
val id: BoostId,
@SerialName(addDateField)
val addDate: TelegramDate,
@SerialName(expirationDateField)
val expirationDate: TelegramDate,
@SerialName(sourceField)
val source: ChatBoostSource
)

View File

@ -0,0 +1,19 @@
package dev.inmo.tgbotapi.types.boosts
import dev.inmo.tgbotapi.abstracts.WithPreviewChat
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.PreviewChat
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class ChatBoostRemoved(
@SerialName(chatField)
override val chat: PreviewChat,
@SerialName(boostIdField)
val boostId: BoostId,
@SerialName(removeDateField)
val removeDate: TelegramDate,
@SerialName(sourceField)
val source: ChatBoostSource
) : WithPreviewChat

View File

@ -0,0 +1,171 @@
package dev.inmo.tgbotapi.types.boosts
import dev.inmo.tgbotapi.abstracts.WithMessageId
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.PreviewUser
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Required
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
import kotlinx.serialization.json.decodeFromJsonElement
@Serializable(ChatBoostSource.Companion::class)
@ClassCastsIncluded
sealed interface ChatBoostSource {
val sourceName: String
val user: PreviewUser?
sealed interface ByUser : ChatBoostSource {
override val user: PreviewUser
}
@Serializable(ChatBoostSource.Companion::class)
data class Premium(
@SerialName(userField)
override val user: PreviewUser
) : ByUser {
@Required
@SerialName(sourceField)
override val sourceName: String = sourceCode
companion object {
const val sourceCode = "premium"
}
}
@Serializable(ChatBoostSource.Companion::class)
data class GiftCode(
@SerialName(userField)
override val user: PreviewUser
) : ByUser {
@Required
@SerialName(sourceField)
override val sourceName: String = sourceCode
companion object {
const val sourceCode = "gift_code"
}
}
@Serializable(ChatBoostSource.Companion::class)
sealed interface Giveaway : ChatBoostSource, WithMessageId {
val unclaimed: Boolean
val claimed: Boolean
get() = !unclaimed
@Serializable(ChatBoostSource.Companion::class)
data class Claimed(
@SerialName(giveawayMessageIdField)
override val messageId: MessageId,
@SerialName(userField)
override val user: PreviewUser
) : Giveaway, ByUser {
@Required
@SerialName(sourceField)
override val sourceName: String = Giveaway.sourceCode
@Required
@SerialName(isUnclaimedField)
override val unclaimed: Boolean = false
}
@Serializable(ChatBoostSource.Companion::class)
data class Unclaimed(
@SerialName(giveawayMessageIdField)
override val messageId: MessageId
) : Giveaway {
@Required
@SerialName(sourceField)
override val sourceName: String = Giveaway.sourceCode
@Required
@SerialName(isUnclaimedField)
override val unclaimed: Boolean = true
@SerialName(userField)
override val user: PreviewUser? = null
}
companion object {
val sourceCode = "giveaway"
}
}
@Serializable(ChatBoostSource.Companion::class)
data class Unknown(
override val sourceName: String,
override val user: PreviewUser?,
val json: JsonElement?
) : ChatBoostSource
@Serializable
private data class Surrogate(
@Required
@SerialName(sourceField)
val sourceName: String,
@SerialName(userField)
val user: PreviewUser? = null,
@SerialName(giveawayMessageIdField)
val messageId: MessageId? = null,
@SerialName(isUnclaimedField)
val unclaimed: Boolean? = null
)
companion object : KSerializer<ChatBoostSource> {
override val descriptor: SerialDescriptor
get() = Surrogate.serializer().descriptor
override fun deserialize(decoder: Decoder): ChatBoostSource {
val (surrogate, json) = when {
decoder is JsonDecoder -> {
val json = decoder.decodeJsonElement()
val surrogate = decoder.json.decodeFromJsonElement(Surrogate.serializer(), json)
surrogate to json
}
else -> Surrogate.serializer().deserialize(decoder) to null
}
return when {
surrogate.sourceName == Premium.sourceCode && surrogate.user != null -> {
Premium(surrogate.user)
}
surrogate.sourceName == GiftCode.sourceCode && surrogate.user != null -> {
GiftCode(surrogate.user)
}
surrogate.sourceName == Giveaway.sourceCode && surrogate.messageId != null -> {
when {
surrogate.user != null && surrogate.unclaimed == false -> Giveaway.Claimed(
surrogate.messageId,
surrogate.user
)
surrogate.unclaimed == true -> Giveaway.Unclaimed(
surrogate.messageId
)
else -> null
}
}
else -> null
} ?: Unknown(surrogate.sourceName, surrogate.user, json)
}
override fun serialize(encoder: Encoder, value: ChatBoostSource) {
if (value is Unknown && value.json != null) {
JsonElement.serializer().serialize(encoder, value.json)
return
}
val surrogate = Surrogate(
value.sourceName,
value.user,
(value as? Giveaway) ?.messageId,
(value as? Giveaway) ?.unclaimed,
)
Surrogate.serializer().serialize(encoder, surrogate)
}
}
}

View File

@ -0,0 +1,16 @@
package dev.inmo.tgbotapi.types.boosts
import dev.inmo.tgbotapi.abstracts.WithPreviewChat
import dev.inmo.tgbotapi.types.boostField
import dev.inmo.tgbotapi.types.chat.PreviewChat
import dev.inmo.tgbotapi.types.chatField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class ChatBoostUpdated(
@SerialName(chatField)
override val chat: PreviewChat,
@SerialName(boostField)
val boost: ChatBoost
) : WithPreviewChat

View File

@ -0,0 +1,11 @@
package dev.inmo.tgbotapi.types.boosts
import dev.inmo.tgbotapi.types.boostsField
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class UserChatBoosts(
@SerialName(boostsField)
val boosts: List<ChatBoost>
)

View File

@ -1,5 +1,7 @@
package dev.inmo.tgbotapi.types.chat
import dev.inmo.tgbotapi.abstracts.WithPreviewChat
import dev.inmo.tgbotapi.abstracts.WithPreviewChatAndMessageId
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.reactions.Reaction
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
@ -14,9 +16,7 @@ import kotlinx.serialization.json.JsonElement
@Serializable(ChatMessageReactionUpdated.Companion::class)
@ClassCastsIncluded
sealed interface ChatMessageReactionUpdated {
val chat: PreviewChat
val messageId: MessageIdentifier
sealed interface ChatMessageReactionUpdated : WithPreviewChatAndMessageId {
val reactedUser: PreviewUser?
val reactedChat: PreviewChat?
val date: TelegramDate

View File

@ -1,5 +1,7 @@
package dev.inmo.tgbotapi.types.chat
import dev.inmo.tgbotapi.abstracts.WithPreviewChat
import dev.inmo.tgbotapi.abstracts.WithPreviewChatAndMessageId
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.reactions.ReactionsCount
import kotlinx.serialization.SerialName
@ -8,12 +10,12 @@ import kotlinx.serialization.Serializable
@Serializable
data class ChatMessageReactionsCountUpdated(
@SerialName(chatField)
val chat: PreviewChat,
override val chat: PreviewChat,
@SerialName(messageIdField)
val messageId: MessageIdentifier,
override val messageId: MessageIdentifier,
@Serializable(TelegramDateSerializer::class)
@SerialName(dateField)
val date: TelegramDate,
@SerialName(reactionsField)
val reactions: List<ReactionsCount>
)
) : WithPreviewChatAndMessageId

View File

@ -1,7 +1,9 @@
package dev.inmo.tgbotapi.types.message.abstracts
import dev.inmo.tgbotapi.abstracts.WithMessageId
import korlibs.time.DateTime
import dev.inmo.tgbotapi.abstracts.WithPreviewChat
import dev.inmo.tgbotapi.abstracts.WithPreviewChatAndMessageId
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.chat.Chat
@ -13,8 +15,7 @@ import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
@ClassCastsIncluded(excludeRegex = ".*Impl")
interface Message : WithPreviewChat {
val messageId: MessageId
interface Message : WithPreviewChatAndMessageId {
val date: DateTime
}

View File

@ -0,0 +1,14 @@
package dev.inmo.tgbotapi.types.update
import dev.inmo.tgbotapi.types.UpdateIdentifier
import dev.inmo.tgbotapi.types.boosts.ChatBoostRemoved
import dev.inmo.tgbotapi.types.boosts.ChatBoostUpdated
import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated
import dev.inmo.tgbotapi.types.update.abstracts.Update
import kotlinx.serialization.Serializable
@Serializable
data class ChatBoostRemovedUpdate(
override val updateId: UpdateIdentifier,
override val data: ChatBoostRemoved
) : Update

View File

@ -0,0 +1,13 @@
package dev.inmo.tgbotapi.types.update
import dev.inmo.tgbotapi.types.UpdateIdentifier
import dev.inmo.tgbotapi.types.boosts.ChatBoostUpdated
import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated
import dev.inmo.tgbotapi.types.update.abstracts.Update
import kotlinx.serialization.Serializable
@Serializable
data class ChatBoostUpdatedUpdate(
override val updateId: UpdateIdentifier,
override val data: ChatBoostUpdated
) : Update

View File

@ -4,6 +4,8 @@ import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.queries.callback.RawCallbackQuery
import dev.inmo.tgbotapi.types.InlineQueries.ChosenInlineResult.RawChosenInlineResult
import dev.inmo.tgbotapi.types.InlineQueries.query.RawInlineQuery
import dev.inmo.tgbotapi.types.boosts.ChatBoostRemoved
import dev.inmo.tgbotapi.types.boosts.ChatBoostUpdated
import dev.inmo.tgbotapi.types.chat.ChatJoinRequest
import dev.inmo.tgbotapi.types.chat.ChatMessageReactionUpdated
import dev.inmo.tgbotapi.types.chat.ChatMessageReactionsCountUpdated
@ -42,7 +44,9 @@ internal data class RawUpdate constructor(
private val chat_member: ChatMemberUpdated? = null,
private val chat_join_request: ChatJoinRequest? = null,
private val message_reaction: ChatMessageReactionUpdated? = null,
private val message_reaction_count: ChatMessageReactionsCountUpdated? = null
private val message_reaction_count: ChatMessageReactionsCountUpdated? = null,
private val chat_boost: ChatBoostUpdated? = null,
private val removed_chat_boost: ChatBoostRemoved? = null
) {
private var initedUpdate: Update? = null
/**
@ -71,6 +75,8 @@ internal data class RawUpdate constructor(
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)
chat_boost != null -> ChatBoostUpdatedUpdate(updateId, chat_boost)
removed_chat_boost != null -> ChatBoostRemovedUpdate(updateId, removed_chat_boost)
else -> UnknownUpdate(
updateId,
raw

View File

@ -39,6 +39,8 @@ interface FlowsUpdatesFilter : UpdatesFilter {
val chatJoinRequestUpdateFlow: Flow<ChatJoinRequestUpdate>
val chatMessageReactionUpdatedUpdateFlow: Flow<ChatMessageReactionUpdatedUpdate>
val chatMessageReactionsCountUpdatedUpdateFlow: Flow<ChatMessageReactionsCountUpdatedUpdate>
val chatBoostUpdatedUpdateFlow: Flow<ChatBoostUpdatedUpdate>
val chatBoostRemovedUpdateFlow: Flow<ChatBoostRemovedUpdate>
val unknownUpdatesFlow: Flow<UnknownUpdate>
}
@ -60,6 +62,8 @@ abstract class AbstractFlowsUpdatesFilter : FlowsUpdatesFilter {
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 chatBoostUpdatedUpdateFlow: Flow<ChatBoostUpdatedUpdate> by lazy { allUpdatesFlow.filterIsInstance() }
override val chatBoostRemovedUpdateFlow: Flow<ChatBoostRemovedUpdate> by lazy { allUpdatesFlow.filterIsInstance() }
}
/**

View File

@ -90,6 +90,7 @@ import dev.inmo.tgbotapi.types.actions.UploadPhotoAction
import dev.inmo.tgbotapi.types.actions.UploadVideoAction
import dev.inmo.tgbotapi.types.actions.UploadVideoNoteAction
import dev.inmo.tgbotapi.types.actions.UploadVoiceAction
import dev.inmo.tgbotapi.types.boosts.ChatBoostSource
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.CallbackDataInlineKeyboardButton
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.CallbackGameInlineKeyboardButton
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.InlineKeyboardButton
@ -424,6 +425,8 @@ import dev.inmo.tgbotapi.types.request.RequestResponse
import dev.inmo.tgbotapi.types.request.UsersShared
import dev.inmo.tgbotapi.types.update.CallbackQueryUpdate
import dev.inmo.tgbotapi.types.update.ChannelPostUpdate
import dev.inmo.tgbotapi.types.update.ChatBoostRemovedUpdate
import dev.inmo.tgbotapi.types.update.ChatBoostUpdatedUpdate
import dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate
import dev.inmo.tgbotapi.types.update.ChatMessageReactionUpdatedUpdate
import dev.inmo.tgbotapi.types.update.ChatMessageReactionsCountUpdatedUpdate
@ -1620,6 +1623,69 @@ public inline fun BotAction.customBotActionOrThrow(): CustomBotAction = this as
public inline fun <T> BotAction.ifCustomBotAction(block: (CustomBotAction) -> T): T? =
customBotActionOrNull() ?.let(block)
public inline fun ChatBoostSource.byUserOrNull(): ChatBoostSource.ByUser? = this as?
dev.inmo.tgbotapi.types.boosts.ChatBoostSource.ByUser
public inline fun ChatBoostSource.byUserOrThrow(): ChatBoostSource.ByUser = this as
dev.inmo.tgbotapi.types.boosts.ChatBoostSource.ByUser
public inline fun <T> ChatBoostSource.ifByUser(block: (ChatBoostSource.ByUser) -> T): T? =
byUserOrNull() ?.let(block)
public inline fun ChatBoostSource.giftCodeOrNull(): ChatBoostSource.GiftCode? = this as?
dev.inmo.tgbotapi.types.boosts.ChatBoostSource.GiftCode
public inline fun ChatBoostSource.giftCodeOrThrow(): ChatBoostSource.GiftCode = this as
dev.inmo.tgbotapi.types.boosts.ChatBoostSource.GiftCode
public inline fun <T> ChatBoostSource.ifGiftCode(block: (ChatBoostSource.GiftCode) -> T): T? =
giftCodeOrNull() ?.let(block)
public inline fun ChatBoostSource.claimedOrNull(): ChatBoostSource.Giveaway.Claimed? = this as?
dev.inmo.tgbotapi.types.boosts.ChatBoostSource.Giveaway.Claimed
public inline fun ChatBoostSource.claimedOrThrow(): ChatBoostSource.Giveaway.Claimed = this as
dev.inmo.tgbotapi.types.boosts.ChatBoostSource.Giveaway.Claimed
public inline fun <T> ChatBoostSource.ifClaimed(block: (ChatBoostSource.Giveaway.Claimed) -> T): T?
= claimedOrNull() ?.let(block)
public inline fun ChatBoostSource.premiumOrNull(): ChatBoostSource.Premium? = this as?
dev.inmo.tgbotapi.types.boosts.ChatBoostSource.Premium
public inline fun ChatBoostSource.premiumOrThrow(): ChatBoostSource.Premium = this as
dev.inmo.tgbotapi.types.boosts.ChatBoostSource.Premium
public inline fun <T> ChatBoostSource.ifPremium(block: (ChatBoostSource.Premium) -> T): T? =
premiumOrNull() ?.let(block)
public inline fun ChatBoostSource.giveawayOrNull(): ChatBoostSource.Giveaway? = this as?
dev.inmo.tgbotapi.types.boosts.ChatBoostSource.Giveaway
public inline fun ChatBoostSource.giveawayOrThrow(): ChatBoostSource.Giveaway = this as
dev.inmo.tgbotapi.types.boosts.ChatBoostSource.Giveaway
public inline fun <T> ChatBoostSource.ifGiveaway(block: (ChatBoostSource.Giveaway) -> T): T? =
giveawayOrNull() ?.let(block)
public inline fun ChatBoostSource.unclaimedOrNull(): ChatBoostSource.Giveaway.Unclaimed? = this as?
dev.inmo.tgbotapi.types.boosts.ChatBoostSource.Giveaway.Unclaimed
public inline fun ChatBoostSource.unclaimedOrThrow(): ChatBoostSource.Giveaway.Unclaimed = this as
dev.inmo.tgbotapi.types.boosts.ChatBoostSource.Giveaway.Unclaimed
public inline fun <T> ChatBoostSource.ifUnclaimed(block: (ChatBoostSource.Giveaway.Unclaimed) -> T):
T? = unclaimedOrNull() ?.let(block)
public inline fun ChatBoostSource.unknownOrNull(): ChatBoostSource.Unknown? = this as?
dev.inmo.tgbotapi.types.boosts.ChatBoostSource.Unknown
public inline fun ChatBoostSource.unknownOrThrow(): ChatBoostSource.Unknown = this as
dev.inmo.tgbotapi.types.boosts.ChatBoostSource.Unknown
public inline fun <T> ChatBoostSource.ifUnknown(block: (ChatBoostSource.Unknown) -> T): T? =
unknownOrNull() ?.let(block)
public inline fun InlineKeyboardButton.unknownInlineKeyboardButtonOrNull():
UnknownInlineKeyboardButton? = this as?
dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.UnknownInlineKeyboardButton
@ -4603,6 +4669,24 @@ public inline fun Update.channelPostUpdateOrThrow(): ChannelPostUpdate = this as
public inline fun <T> Update.ifChannelPostUpdate(block: (ChannelPostUpdate) -> T): T? =
channelPostUpdateOrNull() ?.let(block)
public inline fun Update.chatBoostRemovedUpdateOrNull(): ChatBoostRemovedUpdate? = this as?
dev.inmo.tgbotapi.types.update.ChatBoostRemovedUpdate
public inline fun Update.chatBoostRemovedUpdateOrThrow(): ChatBoostRemovedUpdate = this as
dev.inmo.tgbotapi.types.update.ChatBoostRemovedUpdate
public inline fun <T> Update.ifChatBoostRemovedUpdate(block: (ChatBoostRemovedUpdate) -> T): T? =
chatBoostRemovedUpdateOrNull() ?.let(block)
public inline fun Update.chatBoostUpdatedUpdateOrNull(): ChatBoostUpdatedUpdate? = this as?
dev.inmo.tgbotapi.types.update.ChatBoostUpdatedUpdate
public inline fun Update.chatBoostUpdatedUpdateOrThrow(): ChatBoostUpdatedUpdate = this as
dev.inmo.tgbotapi.types.update.ChatBoostUpdatedUpdate
public inline fun <T> Update.ifChatBoostUpdatedUpdate(block: (ChatBoostUpdatedUpdate) -> T): T? =
chatBoostUpdatedUpdateOrNull() ?.let(block)
public inline fun Update.chatJoinRequestUpdateOrNull(): ChatJoinRequestUpdate? = this as?
dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate

View File

@ -42,6 +42,8 @@ fun Update.sourceChatWithConverters(
myChatMemberUpdatedUpdateConverter: (MyChatMemberUpdatedUpdate) -> Chat? = { it.data.chat },
chatMessageReactionUpdatedUpdateConverter: (ChatMessageReactionUpdatedUpdate) -> Chat? = { it.data.chat },
chatMessageReactionsCountUpdatedUpdateConverter: (ChatMessageReactionsCountUpdatedUpdate) -> Chat? = { it.data.chat },
chatBoostUpdatedUpdateFlow: (ChatBoostUpdatedUpdate) -> Chat? = { it.data.chat },
chatBoostRemovedUpdateFlow: (ChatBoostRemovedUpdate) -> Chat? = { it.data.chat },
commonChatMemberUpdatedUpdateConverter: (CommonChatMemberUpdatedUpdate) -> Chat? = { it.data.chat }
): Chat? = when (this) {
is BaseMessageUpdate -> baseMessageUpdateConverter(this)
@ -61,6 +63,8 @@ fun Update.sourceChatWithConverters(
is CommonChatMemberUpdatedUpdate -> commonChatMemberUpdatedUpdateConverter(this)
is ChatMessageReactionUpdatedUpdate -> chatMessageReactionUpdatedUpdateConverter(this)
is ChatMessageReactionsCountUpdatedUpdate -> chatMessageReactionsCountUpdatedUpdateConverter(this)
is ChatBoostUpdatedUpdate -> chatBoostUpdatedUpdateFlow(this)
is ChatBoostRemovedUpdate -> chatBoostRemovedUpdateFlow(this)
else -> {
when (val data = data) {
is FromUser -> data.from