From 1eef5bb239c9d7de1675ba17130939676060b614 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 8 Jul 2024 00:18:54 +0600 Subject: [PATCH] temporal progress on adding support of paid media --- .../tgbotapi/extensions/api/edit/Edits.kt | 8 +- .../extensions/api/edit/InlineEdits.kt | 4 +- .../api/edit/media/EditChatMessageMedia.kt | 8 +- .../api/edit/media/EditInlineMessageMedia.kt | 4 +- .../edit/abstracts/EditMediaMessage.kt | 4 +- .../edit/media/EditChatMessageMedia.kt | 4 +- .../edit/media/EditInlineMessageMedia.kt | 4 +- .../requests/send/media/SendMediaGroup.kt | 3 +- .../requests/send/media/SendPaidMediaGroup.kt | 209 ++++++++++++++++++ .../kotlin/dev/inmo/tgbotapi/types/Common.kt | 1 + .../inmo/tgbotapi/types/files/PhotoSize.kt | 2 +- .../types/files/UsefulAsPaidMediaFile.kt | 3 + .../inmo/tgbotapi/types/files/VideoFile.kt | 11 +- ...GroupMemberTelegramFreeMediaSerializer.kt} | 8 +- .../media/MediaGroupMemberTelegramMedia.kt | 30 +-- ...aGroupMemberTelegramPaidMediaSerializer.kt | 38 ++++ .../{payments/stars => media}/PaidMedia.kt | 12 +- .../tgbotapi/types/media/TelegramFreeMedia.kt | 9 + .../types/media/TelegramMediaAnimation.kt | 2 +- .../types/media/TelegramMediaAudio.kt | 2 +- .../types/media/TelegramMediaDocument.kt | 2 +- .../types/media/TelegramMediaPhoto.kt | 2 +- .../types/media/TelegramMediaSerializer.kt | 2 + .../types/media/TelegramMediaVideo.kt | 2 +- .../tgbotapi/types/media/TelegramPaidMedia.kt | 9 + .../types/media/TelegramPaidMediaPhoto.kt | 33 +++ .../types/media/TelegramPaidMediaVideo.kt | 38 ++++ .../types/message/content/Abstracts.kt | 1 + .../message/content/MediaGroupContent.kt | 4 +- .../message/content/PaidMediaInfoContent.kt | 40 ++++ .../dev/inmo/tgbotapi/SimpleInputFilesTest.kt | 6 +- .../tgbotapi/extensions/utils/ClassCasts.kt | 78 +++---- .../extensions/utils/ClassCastsNew.kt | 92 ++++---- 33 files changed, 535 insertions(+), 140 deletions(-) create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendPaidMediaGroup.kt create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/UsefulAsPaidMediaFile.kt rename tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/{MediaGroupMemberTelegramMediaSerializer.kt => MediaGroupMemberTelegramFreeMediaSerializer.kt} (88%) create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/MediaGroupMemberTelegramPaidMediaSerializer.kt rename tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/{payments/stars => media}/PaidMedia.kt (94%) create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramFreeMedia.kt create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramPaidMedia.kt create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramPaidMediaPhoto.kt create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramPaidMediaVideo.kt create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/PaidMediaInfoContent.kt diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/Edits.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/Edits.kt index 5b7480c5b6..09666ed92c 100644 --- a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/Edits.kt +++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/Edits.kt @@ -12,7 +12,7 @@ import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.location.LiveLocation -import dev.inmo.tgbotapi.types.media.TelegramMedia +import dev.inmo.tgbotapi.types.media.TelegramFreeMedia import dev.inmo.tgbotapi.types.message.ParseMode import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.AccessibleMessage @@ -145,7 +145,7 @@ suspend fun TelegramBot.edit( suspend fun TelegramBot.edit( chatId: ChatIdentifier, messageId: MessageId, - media: TelegramMedia, + media: TelegramFreeMedia, businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId, replyMarkup: InlineKeyboardMarkup? = null ) = editMessageMedia(chatId, messageId, media, businessConnectionId, replyMarkup) @@ -157,7 +157,7 @@ suspend fun TelegramBot.edit( suspend fun TelegramBot.edit( chat: Chat, messageId: MessageId, - media: TelegramMedia, + media: TelegramFreeMedia, businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId, replyMarkup: InlineKeyboardMarkup? = null ) = editMessageMedia(chat, messageId, media, businessConnectionId, replyMarkup) @@ -168,7 +168,7 @@ suspend fun TelegramBot.edit( */ suspend fun TelegramBot.edit( message: ContentMessage, - media: TelegramMedia, + media: TelegramFreeMedia, businessConnectionId: BusinessConnectionId? = message.chat.id.businessConnectionId, replyMarkup: InlineKeyboardMarkup? = null ) = editMessageMedia(message, media, businessConnectionId, replyMarkup) diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/InlineEdits.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/InlineEdits.kt index 1c202a886b..70429696e9 100644 --- a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/InlineEdits.kt +++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/InlineEdits.kt @@ -8,7 +8,7 @@ import dev.inmo.tgbotapi.extensions.api.edit.text.editMessageText import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup import dev.inmo.tgbotapi.types.location.LiveLocation -import dev.inmo.tgbotapi.types.media.TelegramMedia +import dev.inmo.tgbotapi.types.media.TelegramFreeMedia import dev.inmo.tgbotapi.types.message.ParseMode import dev.inmo.tgbotapi.types.message.textsources.TextSource import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList @@ -47,7 +47,7 @@ suspend fun TelegramBot.edit( */ suspend fun TelegramBot.edit( messageId: InlineMessageId, - media: TelegramMedia, + media: TelegramFreeMedia, replyMarkup: InlineKeyboardMarkup? = null ) = editMessageMedia(messageId, media, replyMarkup) diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/media/EditChatMessageMedia.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/media/EditChatMessageMedia.kt index f8aed69af4..8611e6e6c5 100644 --- a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/media/EditChatMessageMedia.kt +++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/media/EditChatMessageMedia.kt @@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.extensions.api.edit.media import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.requests.edit.media.EditChatMessageMedia import dev.inmo.tgbotapi.types.ChatIdentifier -import dev.inmo.tgbotapi.types.media.TelegramMedia +import dev.inmo.tgbotapi.types.media.TelegramFreeMedia import dev.inmo.tgbotapi.types.MessageId import dev.inmo.tgbotapi.types.businessConnectionId import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId @@ -19,7 +19,7 @@ import dev.inmo.tgbotapi.types.message.content.MediaContent suspend fun TelegramBot.editMessageMedia( chatId: ChatIdentifier, messageId: MessageId, - media: TelegramMedia, + media: TelegramFreeMedia, businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId, replyMarkup: InlineKeyboardMarkup? = null ) = execute( @@ -33,7 +33,7 @@ suspend fun TelegramBot.editMessageMedia( suspend fun TelegramBot.editMessageMedia( chat: Chat, messageId: MessageId, - media: TelegramMedia, + media: TelegramFreeMedia, businessConnectionId: BusinessConnectionId? = chat.id.businessConnectionId, replyMarkup: InlineKeyboardMarkup? = null ) = editMessageMedia(chat.id, messageId, media, businessConnectionId, replyMarkup) @@ -44,7 +44,7 @@ suspend fun TelegramBot.editMessageMedia( */ suspend fun TelegramBot.editMessageMedia( message: ContentMessage, - media: TelegramMedia, + media: TelegramFreeMedia, businessConnectionId: BusinessConnectionId? = message.chat.id.businessConnectionId, replyMarkup: InlineKeyboardMarkup? = null ) = editMessageMedia(message.chat.id, message.messageId, media, businessConnectionId, replyMarkup) diff --git a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/media/EditInlineMessageMedia.kt b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/media/EditInlineMessageMedia.kt index 000f2d5b6d..3272f78db6 100644 --- a/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/media/EditInlineMessageMedia.kt +++ b/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/edit/media/EditInlineMessageMedia.kt @@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.extensions.api.edit.media import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.requests.edit.media.EditInlineMessageMedia import dev.inmo.tgbotapi.types.InlineMessageId -import dev.inmo.tgbotapi.types.media.TelegramMedia +import dev.inmo.tgbotapi.types.media.TelegramFreeMedia import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup /** @@ -12,6 +12,6 @@ import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup */ suspend fun TelegramBot.editMessageMedia( inlineMessageId: InlineMessageId, - media: TelegramMedia, + media: TelegramFreeMedia, replyMarkup: InlineKeyboardMarkup? = null ) = execute(EditInlineMessageMedia(inlineMessageId, media, replyMarkup)) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/abstracts/EditMediaMessage.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/abstracts/EditMediaMessage.kt index ec68b4aff0..5edd956590 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/abstracts/EditMediaMessage.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/abstracts/EditMediaMessage.kt @@ -1,7 +1,7 @@ package dev.inmo.tgbotapi.requests.edit.abstracts -import dev.inmo.tgbotapi.types.media.TelegramMedia +import dev.inmo.tgbotapi.types.media.TelegramFreeMedia interface EditMediaMessage { - val media: TelegramMedia + val media: TelegramFreeMedia } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/media/EditChatMessageMedia.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/media/EditChatMessageMedia.kt index 6df690d2f6..a5afd389a5 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/media/EditChatMessageMedia.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/media/EditChatMessageMedia.kt @@ -4,7 +4,7 @@ import dev.inmo.tgbotapi.requests.abstracts.MultipartFile import dev.inmo.tgbotapi.requests.edit.abstracts.* import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId -import dev.inmo.tgbotapi.types.media.TelegramMedia +import dev.inmo.tgbotapi.types.media.TelegramFreeMedia import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass @@ -22,7 +22,7 @@ data class EditChatMessageMedia( @SerialName(messageIdField) override val messageId: MessageId, @SerialName(mediaField) - override val media: TelegramMedia, + override val media: TelegramFreeMedia, @SerialName(businessConnectionIdField) override val businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId, @SerialName(replyMarkupField) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/media/EditInlineMessageMedia.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/media/EditInlineMessageMedia.kt index 2f04cfd043..a6a8fecfa6 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/media/EditInlineMessageMedia.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/edit/media/EditInlineMessageMedia.kt @@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.requests.edit.media import dev.inmo.tgbotapi.requests.abstracts.MultipartFile import dev.inmo.tgbotapi.requests.edit.abstracts.* import dev.inmo.tgbotapi.types.* -import dev.inmo.tgbotapi.types.media.TelegramMedia +import dev.inmo.tgbotapi.types.media.TelegramFreeMedia import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup import kotlinx.serialization.* @@ -12,7 +12,7 @@ data class EditInlineMessageMedia( @SerialName(inlineMessageIdField) override val inlineMessageId: InlineMessageId, @SerialName(mediaField) - override val media: TelegramMedia, + override val media: TelegramFreeMedia, @SerialName(replyMarkupField) override val replyMarkup: InlineKeyboardMarkup? = null ) : EditInlineMessage, EditReplyMessage, EditMediaMessage { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendMediaGroup.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendMediaGroup.kt index 360d8fb440..236f062036 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendMediaGroup.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendMediaGroup.kt @@ -4,7 +4,6 @@ import dev.inmo.tgbotapi.requests.abstracts.MultipartFile import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.common.CommonMultipartFileRequest import dev.inmo.tgbotapi.requests.send.abstracts.SendContentMessageRequest -import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest import dev.inmo.tgbotapi.requests.send.media.base.* import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId @@ -193,7 +192,7 @@ data class SendMediaGroupData internal constructor( private val convertedMedia: String get() = buildJsonArray { media.forEach { - add(it.toJsonWithoutNulls(MediaGroupMemberTelegramMediaSerializer)) + add(it.toJsonWithoutNulls(MediaGroupMemberTelegramFreeMediaSerializer)) } }.toString() diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendPaidMediaGroup.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendPaidMediaGroup.kt new file mode 100644 index 0000000000..ed2433d964 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendPaidMediaGroup.kt @@ -0,0 +1,209 @@ +package dev.inmo.tgbotapi.requests.send.media + +import dev.inmo.tgbotapi.requests.abstracts.MultipartFile +import dev.inmo.tgbotapi.requests.abstracts.Request +import dev.inmo.tgbotapi.requests.common.CommonMultipartFileRequest +import dev.inmo.tgbotapi.requests.send.abstracts.SendContentMessageRequest +import dev.inmo.tgbotapi.requests.send.media.base.* +import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId +import dev.inmo.tgbotapi.types.media.* +import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage +import dev.inmo.tgbotapi.types.message.abstracts.PossiblySentViaBotCommonMessage +import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializerClass +import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent +import dev.inmo.tgbotapi.types.message.content.VisualMediaGroupPartContent +import dev.inmo.tgbotapi.types.message.content.AudioContent +import dev.inmo.tgbotapi.types.message.content.DocumentContent +import dev.inmo.tgbotapi.types.message.content.MediaGroupContent +import dev.inmo.tgbotapi.utils.* +import dev.inmo.tgbotapi.utils.extensions.asMediaGroupMessage +import kotlinx.serialization.* +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.json.buildJsonArray + +const val rawSendingMediaGroupsWarning = "Media groups contains restrictions related to combinations of media" + + " types. Currently it is possible to combine photo + video OR audio OR documents" + +@RiskFeature(rawSendingMediaGroupsWarning) +fun SendMediaGroup( + chatId: ChatIdentifier, + media: List, + threadId: MessageThreadId? = chatId.threadId, + businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId, + disableNotification: Boolean = false, + protectContent: Boolean = false, + effectId: EffectId? = null, + replyParameters: ReplyParameters? = null +): Request>> { + if (media.size !in mediaCountInMediaGroup) { + throwRangeError("Count of members in media group", mediaCountInMediaGroup, media.size) + } + + val files: List = media.flatMap { + listOfNotNull( + it.file as? MultipartFile, + if (it is ThumbedTelegramMedia) { + it.thumb as? MultipartFile + } else { + null + } + ) + } + + val data = SendMediaGroupData( + chatId = chatId, + media = media, + threadId = threadId, + businessConnectionId = businessConnectionId, + disableNotification = disableNotification, + protectContent = protectContent, + effectId = effectId, + replyParameters = replyParameters + ) + + return (if (files.isEmpty()) { + data + } else { + CommonMultipartFileRequest( + data, + files.associateBy { it.fileId } + ) + }) as Request>> +} + +/** + * Use this method to be sure that you are correctly sending playlist with audios + * + * @see TelegramMediaAudio + */ +@Suppress("NOTHING_TO_INLINE") +inline fun SendPlaylist( + chatId: ChatIdentifier, + media: List, + threadId: MessageThreadId? = chatId.threadId, + businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId, + disableNotification: Boolean = false, + protectContent: Boolean = false, + effectId: EffectId? = null, + replyParameters: ReplyParameters? = null +) = SendMediaGroup( + chatId = chatId, + media = media, + threadId = threadId, + businessConnectionId = businessConnectionId, + disableNotification = disableNotification, + protectContent = protectContent, + effectId = effectId, + replyParameters = replyParameters +) + +/** + * Use this method to be sure that you are correctly sending documents media group + * + * @see TelegramMediaDocument + */ +@Suppress("NOTHING_TO_INLINE") +inline fun SendDocumentsGroup( + chatId: ChatIdentifier, + media: List, + threadId: MessageThreadId? = chatId.threadId, + businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId, + disableNotification: Boolean = false, + protectContent: Boolean = false, + effectId: EffectId? = null, + replyParameters: ReplyParameters? = null +) = SendMediaGroup( + chatId = chatId, + media = media, + threadId = threadId, + businessConnectionId = businessConnectionId, + disableNotification = disableNotification, + protectContent = protectContent, + effectId = effectId, + replyParameters = replyParameters +) + +/** + * Use this method to be sure that you are correctly sending visual media group + * + * @see TelegramMediaPhoto + * @see TelegramMediaVideo + */ +@Suppress("NOTHING_TO_INLINE") +inline fun SendVisualMediaGroup( + chatId: ChatIdentifier, + media: List, + threadId: MessageThreadId? = chatId.threadId, + businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId, + disableNotification: Boolean = false, + protectContent: Boolean = false, + effectId: EffectId? = null, + replyParameters: ReplyParameters? = null, +) = SendMediaGroup( + chatId = chatId, + media = media, + threadId = threadId, + businessConnectionId = businessConnectionId, + disableNotification = disableNotification, + protectContent = protectContent, + effectId = effectId, + replyParameters = replyParameters +) + +private object MessagesListSerializer: KSerializer>> { + private val serializer = ListSerializer(TelegramBotAPIMessageDeserializeOnlySerializerClass>()) + override val descriptor: SerialDescriptor = serializer.descriptor + + override fun deserialize(decoder: Decoder): PossiblySentViaBotCommonMessage> { + val messages = serializer.deserialize(decoder) + return messages.asMediaGroupMessage() + } + + override fun serialize(encoder: Encoder, value: PossiblySentViaBotCommonMessage>) { + serializer.serialize(encoder, value.content.group.map { it.sourceMessage }) + } + +} + +@Serializable +data class SendMediaGroupData internal constructor( + @SerialName(chatIdField) + override val chatId: ChatIdentifier, + val media: List = emptyList(), + @SerialName(messageThreadIdField) + override val threadId: MessageThreadId? = chatId.threadId, + @SerialName(businessConnectionIdField) + override val businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId, + @SerialName(disableNotificationField) + override val disableNotification: Boolean = false, + @SerialName(protectContentField) + override val protectContent: Boolean = false, + @SerialName(messageEffectIdField) + override val effectId: EffectId? = null, + @SerialName(replyParametersField) + override val replyParameters: ReplyParameters? = null, +) : DataRequest>>, + SendContentMessageRequest>> { + @SerialName(mediaField) + private val convertedMedia: String + get() = buildJsonArray { + media.forEach { + add(it.toJsonWithoutNulls(MediaGroupMemberTelegramFreeMediaSerializer)) + } + }.toString() + + + override fun method(): String = "sendMediaGroup" + override val requestSerializer: SerializationStrategy<*> + get() = serializer() + override val resultDeserializer: DeserializationStrategy>> + get() = MessagesListSerializer +} + +data class SendMediaGroupFiles internal constructor( + val files: List +) : Files by (files.map { it.fileId to it }.toMap()) 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 806e814634..6fa5e357b5 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 @@ -229,6 +229,7 @@ const val canDeleteStoriesField = "can_delete_stories" const val captionEntitiesField = "caption_entities" const val hasSpoilerField = "has_spoiler" const val showCaptionAboveMediaField = "show_caption_above_media" +const val supportsStreamingField = "supports_streaming" const val loginUrlField = "login_url" const val forwardTextField = "forward_text" const val botUsernameField = "bot_username" diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/PhotoSize.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/PhotoSize.kt index 01341aeba6..3fe521be27 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/PhotoSize.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/PhotoSize.kt @@ -10,7 +10,7 @@ import kotlin.jvm.JvmInline @JvmInline value class Photo( val photos: List -) : List by photos, MediaContentVariant { +) : List by photos, MediaContentVariant, UsefulAsPaidMediaFile { val biggest: PhotoSize get() = biggest()!! override val fileId: FileId diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/UsefulAsPaidMediaFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/UsefulAsPaidMediaFile.kt new file mode 100644 index 0000000000..dd443dcc9e --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/UsefulAsPaidMediaFile.kt @@ -0,0 +1,3 @@ +package dev.inmo.tgbotapi.types.files + +sealed interface UsefulAsPaidMediaFile : MediaContentVariant diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VideoFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VideoFile.kt index 846fc7ca91..e9d492ff5f 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VideoFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/VideoFile.kt @@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.types.files import dev.inmo.tgbotapi.requests.abstracts.FileId import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.media.TelegramMediaVideo +import dev.inmo.tgbotapi.types.media.TelegramPaidMediaVideo import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList import dev.inmo.tgbotapi.types.message.ParseMode import dev.inmo.tgbotapi.utils.MimeType @@ -30,7 +31,7 @@ data class VideoFile( @SerialName(fileSizeField) override val fileSize: Long? = null ) : TelegramMediaFile, CustomNamedMediaFile, MimedMediaFile, ThumbedMediaFile, PlayableMediaFile, SizedMediaFile, - MediaContentVariant + MediaContentVariant, UsefulAsPaidMediaFile @Suppress("NOTHING_TO_INLINE") inline fun VideoFile.toTelegramMediaVideo( @@ -65,3 +66,11 @@ inline fun VideoFile.toTelegramMediaVideo( duration = duration, thumb = thumbnail ?.fileId ) +@Suppress("NOTHING_TO_INLINE") +inline fun VideoFile.toTelegramPaidMediaVideo() = TelegramPaidMediaVideo( + file = fileId, + width = width, + height = height, + duration = duration, + thumb = thumbnail ?.fileId +) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/MediaGroupMemberTelegramMediaSerializer.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/MediaGroupMemberTelegramFreeMediaSerializer.kt similarity index 88% rename from tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/MediaGroupMemberTelegramMediaSerializer.kt rename to tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/MediaGroupMemberTelegramFreeMediaSerializer.kt index 19c9124d52..285049b722 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/MediaGroupMemberTelegramMediaSerializer.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/MediaGroupMemberTelegramFreeMediaSerializer.kt @@ -11,10 +11,10 @@ import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.json.* @RiskFeature -object MediaGroupMemberTelegramMediaSerializer : KSerializer { +object MediaGroupMemberTelegramFreeMediaSerializer : KSerializer { @OptIn(InternalSerializationApi::class) override val descriptor: SerialDescriptor = buildSerialDescriptor(MediaGroupMemberTelegramMedia::class.toString(), PolymorphicKind.OPEN) - override fun serialize(encoder: Encoder, value: MediaGroupMemberTelegramMedia) { + override fun serialize(encoder: Encoder, value: MediaGroupMemberTelegramFreeMedia) { when (value) { is TelegramMediaPhoto -> TelegramMediaPhoto.serializer().serialize(encoder, value) is TelegramMediaVideo -> TelegramMediaVideo.serializer().serialize(encoder, value) @@ -23,7 +23,7 @@ object MediaGroupMemberTelegramMediaSerializer : KSerializer { + @OptIn(InternalSerializationApi::class) + override val descriptor: SerialDescriptor = + buildSerialDescriptor(MediaGroupMemberTelegramMedia::class.toString(), PolymorphicKind.OPEN) + override fun serialize(encoder: Encoder, value: MediaGroupMemberTelegramPaidMedia) { + when (value) { + is TelegramPaidMediaPhoto -> TelegramPaidMediaPhoto.serializer().serialize(encoder, value) + is TelegramPaidMediaVideo -> TelegramPaidMediaVideo.serializer().serialize(encoder, value) + } + } + + override fun deserialize(decoder: Decoder): MediaGroupMemberTelegramPaidMedia { + val json = JsonObject.serializer().deserialize(decoder) + + return when (json[typeField] ?.jsonPrimitive ?.contentOrNull) { + photoTelegramPaidMediaType -> nonstrictJsonFormat.decodeFromJsonElement(TelegramPaidMediaPhoto.serializer(), json) + videoTelegramPaidMediaType -> nonstrictJsonFormat.decodeFromJsonElement(TelegramPaidMediaVideo.serializer(), json) + else -> error("Illegal type of incoming MediaGroupMemberTelegramMedia") + } + } +} \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/payments/stars/PaidMedia.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/PaidMedia.kt similarity index 94% rename from tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/payments/stars/PaidMedia.kt rename to tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/PaidMedia.kt index 15db1ad1fd..0c98d4893b 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/payments/stars/PaidMedia.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/PaidMedia.kt @@ -1,7 +1,7 @@ -package dev.inmo.tgbotapi.types.payments.stars +package dev.inmo.tgbotapi.types.media import dev.inmo.tgbotapi.types.* -import dev.inmo.tgbotapi.types.files.PhotoSize +import dev.inmo.tgbotapi.types.files.VideoFile import dev.inmo.tgbotapi.utils.decodeDataAndJson import kotlinx.serialization.EncodeDefault import kotlinx.serialization.KSerializer @@ -13,9 +13,7 @@ import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.json.JsonElement @Serializable(PaidMedia.Companion::class) -sealed interface PaidMedia { - val type: String - +sealed interface PaidMedia : TelegramMedia { @Serializable data class Preview( @SerialName(widthField) @@ -51,7 +49,7 @@ sealed interface PaidMedia { @Serializable data class Video( @SerialName(videoField) - val video: Video + val video: VideoFile ) : PaidMedia { @EncodeDefault @SerialName(typeField) @@ -62,7 +60,7 @@ sealed interface PaidMedia { } } - @Serializable(PaidMedia.Companion::class) + @Serializable(Companion::class) data class Unknown( @SerialName(typeField) override val type: String, diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramFreeMedia.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramFreeMedia.kt new file mode 100644 index 0000000000..80f0d87efb --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramFreeMedia.kt @@ -0,0 +1,9 @@ +package dev.inmo.tgbotapi.types.media + +import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded +import dev.inmo.tgbotapi.requests.abstracts.InputFile +import kotlinx.serialization.Serializable + +@Serializable(TelegramMediaSerializer::class) +@ClassCastsIncluded +sealed interface TelegramFreeMedia : TelegramMedia diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaAnimation.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaAnimation.kt index f3fafe6f6c..31cd7ab371 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaAnimation.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaAnimation.kt @@ -65,7 +65,7 @@ data class TelegramMediaAnimation internal constructor( override val height: Int? = null, override val duration: Long? = null, override val thumb: InputFile? = null -) : TelegramMedia, SizedTelegramMedia, DuratedTelegramMedia, ThumbedTelegramMedia, TextedOutput, SpoilerableTelegramMedia, WithCustomizableCaptionTelegramMedia { +) : TelegramFreeMedia, SizedTelegramMedia, DuratedTelegramMedia, ThumbedTelegramMedia, TextedOutput, SpoilerableTelegramMedia, WithCustomizableCaptionTelegramMedia { override val type: String = "animation" override val textSources: TextSourcesList? by lazy { rawEntities ?.asTextSources(text ?: return@lazy null) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaAudio.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaAudio.kt index 9a21b6ca1d..d9da215565 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaAudio.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaAudio.kt @@ -52,7 +52,7 @@ data class TelegramMediaAudio internal constructor( override val performer: String? = null, override val title: String? = null, override val thumb: InputFile? = null -) : TelegramMedia, AudioMediaGroupMemberTelegramMedia, DuratedTelegramMedia, ThumbedTelegramMedia, TitledTelegramMedia, +) : TelegramFreeMedia, AudioMediaGroupMemberTelegramMedia, DuratedTelegramMedia, ThumbedTelegramMedia, TitledTelegramMedia, Performerable { override val type: String = audioTelegramMediaType override val textSources: TextSourcesList? by lazy { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaDocument.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaDocument.kt index 8049a4b692..109a6cd687 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaDocument.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaDocument.kt @@ -58,7 +58,7 @@ data class TelegramMediaDocument internal constructor( override val thumb: InputFile? = null, @SerialName(disableContentTypeDetectionField) val disableContentTypeDetection: Boolean? = null -) : TelegramMedia, DocumentMediaGroupMemberTelegramMedia, ThumbedTelegramMedia { +) : TelegramFreeMedia, DocumentMediaGroupMemberTelegramMedia, ThumbedTelegramMedia { override val type: String = documentTelegramMediaType override val textSources: TextSourcesList? by lazy { rawEntities ?.asTextSources(text ?: return@lazy null) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaPhoto.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaPhoto.kt index f7eaa6320c..564875ee53 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaPhoto.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaPhoto.kt @@ -43,7 +43,7 @@ data class TelegramMediaPhoto internal constructor( override val spoilered: Boolean = false, @SerialName(showCaptionAboveMediaField) override val showCaptionAboveMedia: Boolean = false, -) : TelegramMedia, VisualMediaGroupMemberTelegramMedia { +) : TelegramFreeMedia, VisualMediaGroupMemberTelegramFreeMedia { override val type: String = photoTelegramMediaType override val textSources: TextSourcesList? by lazy { rawEntities ?.asTextSources(text ?: return@lazy null) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaSerializer.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaSerializer.kt index 989f5bbb9a..47291efd32 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaSerializer.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaSerializer.kt @@ -18,6 +18,8 @@ object TelegramMediaSerializer : KSerializer { is TelegramMediaPhoto -> TelegramMediaPhoto.serializer().serialize(encoder, value) is TelegramMediaAnimation -> TelegramMediaAnimation.serializer().serialize(encoder, value) is TelegramMediaDocument -> TelegramMediaDocument.serializer().serialize(encoder, value) + is TelegramPaidMediaVideo -> TelegramPaidMediaVideo.serializer().serialize(encoder, value) + is TelegramPaidMediaPhoto -> TelegramPaidMediaPhoto.serializer().serialize(encoder, value) } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaVideo.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaVideo.kt index 1871adb345..d63119662f 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaVideo.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramMediaVideo.kt @@ -76,7 +76,7 @@ data class TelegramMediaVideo internal constructor ( override val height: Int? = null, override val duration: Long? = null, override val thumb: InputFile? = null -) : TelegramMedia, SizedTelegramMedia, DuratedTelegramMedia, ThumbedTelegramMedia, VisualMediaGroupMemberTelegramMedia { +) : TelegramFreeMedia, SizedTelegramMedia, DuratedTelegramMedia, ThumbedTelegramMedia, VisualMediaGroupMemberTelegramFreeMedia { override val type: String = videoTelegramMediaType override val textSources: TextSourcesList? by lazy { rawEntities ?.asTextSources(text ?: return@lazy null) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramPaidMedia.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramPaidMedia.kt new file mode 100644 index 0000000000..1e57918e11 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramPaidMedia.kt @@ -0,0 +1,9 @@ +package dev.inmo.tgbotapi.types.media + +import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded +import dev.inmo.tgbotapi.requests.abstracts.InputFile +import kotlinx.serialization.Serializable + +@Serializable(TelegramMediaSerializer::class) +@ClassCastsIncluded +sealed interface TelegramPaidMedia : TelegramMedia diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramPaidMediaPhoto.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramPaidMediaPhoto.kt new file mode 100644 index 0000000000..b230fabd8f --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramPaidMediaPhoto.kt @@ -0,0 +1,33 @@ +package dev.inmo.tgbotapi.types.media + +import dev.inmo.tgbotapi.requests.abstracts.InputFile +import dev.inmo.tgbotapi.requests.abstracts.fileIdToSend +import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList +import dev.inmo.tgbotapi.types.message.ParseMode +import dev.inmo.tgbotapi.types.message.parseModeField +import dev.inmo.tgbotapi.types.files.PhotoSize +import dev.inmo.tgbotapi.types.message.* +import dev.inmo.tgbotapi.types.message.RawMessageEntity +import dev.inmo.tgbotapi.types.message.toRawMessageEntities +import dev.inmo.tgbotapi.utils.extensions.makeString +import kotlinx.serialization.* + +internal const val photoTelegramPaidMediaType = "photo" + +@Serializable +data class TelegramPaidMediaPhoto internal constructor( + override val file: InputFile, +) : TelegramPaidMedia, VisualMediaGroupMemberTelegramPaidMedia { + override val type: String = photoTelegramPaidMediaType + + override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this) + + @SerialName(mediaField) + override val media: String + init { media = file.fileIdToSend } // crutch until js compiling will be fixed +} + +fun PhotoSize.toTelegramPaidMediaPhoto(): TelegramPaidMediaPhoto = TelegramPaidMediaPhoto( + file = fileId, +) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramPaidMediaVideo.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramPaidMediaVideo.kt new file mode 100644 index 0000000000..576a7a52b6 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/media/TelegramPaidMediaVideo.kt @@ -0,0 +1,38 @@ +package dev.inmo.tgbotapi.types.media + +import dev.inmo.tgbotapi.requests.abstracts.InputFile +import dev.inmo.tgbotapi.requests.abstracts.fileIdToSend +import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.files.VideoFile +import kotlinx.serialization.* + +internal const val videoTelegramPaidMediaType = "video" + +@Serializable +data class TelegramPaidMediaVideo ( + override val file: InputFile, + override val thumb: InputFile? = null, + override val width: Int? = null, + override val height: Int? = null, + override val duration: Long? = null, + @SerialName(supportsStreamingField) + val supportsStreaming: Boolean = false, +) : TelegramPaidMedia, SizedTelegramMedia, DuratedTelegramMedia, ThumbedTelegramMedia, VisualMediaGroupMemberTelegramPaidMedia { + override val type: String = videoTelegramPaidMediaType + + override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this) + + @SerialName(mediaField) + override val media: String + init { media = file.fileIdToSend } // crutch until js compiling will be fixed +} + +fun VideoFile.toTelegramPaidMediaVideo(): TelegramPaidMediaVideo = TelegramPaidMediaVideo( + file = fileId, + thumb = thumbnail ?.fileId, + width = width, + height = height, + duration = duration +) + +fun PaidMedia.Video.toTelegramPaidMediaVideo(): TelegramPaidMediaVideo = video.toTelegramPaidMediaVideo() diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/Abstracts.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/Abstracts.kt index 752cfe4fef..1556f45a5b 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/Abstracts.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/Abstracts.kt @@ -9,6 +9,7 @@ import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.files.TelegramMediaFile +import dev.inmo.tgbotapi.types.media.TelegramFreeMedia import dev.inmo.tgbotapi.types.media.TelegramMedia import dev.inmo.tgbotapi.types.message.abstracts.* import dev.inmo.tgbotapi.utils.RiskFeature diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/MediaGroupContent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/MediaGroupContent.kt index 6d75745a59..66406ededb 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/MediaGroupContent.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/MediaGroupContent.kt @@ -7,7 +7,7 @@ import dev.inmo.tgbotapi.types.abstracts.WithOptionalQuoteInfo import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.files.TelegramMediaFile -import dev.inmo.tgbotapi.types.media.TelegramMedia +import dev.inmo.tgbotapi.types.media.TelegramFreeMedia import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.textsources.TextSource import kotlinx.serialization.Serializable @@ -29,7 +29,7 @@ data class MediaGroupContent( override val text: String? get() = mainContent.text - override fun asTelegramMedia(): TelegramMedia = mainContent.asTelegramMedia() + override fun asTelegramMedia(): TelegramFreeMedia = mainContent.asTelegramMedia() override fun createResend( chatId: ChatIdentifier, diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/PaidMediaInfoContent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/PaidMediaInfoContent.kt new file mode 100644 index 0000000000..fc02655356 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/PaidMediaInfoContent.kt @@ -0,0 +1,40 @@ +package dev.inmo.tgbotapi.types.message.content + +import dev.inmo.tgbotapi.requests.abstracts.Request +import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId +import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList +import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup +import dev.inmo.tgbotapi.types.files.* +import dev.inmo.tgbotapi.types.media.PaidMedia +import dev.inmo.tgbotapi.types.media.TelegramPaidMedia +import dev.inmo.tgbotapi.types.media.toTelegramMediaPhoto +import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage +import kotlinx.serialization.Serializable + +@Serializable +data class PaidMediaInfoContent( + override val mediaCollection: List, + override val text: String? = null, + override val textSources: TextSourcesList = emptyList(), + override val quote: TextQuote? = null, + override val showCaptionAboveMedia: Boolean = false +) : MediaCollectionContent, TextedMediaContent, WithCustomizedCaptionMediaContent { + override val media: UsefulAsPaidMediaFile + get() = mediaCollection.first() + override fun asTelegramMedia(): TelegramPaidMedia = when (val media = media) { + is VideoFile -> media.toTelegramPaidMediaVideo() + is Photo -> media.biggest.toTelegramMediaPhoto() + } + + override fun createResend( + chatId: ChatIdentifier, + messageThreadId: MessageThreadId?, + businessConnectionId: BusinessConnectionId?, + disableNotification: Boolean, + protectContent: Boolean, + effectId: EffectId?, + replyParameters: ReplyParameters?, + replyMarkup: KeyboardMarkup? + ): Request> = TODO() +} diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/SimpleInputFilesTest.kt b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/SimpleInputFilesTest.kt index 789bfca0d4..559317c294 100644 --- a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/SimpleInputFilesTest.kt +++ b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/SimpleInputFilesTest.kt @@ -3,7 +3,7 @@ package dev.inmo.tgbotapi import dev.inmo.tgbotapi.requests.abstracts.toInputFile import dev.inmo.tgbotapi.types.TgFileUniqueId import dev.inmo.tgbotapi.types.files.Photo -import dev.inmo.tgbotapi.types.media.MediaGroupMemberTelegramMediaSerializer +import dev.inmo.tgbotapi.types.media.MediaGroupMemberTelegramFreeMediaSerializer import dev.inmo.tgbotapi.types.files.PhotoSize import dev.inmo.tgbotapi.types.message.content.PhotoContent import kotlinx.serialization.json.Json @@ -31,13 +31,13 @@ class SimpleInputFilesTest { val inputMedia = photoContent.toMediaGroupMemberTelegramMedia() assertEquals(photoContent.media.fileId, inputMedia.file) val encoded = nonstrictJsonFormat.encodeToString( - MediaGroupMemberTelegramMediaSerializer, + MediaGroupMemberTelegramFreeMediaSerializer, inputMedia ) assertEquals( inputMedia, nonstrictJsonFormat.decodeFromString( - MediaGroupMemberTelegramMediaSerializer, + MediaGroupMemberTelegramFreeMediaSerializer, encoded ) ) diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt index ccb25f7023..4d228c08b0 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt @@ -1999,141 +1999,141 @@ inline fun ChatMember.asSpecialRightsChatMember(): SpecialRightsChatMember? = th inline fun ChatMember.requireSpecialRightsChatMember(): SpecialRightsChatMember = this as SpecialRightsChatMember @PreviewFeature -inline fun TelegramMedia.whenAudioMediaGroupMemberTelegramMedia(block: (AudioMediaGroupMemberTelegramMedia) -> T) = +inline fun TelegramFreeMedia.whenAudioMediaGroupMemberTelegramMedia(block: (AudioMediaGroupMemberTelegramMedia) -> T) = asAudioMediaGroupMemberTelegramMedia()?.let(block) @PreviewFeature -inline fun TelegramMedia.asAudioMediaGroupMemberTelegramMedia(): AudioMediaGroupMemberTelegramMedia? = +inline fun TelegramFreeMedia.asAudioMediaGroupMemberTelegramMedia(): AudioMediaGroupMemberTelegramMedia? = this as? AudioMediaGroupMemberTelegramMedia @PreviewFeature -inline fun TelegramMedia.requireAudioMediaGroupMemberTelegramMedia(): AudioMediaGroupMemberTelegramMedia = +inline fun TelegramFreeMedia.requireAudioMediaGroupMemberTelegramMedia(): AudioMediaGroupMemberTelegramMedia = this as AudioMediaGroupMemberTelegramMedia @PreviewFeature -inline fun TelegramMedia.whenDocumentMediaGroupMemberTelegramMedia(block: (DocumentMediaGroupMemberTelegramMedia) -> T) = +inline fun TelegramFreeMedia.whenDocumentMediaGroupMemberTelegramMedia(block: (DocumentMediaGroupMemberTelegramMedia) -> T) = asDocumentMediaGroupMemberTelegramMedia()?.let(block) @PreviewFeature -inline fun TelegramMedia.asDocumentMediaGroupMemberTelegramMedia(): DocumentMediaGroupMemberTelegramMedia? = +inline fun TelegramFreeMedia.asDocumentMediaGroupMemberTelegramMedia(): DocumentMediaGroupMemberTelegramMedia? = this as? DocumentMediaGroupMemberTelegramMedia @PreviewFeature -inline fun TelegramMedia.requireDocumentMediaGroupMemberTelegramMedia(): DocumentMediaGroupMemberTelegramMedia = +inline fun TelegramFreeMedia.requireDocumentMediaGroupMemberTelegramMedia(): DocumentMediaGroupMemberTelegramMedia = this as DocumentMediaGroupMemberTelegramMedia @PreviewFeature -inline fun TelegramMedia.whenDuratedTelegramMedia(block: (DuratedTelegramMedia) -> T) = +inline fun TelegramFreeMedia.whenDuratedTelegramMedia(block: (DuratedTelegramMedia) -> T) = asDuratedTelegramMedia()?.let(block) @PreviewFeature -inline fun TelegramMedia.asDuratedTelegramMedia(): DuratedTelegramMedia? = this as? DuratedTelegramMedia +inline fun TelegramFreeMedia.asDuratedTelegramMedia(): DuratedTelegramMedia? = this as? DuratedTelegramMedia @PreviewFeature -inline fun TelegramMedia.requireDuratedTelegramMedia(): DuratedTelegramMedia = this as DuratedTelegramMedia +inline fun TelegramFreeMedia.requireDuratedTelegramMedia(): DuratedTelegramMedia = this as DuratedTelegramMedia @PreviewFeature -inline fun TelegramMedia.whenTelegramMediaAnimation(block: (TelegramMediaAnimation) -> T) = +inline fun TelegramFreeMedia.whenTelegramMediaAnimation(block: (TelegramMediaAnimation) -> T) = asTelegramMediaAnimation()?.let(block) @PreviewFeature -inline fun TelegramMedia.asTelegramMediaAnimation(): TelegramMediaAnimation? = this as? TelegramMediaAnimation +inline fun TelegramFreeMedia.asTelegramMediaAnimation(): TelegramMediaAnimation? = this as? TelegramMediaAnimation @PreviewFeature -inline fun TelegramMedia.requireTelegramMediaAnimation(): TelegramMediaAnimation = this as TelegramMediaAnimation +inline fun TelegramFreeMedia.requireTelegramMediaAnimation(): TelegramMediaAnimation = this as TelegramMediaAnimation @PreviewFeature -inline fun TelegramMedia.whenTelegramMediaAudio(block: (TelegramMediaAudio) -> T) = +inline fun TelegramFreeMedia.whenTelegramMediaAudio(block: (TelegramMediaAudio) -> T) = asTelegramMediaAudio()?.let(block) @PreviewFeature -inline fun TelegramMedia.asTelegramMediaAudio(): TelegramMediaAudio? = this as? TelegramMediaAudio +inline fun TelegramFreeMedia.asTelegramMediaAudio(): TelegramMediaAudio? = this as? TelegramMediaAudio @PreviewFeature -inline fun TelegramMedia.requireTelegramMediaAudio(): TelegramMediaAudio = this as TelegramMediaAudio +inline fun TelegramFreeMedia.requireTelegramMediaAudio(): TelegramMediaAudio = this as TelegramMediaAudio @PreviewFeature -inline fun TelegramMedia.whenTelegramMediaDocument(block: (TelegramMediaDocument) -> T) = +inline fun TelegramFreeMedia.whenTelegramMediaDocument(block: (TelegramMediaDocument) -> T) = asTelegramMediaDocument()?.let(block) @PreviewFeature -inline fun TelegramMedia.asTelegramMediaDocument(): TelegramMediaDocument? = this as? TelegramMediaDocument +inline fun TelegramFreeMedia.asTelegramMediaDocument(): TelegramMediaDocument? = this as? TelegramMediaDocument @PreviewFeature -inline fun TelegramMedia.requireTelegramMediaDocument(): TelegramMediaDocument = this as TelegramMediaDocument +inline fun TelegramFreeMedia.requireTelegramMediaDocument(): TelegramMediaDocument = this as TelegramMediaDocument @PreviewFeature -inline fun TelegramMedia.whenTelegramMediaPhoto(block: (TelegramMediaPhoto) -> T) = +inline fun TelegramFreeMedia.whenTelegramMediaPhoto(block: (TelegramMediaPhoto) -> T) = asTelegramMediaPhoto()?.let(block) @PreviewFeature -inline fun TelegramMedia.asTelegramMediaPhoto(): TelegramMediaPhoto? = this as? TelegramMediaPhoto +inline fun TelegramFreeMedia.asTelegramMediaPhoto(): TelegramMediaPhoto? = this as? TelegramMediaPhoto @PreviewFeature -inline fun TelegramMedia.requireTelegramMediaPhoto(): TelegramMediaPhoto = this as TelegramMediaPhoto +inline fun TelegramFreeMedia.requireTelegramMediaPhoto(): TelegramMediaPhoto = this as TelegramMediaPhoto @PreviewFeature -inline fun TelegramMedia.whenTelegramMediaVideo(block: (TelegramMediaVideo) -> T) = +inline fun TelegramFreeMedia.whenTelegramMediaVideo(block: (TelegramMediaVideo) -> T) = asTelegramMediaVideo()?.let(block) @PreviewFeature -inline fun TelegramMedia.asTelegramMediaVideo(): TelegramMediaVideo? = this as? TelegramMediaVideo +inline fun TelegramFreeMedia.asTelegramMediaVideo(): TelegramMediaVideo? = this as? TelegramMediaVideo @PreviewFeature -inline fun TelegramMedia.requireTelegramMediaVideo(): TelegramMediaVideo = this as TelegramMediaVideo +inline fun TelegramFreeMedia.requireTelegramMediaVideo(): TelegramMediaVideo = this as TelegramMediaVideo @PreviewFeature -inline fun TelegramMedia.whenMediaGroupMemberTelegramMedia(block: (MediaGroupMemberTelegramMedia) -> T) = +inline fun TelegramFreeMedia.whenMediaGroupMemberTelegramMedia(block: (MediaGroupMemberTelegramMedia) -> T) = asMediaGroupMemberTelegramMedia()?.let(block) @PreviewFeature -inline fun TelegramMedia.asMediaGroupMemberTelegramMedia(): MediaGroupMemberTelegramMedia? = +inline fun TelegramFreeMedia.asMediaGroupMemberTelegramMedia(): MediaGroupMemberTelegramMedia? = this as? MediaGroupMemberTelegramMedia @PreviewFeature -inline fun TelegramMedia.requireMediaGroupMemberTelegramMedia(): MediaGroupMemberTelegramMedia = +inline fun TelegramFreeMedia.requireMediaGroupMemberTelegramMedia(): MediaGroupMemberTelegramMedia = this as MediaGroupMemberTelegramMedia @PreviewFeature -inline fun TelegramMedia.whenSizedTelegramMedia(block: (SizedTelegramMedia) -> T) = +inline fun TelegramFreeMedia.whenSizedTelegramMedia(block: (SizedTelegramMedia) -> T) = asSizedTelegramMedia()?.let(block) @PreviewFeature -inline fun TelegramMedia.asSizedTelegramMedia(): SizedTelegramMedia? = this as? SizedTelegramMedia +inline fun TelegramFreeMedia.asSizedTelegramMedia(): SizedTelegramMedia? = this as? SizedTelegramMedia @PreviewFeature -inline fun TelegramMedia.requireSizedTelegramMedia(): SizedTelegramMedia = this as SizedTelegramMedia +inline fun TelegramFreeMedia.requireSizedTelegramMedia(): SizedTelegramMedia = this as SizedTelegramMedia @PreviewFeature -inline fun TelegramMedia.whenThumbedTelegramMedia(block: (ThumbedTelegramMedia) -> T) = +inline fun TelegramFreeMedia.whenThumbedTelegramMedia(block: (ThumbedTelegramMedia) -> T) = asThumbedTelegramMedia()?.let(block) @PreviewFeature -inline fun TelegramMedia.asThumbedTelegramMedia(): ThumbedTelegramMedia? = this as? ThumbedTelegramMedia +inline fun TelegramFreeMedia.asThumbedTelegramMedia(): ThumbedTelegramMedia? = this as? ThumbedTelegramMedia @PreviewFeature -inline fun TelegramMedia.requireThumbedTelegramMedia(): ThumbedTelegramMedia = this as ThumbedTelegramMedia +inline fun TelegramFreeMedia.requireThumbedTelegramMedia(): ThumbedTelegramMedia = this as ThumbedTelegramMedia @PreviewFeature -inline fun TelegramMedia.whenTitledTelegramMedia(block: (TitledTelegramMedia) -> T) = +inline fun TelegramFreeMedia.whenTitledTelegramMedia(block: (TitledTelegramMedia) -> T) = asTitledTelegramMedia()?.let(block) @PreviewFeature -inline fun TelegramMedia.asTitledTelegramMedia(): TitledTelegramMedia? = this as? TitledTelegramMedia +inline fun TelegramFreeMedia.asTitledTelegramMedia(): TitledTelegramMedia? = this as? TitledTelegramMedia @PreviewFeature -inline fun TelegramMedia.requireTitledTelegramMedia(): TitledTelegramMedia = this as TitledTelegramMedia +inline fun TelegramFreeMedia.requireTitledTelegramMedia(): TitledTelegramMedia = this as TitledTelegramMedia @PreviewFeature -inline fun TelegramMedia.whenVisualMediaGroupMemberTelegramMedia(block: (VisualMediaGroupMemberTelegramMedia) -> T) = +inline fun TelegramFreeMedia.whenVisualMediaGroupMemberTelegramMedia(block: (VisualMediaGroupMemberTelegramMedia) -> T) = asVisualMediaGroupMemberTelegramMedia()?.let(block) @PreviewFeature -inline fun TelegramMedia.asVisualMediaGroupMemberTelegramMedia(): VisualMediaGroupMemberTelegramMedia? = +inline fun TelegramFreeMedia.asVisualMediaGroupMemberTelegramMedia(): VisualMediaGroupMemberTelegramMedia? = this as? VisualMediaGroupMemberTelegramMedia @PreviewFeature -inline fun TelegramMedia.requireVisualMediaGroupMemberTelegramMedia(): VisualMediaGroupMemberTelegramMedia = +inline fun TelegramFreeMedia.requireVisualMediaGroupMemberTelegramMedia(): VisualMediaGroupMemberTelegramMedia = this as VisualMediaGroupMemberTelegramMedia @PreviewFeature 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 e9ead34db5..ba7dcb4aa8 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 @@ -220,7 +220,7 @@ import dev.inmo.tgbotapi.types.media.DuratedTelegramMedia import dev.inmo.tgbotapi.types.media.MediaGroupMemberTelegramMedia import dev.inmo.tgbotapi.types.media.SizedTelegramMedia import dev.inmo.tgbotapi.types.media.SpoilerableTelegramMedia -import dev.inmo.tgbotapi.types.media.TelegramMedia +import dev.inmo.tgbotapi.types.media.TelegramFreeMedia import dev.inmo.tgbotapi.types.media.TelegramMediaAnimation import dev.inmo.tgbotapi.types.media.TelegramMediaAudio import dev.inmo.tgbotapi.types.media.TelegramMediaDocument @@ -2945,155 +2945,155 @@ public inline fun Location.liveLocationOrThrow(): LiveLocation = this as public inline fun Location.ifLiveLocation(block: (LiveLocation) -> T): T? = liveLocationOrNull() ?.let(block) -public inline fun TelegramMedia.duratedTelegramMediaOrNull(): DuratedTelegramMedia? = this as? +public inline fun TelegramFreeMedia.duratedTelegramMediaOrNull(): DuratedTelegramMedia? = this as? dev.inmo.tgbotapi.types.media.DuratedTelegramMedia -public inline fun TelegramMedia.duratedTelegramMediaOrThrow(): DuratedTelegramMedia = this as +public inline fun TelegramFreeMedia.duratedTelegramMediaOrThrow(): DuratedTelegramMedia = this as dev.inmo.tgbotapi.types.media.DuratedTelegramMedia -public inline fun TelegramMedia.ifDuratedTelegramMedia(block: (DuratedTelegramMedia) -> T): T? = +public inline fun TelegramFreeMedia.ifDuratedTelegramMedia(block: (DuratedTelegramMedia) -> T): T? = duratedTelegramMediaOrNull() ?.let(block) -public inline fun TelegramMedia.mediaGroupMemberTelegramMediaOrNull(): +public inline fun TelegramFreeMedia.mediaGroupMemberTelegramMediaOrNull(): MediaGroupMemberTelegramMedia? = this as? dev.inmo.tgbotapi.types.media.MediaGroupMemberTelegramMedia -public inline fun TelegramMedia.mediaGroupMemberTelegramMediaOrThrow(): +public inline fun TelegramFreeMedia.mediaGroupMemberTelegramMediaOrThrow(): MediaGroupMemberTelegramMedia = this as dev.inmo.tgbotapi.types.media.MediaGroupMemberTelegramMedia public inline fun - TelegramMedia.ifMediaGroupMemberTelegramMedia(block: (MediaGroupMemberTelegramMedia) -> T): T? = + TelegramFreeMedia.ifMediaGroupMemberTelegramMedia(block: (MediaGroupMemberTelegramMedia) -> T): T? = mediaGroupMemberTelegramMediaOrNull() ?.let(block) -public inline fun TelegramMedia.audioMediaGroupMemberTelegramMediaOrNull(): +public inline fun TelegramFreeMedia.audioMediaGroupMemberTelegramMediaOrNull(): AudioMediaGroupMemberTelegramMedia? = this as? dev.inmo.tgbotapi.types.media.AudioMediaGroupMemberTelegramMedia -public inline fun TelegramMedia.audioMediaGroupMemberTelegramMediaOrThrow(): +public inline fun TelegramFreeMedia.audioMediaGroupMemberTelegramMediaOrThrow(): AudioMediaGroupMemberTelegramMedia = this as dev.inmo.tgbotapi.types.media.AudioMediaGroupMemberTelegramMedia public inline fun - TelegramMedia.ifAudioMediaGroupMemberTelegramMedia(block: (AudioMediaGroupMemberTelegramMedia) -> T): + TelegramFreeMedia.ifAudioMediaGroupMemberTelegramMedia(block: (AudioMediaGroupMemberTelegramMedia) -> T): T? = audioMediaGroupMemberTelegramMediaOrNull() ?.let(block) -public inline fun TelegramMedia.documentMediaGroupMemberTelegramMediaOrNull(): +public inline fun TelegramFreeMedia.documentMediaGroupMemberTelegramMediaOrNull(): DocumentMediaGroupMemberTelegramMedia? = this as? dev.inmo.tgbotapi.types.media.DocumentMediaGroupMemberTelegramMedia -public inline fun TelegramMedia.documentMediaGroupMemberTelegramMediaOrThrow(): +public inline fun TelegramFreeMedia.documentMediaGroupMemberTelegramMediaOrThrow(): DocumentMediaGroupMemberTelegramMedia = this as dev.inmo.tgbotapi.types.media.DocumentMediaGroupMemberTelegramMedia public inline fun - TelegramMedia.ifDocumentMediaGroupMemberTelegramMedia(block: (DocumentMediaGroupMemberTelegramMedia) -> T): + TelegramFreeMedia.ifDocumentMediaGroupMemberTelegramMedia(block: (DocumentMediaGroupMemberTelegramMedia) -> T): T? = documentMediaGroupMemberTelegramMediaOrNull() ?.let(block) -public inline fun TelegramMedia.visualMediaGroupMemberTelegramMediaOrNull(): +public inline fun TelegramFreeMedia.visualMediaGroupMemberTelegramMediaOrNull(): VisualMediaGroupMemberTelegramMedia? = this as? dev.inmo.tgbotapi.types.media.VisualMediaGroupMemberTelegramMedia -public inline fun TelegramMedia.visualMediaGroupMemberTelegramMediaOrThrow(): +public inline fun TelegramFreeMedia.visualMediaGroupMemberTelegramMediaOrThrow(): VisualMediaGroupMemberTelegramMedia = this as dev.inmo.tgbotapi.types.media.VisualMediaGroupMemberTelegramMedia public inline fun - TelegramMedia.ifVisualMediaGroupMemberTelegramMedia(block: (VisualMediaGroupMemberTelegramMedia) -> T): + TelegramFreeMedia.ifVisualMediaGroupMemberTelegramMedia(block: (VisualMediaGroupMemberTelegramMedia) -> T): T? = visualMediaGroupMemberTelegramMediaOrNull() ?.let(block) -public inline fun TelegramMedia.sizedTelegramMediaOrNull(): SizedTelegramMedia? = this as? +public inline fun TelegramFreeMedia.sizedTelegramMediaOrNull(): SizedTelegramMedia? = this as? dev.inmo.tgbotapi.types.media.SizedTelegramMedia -public inline fun TelegramMedia.sizedTelegramMediaOrThrow(): SizedTelegramMedia = this as +public inline fun TelegramFreeMedia.sizedTelegramMediaOrThrow(): SizedTelegramMedia = this as dev.inmo.tgbotapi.types.media.SizedTelegramMedia -public inline fun TelegramMedia.ifSizedTelegramMedia(block: (SizedTelegramMedia) -> T): T? = +public inline fun TelegramFreeMedia.ifSizedTelegramMedia(block: (SizedTelegramMedia) -> T): T? = sizedTelegramMediaOrNull() ?.let(block) -public inline fun TelegramMedia.spoilerableTelegramMediaOrNull(): SpoilerableTelegramMedia? = this +public inline fun TelegramFreeMedia.spoilerableTelegramMediaOrNull(): SpoilerableTelegramMedia? = this as? dev.inmo.tgbotapi.types.media.SpoilerableTelegramMedia -public inline fun TelegramMedia.spoilerableTelegramMediaOrThrow(): SpoilerableTelegramMedia = this +public inline fun TelegramFreeMedia.spoilerableTelegramMediaOrThrow(): SpoilerableTelegramMedia = this as dev.inmo.tgbotapi.types.media.SpoilerableTelegramMedia public inline fun - TelegramMedia.ifSpoilerableTelegramMedia(block: (SpoilerableTelegramMedia) -> T): T? = + TelegramFreeMedia.ifSpoilerableTelegramMedia(block: (SpoilerableTelegramMedia) -> T): T? = spoilerableTelegramMediaOrNull() ?.let(block) -public inline fun TelegramMedia.telegramMediaAnimationOrNull(): TelegramMediaAnimation? = this as? +public inline fun TelegramFreeMedia.telegramMediaAnimationOrNull(): TelegramMediaAnimation? = this as? dev.inmo.tgbotapi.types.media.TelegramMediaAnimation -public inline fun TelegramMedia.telegramMediaAnimationOrThrow(): TelegramMediaAnimation = this as +public inline fun TelegramFreeMedia.telegramMediaAnimationOrThrow(): TelegramMediaAnimation = this as dev.inmo.tgbotapi.types.media.TelegramMediaAnimation -public inline fun TelegramMedia.ifTelegramMediaAnimation(block: (TelegramMediaAnimation) -> T): +public inline fun TelegramFreeMedia.ifTelegramMediaAnimation(block: (TelegramMediaAnimation) -> T): T? = telegramMediaAnimationOrNull() ?.let(block) -public inline fun TelegramMedia.telegramMediaAudioOrNull(): TelegramMediaAudio? = this as? +public inline fun TelegramFreeMedia.telegramMediaAudioOrNull(): TelegramMediaAudio? = this as? dev.inmo.tgbotapi.types.media.TelegramMediaAudio -public inline fun TelegramMedia.telegramMediaAudioOrThrow(): TelegramMediaAudio = this as +public inline fun TelegramFreeMedia.telegramMediaAudioOrThrow(): TelegramMediaAudio = this as dev.inmo.tgbotapi.types.media.TelegramMediaAudio -public inline fun TelegramMedia.ifTelegramMediaAudio(block: (TelegramMediaAudio) -> T): T? = +public inline fun TelegramFreeMedia.ifTelegramMediaAudio(block: (TelegramMediaAudio) -> T): T? = telegramMediaAudioOrNull() ?.let(block) -public inline fun TelegramMedia.telegramMediaDocumentOrNull(): TelegramMediaDocument? = this as? +public inline fun TelegramFreeMedia.telegramMediaDocumentOrNull(): TelegramMediaDocument? = this as? dev.inmo.tgbotapi.types.media.TelegramMediaDocument -public inline fun TelegramMedia.telegramMediaDocumentOrThrow(): TelegramMediaDocument = this as +public inline fun TelegramFreeMedia.telegramMediaDocumentOrThrow(): TelegramMediaDocument = this as dev.inmo.tgbotapi.types.media.TelegramMediaDocument -public inline fun TelegramMedia.ifTelegramMediaDocument(block: (TelegramMediaDocument) -> T): T? +public inline fun TelegramFreeMedia.ifTelegramMediaDocument(block: (TelegramMediaDocument) -> T): T? = telegramMediaDocumentOrNull() ?.let(block) -public inline fun TelegramMedia.telegramMediaPhotoOrNull(): TelegramMediaPhoto? = this as? +public inline fun TelegramFreeMedia.telegramMediaPhotoOrNull(): TelegramMediaPhoto? = this as? dev.inmo.tgbotapi.types.media.TelegramMediaPhoto -public inline fun TelegramMedia.telegramMediaPhotoOrThrow(): TelegramMediaPhoto = this as +public inline fun TelegramFreeMedia.telegramMediaPhotoOrThrow(): TelegramMediaPhoto = this as dev.inmo.tgbotapi.types.media.TelegramMediaPhoto -public inline fun TelegramMedia.ifTelegramMediaPhoto(block: (TelegramMediaPhoto) -> T): T? = +public inline fun TelegramFreeMedia.ifTelegramMediaPhoto(block: (TelegramMediaPhoto) -> T): T? = telegramMediaPhotoOrNull() ?.let(block) -public inline fun TelegramMedia.telegramMediaVideoOrNull(): TelegramMediaVideo? = this as? +public inline fun TelegramFreeMedia.telegramMediaVideoOrNull(): TelegramMediaVideo? = this as? dev.inmo.tgbotapi.types.media.TelegramMediaVideo -public inline fun TelegramMedia.telegramMediaVideoOrThrow(): TelegramMediaVideo = this as +public inline fun TelegramFreeMedia.telegramMediaVideoOrThrow(): TelegramMediaVideo = this as dev.inmo.tgbotapi.types.media.TelegramMediaVideo -public inline fun TelegramMedia.ifTelegramMediaVideo(block: (TelegramMediaVideo) -> T): T? = +public inline fun TelegramFreeMedia.ifTelegramMediaVideo(block: (TelegramMediaVideo) -> T): T? = telegramMediaVideoOrNull() ?.let(block) -public inline fun TelegramMedia.thumbedTelegramMediaOrNull(): ThumbedTelegramMedia? = this as? +public inline fun TelegramFreeMedia.thumbedTelegramMediaOrNull(): ThumbedTelegramMedia? = this as? dev.inmo.tgbotapi.types.media.ThumbedTelegramMedia -public inline fun TelegramMedia.thumbedTelegramMediaOrThrow(): ThumbedTelegramMedia = this as +public inline fun TelegramFreeMedia.thumbedTelegramMediaOrThrow(): ThumbedTelegramMedia = this as dev.inmo.tgbotapi.types.media.ThumbedTelegramMedia -public inline fun TelegramMedia.ifThumbedTelegramMedia(block: (ThumbedTelegramMedia) -> T): T? = +public inline fun TelegramFreeMedia.ifThumbedTelegramMedia(block: (ThumbedTelegramMedia) -> T): T? = thumbedTelegramMediaOrNull() ?.let(block) -public inline fun TelegramMedia.titledTelegramMediaOrNull(): TitledTelegramMedia? = this as? +public inline fun TelegramFreeMedia.titledTelegramMediaOrNull(): TitledTelegramMedia? = this as? dev.inmo.tgbotapi.types.media.TitledTelegramMedia -public inline fun TelegramMedia.titledTelegramMediaOrThrow(): TitledTelegramMedia = this as +public inline fun TelegramFreeMedia.titledTelegramMediaOrThrow(): TitledTelegramMedia = this as dev.inmo.tgbotapi.types.media.TitledTelegramMedia -public inline fun TelegramMedia.ifTitledTelegramMedia(block: (TitledTelegramMedia) -> T): T? = +public inline fun TelegramFreeMedia.ifTitledTelegramMedia(block: (TitledTelegramMedia) -> T): T? = titledTelegramMediaOrNull() ?.let(block) -public inline fun TelegramMedia.withCustomizableCaptionTelegramMediaOrNull(): +public inline fun TelegramFreeMedia.withCustomizableCaptionTelegramMediaOrNull(): WithCustomizableCaptionTelegramMedia? = this as? dev.inmo.tgbotapi.types.media.WithCustomizableCaptionTelegramMedia -public inline fun TelegramMedia.withCustomizableCaptionTelegramMediaOrThrow(): +public inline fun TelegramFreeMedia.withCustomizableCaptionTelegramMediaOrThrow(): WithCustomizableCaptionTelegramMedia = this as dev.inmo.tgbotapi.types.media.WithCustomizableCaptionTelegramMedia public inline fun - TelegramMedia.ifWithCustomizableCaptionTelegramMedia(block: (WithCustomizableCaptionTelegramMedia) -> T): + TelegramFreeMedia.ifWithCustomizableCaptionTelegramMedia(block: (WithCustomizableCaptionTelegramMedia) -> T): T? = withCustomizableCaptionTelegramMediaOrNull() ?.let(block) public inline fun ChatEvent.chatBackgroundOrNull(): ChatBackground? = this as?