diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt index e66e407779..77fe66ed95 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt @@ -482,6 +482,7 @@ const val isBigField = "is_big" const val oldReactionField = "old_reaction" const val newReactionField = "new_reaction" const val chatField = "chat" +const val chatsField = "chats" const val usernameField = "username" const val bioField = "bio" const val nameField = "name" @@ -544,6 +545,7 @@ const val shippingQueryIdField = "shipping_query_id" const val preCheckoutQueryIdField = "pre_checkout_query_id" const val shippingOptionsField = "shipping_options" const val countryCodeField = "country_code" +const val countryCodesField = "country_codes" const val totalCountField = "total_count" const val stateField = "state" const val cityField = "city" @@ -643,3 +645,13 @@ const val addDateField = "add_date" const val expirationDateField = "expiration_date" const val removeDateField = "remove_date" const val boostsField = "boosts" +const val winnersSelectionDateField = "winners_selection_date" +const val winnersCountField = "winner_count" +const val onlyNewMembersField = "only_new_members" +const val hasPublicWinnersField = "has_public_winners" +const val prizeDescriptionField = "prize_description" +const val premiumSubscriptionMonthCountField = "premium_subscription_month_count" +const val winnersField = "winners" +const val additionalChatCountField = "additional_chat_count" +const val unclaimedPrizeCountField = "unclaimed_prize_count" +const val wasRefundedField = "was_refunded" diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/Giveaway.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/Giveaway.kt new file mode 100644 index 0000000000..cbae4c2740 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/Giveaway.kt @@ -0,0 +1,30 @@ +package dev.inmo.tgbotapi.types.giveaway + +import dev.inmo.micro_utils.language_codes.IetfLang +import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.chat.PreviewChat +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChannelEvent +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChatEvent +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PublicChatEvent +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class Giveaway( + @SerialName(chatsField) + val chats: List, + @SerialName(winnersSelectionDateField) + override val selectionDate: TelegramDate, + @SerialName(winnersCountField) + val count: Int, + @SerialName(onlyNewMembersField) + override val onlyNewMembers: Boolean = false, + @SerialName(hasPublicWinnersField) + val publicWinners: Boolean = false, + @SerialName(prizeDescriptionField) + override val additionalPrizeDescription: String? = null, + @SerialName(countryCodesField) + val countries: List? = null, + @SerialName(premiumSubscriptionMonthCountField) + override val premiumMonths: Int? = null +) : GiveawayInfo, ChatEvent, PublicChatEvent \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayCreated.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayCreated.kt new file mode 100644 index 0000000000..25694a90cd --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayCreated.kt @@ -0,0 +1,8 @@ +package dev.inmo.tgbotapi.types.giveaway + +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChatEvent +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PublicChatEvent +import kotlinx.serialization.Serializable + +@Serializable +object GiveawayCreated : ChatEvent, PublicChatEvent diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayInfo.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayInfo.kt new file mode 100644 index 0000000000..559f001773 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayInfo.kt @@ -0,0 +1,15 @@ +package dev.inmo.tgbotapi.types.giveaway + +import dev.inmo.micro_utils.language_codes.IetfLang +import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.chat.PreviewChat +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +sealed interface GiveawayInfo { + val selectionDate: TelegramDate + val onlyNewMembers: Boolean + val premiumMonths: Int? + val additionalPrizeDescription: String? +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayPrivateResults.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayPrivateResults.kt new file mode 100644 index 0000000000..63e3fb7f4b --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayPrivateResults.kt @@ -0,0 +1,16 @@ +package dev.inmo.tgbotapi.types.giveaway + +import dev.inmo.tgbotapi.types.chat.PreviewChat +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChannelEvent +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChatEvent +import dev.inmo.tgbotapi.types.message.abstracts.Message +import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient + +@Serializable +data class GiveawayPrivateResults( + override val chat: PreviewChat, + override val unclaimedCount: Int, + @Transient // TODO::Add message serializer + val message: Message? = null +) : GiveawayResults diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayPublicResults.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayPublicResults.kt new file mode 100644 index 0000000000..b908d2e314 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayPublicResults.kt @@ -0,0 +1,162 @@ +package dev.inmo.tgbotapi.types.giveaway + +import dev.inmo.tgbotapi.abstracts.WithPreviewChatAndMessageId +import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.chat.PreviewChat +import dev.inmo.tgbotapi.types.chat.PreviewUser +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 + +@Serializable(GiveawayPublicResults.Companion::class) +sealed interface GiveawayPublicResults: GiveawayInfo, GiveawayResults, WithPreviewChatAndMessageId { + val count: Int + val winners: List + val additionalChats: Int + val publicWinners: Boolean + val refunded: Boolean + + @Serializable(GiveawayPublicResults.Companion::class) + data class Refunded( + @SerialName(chatsField) + override val chat: PreviewChat, + @SerialName(giveawayMessageIdField) + override val messageId: MessageId, + @SerialName(winnersSelectionDateField) + override val selectionDate: TelegramDate, + ) : GiveawayPublicResults { + @SerialName(wasRefundedField) + @Required + override val refunded: Boolean = true + @SerialName(winnersCountField) + override val count: Int = 0 + @SerialName(winnersField) + override val winners: List = emptyList() + @SerialName(additionalChatCountField) + override val additionalChats: Int = 0 + @SerialName(unclaimedPrizeCountField) + override val unclaimedCount: Int = 0 + @SerialName(onlyNewMembersField) + override val onlyNewMembers: Boolean = false + @SerialName(hasPublicWinnersField) + override val publicWinners: Boolean = false + @SerialName(prizeDescriptionField) + override val additionalPrizeDescription: String? = null + @SerialName(premiumSubscriptionMonthCountField) + override val premiumMonths: Int? = null + } + + @Serializable(GiveawayPublicResults.Companion::class) + data class Winners ( + @SerialName(chatsField) + override val chat: PreviewChat, + @SerialName(giveawayMessageIdField) + override val messageId: MessageId, + @SerialName(winnersSelectionDateField) + override val selectionDate: TelegramDate, + @SerialName(winnersCountField) + override val count: Int, + @SerialName(winnersField) + override val winners: List, + @SerialName(additionalChatCountField) + override val additionalChats: Int = 0, + @SerialName(unclaimedPrizeCountField) + override val unclaimedCount: Int = 0, + @SerialName(onlyNewMembersField) + override val onlyNewMembers: Boolean = false, + @SerialName(hasPublicWinnersField) + override val publicWinners: Boolean = false, + @SerialName(prizeDescriptionField) + override val additionalPrizeDescription: String? = null, + @SerialName(premiumSubscriptionMonthCountField) + override val premiumMonths: Int? = null + ) : GiveawayPublicResults { + @SerialName(wasRefundedField) + @Required + override val refunded: Boolean = false + } + + @Serializable + private data class Surrogate( + @SerialName(chatsField) + val chat: PreviewChat, + @SerialName(giveawayMessageIdField) + val messageId: MessageId, + @SerialName(winnersSelectionDateField) + val selectionDate: TelegramDate, + @SerialName(winnersCountField) + val count: Int, + @SerialName(winnersField) + val winners: List, + @SerialName(additionalChatCountField) + val additionalChats: Int = 0, + @SerialName(unclaimedPrizeCountField) + val unclaimedCount: Int = 0, + @SerialName(onlyNewMembersField) + val onlyNewMembers: Boolean = false, + @SerialName(hasPublicWinnersField) + val publicWinners: Boolean = false, + @SerialName(wasRefundedField) + val refunded: Boolean = false, + @SerialName(prizeDescriptionField) + val additionalPrizeDescription: String? = null, + @SerialName(premiumSubscriptionMonthCountField) + val premiumMonths: Int? = null + ) + + companion object : KSerializer { + override val descriptor: SerialDescriptor + get() = Surrogate.serializer().descriptor + + override fun deserialize(decoder: Decoder): GiveawayPublicResults { + val surrogate = Surrogate.serializer().deserialize(decoder) + + return when (surrogate.refunded) { + true -> Refunded( + chat = surrogate.chat, + messageId = surrogate.messageId, + selectionDate = surrogate.selectionDate + ) + false -> { + Winners( + chat = surrogate.chat, + messageId = surrogate.messageId, + selectionDate = surrogate.selectionDate, + count = surrogate.count, + winners = surrogate.winners, + additionalChats = surrogate.additionalChats, + unclaimedCount = surrogate.unclaimedCount, + onlyNewMembers = surrogate.onlyNewMembers, + publicWinners = surrogate.publicWinners, + additionalPrizeDescription = surrogate.additionalPrizeDescription, + premiumMonths = surrogate.premiumMonths, + ) + } + } + } + + override fun serialize(encoder: Encoder, value: GiveawayPublicResults) { + val surrogate = Surrogate( + chat = value.chat, + messageId = value.messageId, + selectionDate = value.selectionDate, + count = value.count, + winners = value.winners, + additionalChats = value.additionalChats, + unclaimedCount = value.unclaimedCount, + onlyNewMembers = value.onlyNewMembers, + publicWinners = value.publicWinners, + additionalPrizeDescription = value.additionalPrizeDescription, + premiumMonths = value.premiumMonths, + refunded = value.refunded + ) + + Surrogate.serializer().serialize(encoder, surrogate) + } + + } +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayResults.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayResults.kt new file mode 100644 index 0000000000..fc193537e6 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/giveaway/GiveawayResults.kt @@ -0,0 +1,11 @@ +package dev.inmo.tgbotapi.types.giveaway + +import dev.inmo.tgbotapi.abstracts.WithPreviewChat +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.ChatEvent +import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PublicChatEvent +import kotlinx.serialization.Serializable + +@Serializable +sealed interface GiveawayResults : WithPreviewChat, ChatEvent, PublicChatEvent { + val unclaimedCount: Int +} 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 43f928f24a..5d50d272d4 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 @@ -9,6 +9,10 @@ import dev.inmo.tgbotapi.types.dice.Dice import dev.inmo.tgbotapi.types.files.* import dev.inmo.tgbotapi.types.files.Sticker import dev.inmo.tgbotapi.types.games.RawGame +import dev.inmo.tgbotapi.types.giveaway.Giveaway +import dev.inmo.tgbotapi.types.giveaway.GiveawayCreated +import dev.inmo.tgbotapi.types.giveaway.GiveawayPrivateResults +import dev.inmo.tgbotapi.types.giveaway.GiveawayResults import dev.inmo.tgbotapi.types.location.Location import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.* @@ -130,7 +134,13 @@ internal data class RawMessage( private val link_preview_options: LinkPreviewOptions? = null, - private val reply_markup: InlineKeyboardMarkup? = null + private val reply_markup: InlineKeyboardMarkup? = null, + + // Giveaways + private val giveaway_created: GiveawayCreated? = null, + private val giveaway: Giveaway? = null, + private val giveaway_winners: GiveawayResults? = null, + private val giveaway_completed: GiveawayPrivateResults? = null, ) { private val content: MessageContent? by lazy { val adaptedCaptionEntities = caption ?.let { @@ -268,6 +278,10 @@ internal data class RawMessage( web_app_data != null -> web_app_data users_shared != null -> users_shared chat_shared != null -> chat_shared + giveaway_created != null -> giveaway_created + giveaway != null -> giveaway + giveaway_winners != null -> giveaway_winners + giveaway_completed != null -> giveaway_completed else -> null } } diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCastsNew.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCastsNew.kt index b4fc81fc39..70b2517155 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCastsNew.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCastsNew.kt @@ -196,6 +196,11 @@ import dev.inmo.tgbotapi.types.files.VideoFile import dev.inmo.tgbotapi.types.files.VideoNoteFile import dev.inmo.tgbotapi.types.files.VideoSticker import dev.inmo.tgbotapi.types.files.VoiceFile +import dev.inmo.tgbotapi.types.giveaway.Giveaway +import dev.inmo.tgbotapi.types.giveaway.GiveawayCreated +import dev.inmo.tgbotapi.types.giveaway.GiveawayPrivateResults +import dev.inmo.tgbotapi.types.giveaway.GiveawayPublicResults +import dev.inmo.tgbotapi.types.giveaway.GiveawayResults import dev.inmo.tgbotapi.types.location.LiveLocation import dev.inmo.tgbotapi.types.location.Location import dev.inmo.tgbotapi.types.location.StaticLocation @@ -2714,6 +2719,51 @@ public inline fun TelegramMedia.titledTelegramMediaOrThrow(): TitledTelegramMedi public inline fun TelegramMedia.ifTitledTelegramMedia(block: (TitledTelegramMedia) -> T): T? = titledTelegramMediaOrNull() ?.let(block) +public inline fun ChatEvent.giveawayOrNull(): Giveaway? = this as? + dev.inmo.tgbotapi.types.giveaway.Giveaway + +public inline fun ChatEvent.giveawayOrThrow(): Giveaway = this as + dev.inmo.tgbotapi.types.giveaway.Giveaway + +public inline fun ChatEvent.ifGiveaway(block: (Giveaway) -> T): T? = giveawayOrNull() + ?.let(block) + +public inline fun ChatEvent.giveawayCreatedOrNull(): GiveawayCreated? = this as? + dev.inmo.tgbotapi.types.giveaway.GiveawayCreated + +public inline fun ChatEvent.giveawayCreatedOrThrow(): GiveawayCreated = this as + dev.inmo.tgbotapi.types.giveaway.GiveawayCreated + +public inline fun ChatEvent.ifGiveawayCreated(block: (GiveawayCreated) -> T): T? = + giveawayCreatedOrNull() ?.let(block) + +public inline fun ChatEvent.giveawayPrivateResultsOrNull(): GiveawayPrivateResults? = this as? + dev.inmo.tgbotapi.types.giveaway.GiveawayPrivateResults + +public inline fun ChatEvent.giveawayPrivateResultsOrThrow(): GiveawayPrivateResults = this as + dev.inmo.tgbotapi.types.giveaway.GiveawayPrivateResults + +public inline fun ChatEvent.ifGiveawayPrivateResults(block: (GiveawayPrivateResults) -> T): T? = + giveawayPrivateResultsOrNull() ?.let(block) + +public inline fun ChatEvent.giveawayPublicResultsOrNull(): GiveawayPublicResults? = this as? + dev.inmo.tgbotapi.types.giveaway.GiveawayPublicResults + +public inline fun ChatEvent.giveawayPublicResultsOrThrow(): GiveawayPublicResults = this as + dev.inmo.tgbotapi.types.giveaway.GiveawayPublicResults + +public inline fun ChatEvent.ifGiveawayPublicResults(block: (GiveawayPublicResults) -> T): T? = + giveawayPublicResultsOrNull() ?.let(block) + +public inline fun ChatEvent.giveawayResultsOrNull(): GiveawayResults? = this as? + dev.inmo.tgbotapi.types.giveaway.GiveawayResults + +public inline fun ChatEvent.giveawayResultsOrThrow(): GiveawayResults = this as + dev.inmo.tgbotapi.types.giveaway.GiveawayResults + +public inline fun ChatEvent.ifGiveawayResults(block: (GiveawayResults) -> T): T? = + giveawayResultsOrNull() ?.let(block) + public inline fun ChatEvent.channelChatCreatedOrNull(): ChannelChatCreated? = this as? dev.inmo.tgbotapi.types.message.ChatEvents.ChannelChatCreated