mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-09-14 21:00:15 +00:00
Merge branch '15.1.0' into bot-api-7.6
This commit is contained in:
@@ -192,7 +192,7 @@ data class SendMediaGroupData internal constructor(
|
||||
private val convertedMedia: String
|
||||
get() = buildJsonArray {
|
||||
media.forEach {
|
||||
add(it.toJsonWithoutNulls(MediaGroupMemberTelegramFreeMediaSerializer))
|
||||
add(it.toJsonWithoutNulls(MediaGroupMemberTelegramMediaSerializer))
|
||||
}
|
||||
}.toString()
|
||||
|
||||
|
@@ -0,0 +1,165 @@
|
||||
package dev.inmo.tgbotapi.requests.send.media
|
||||
|
||||
import dev.inmo.tgbotapi.types.media.TelegramPaidMedia
|
||||
import dev.inmo.tgbotapi.types.message.content.PaidMediaInfoContent
|
||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||
import dev.inmo.tgbotapi.requests.common.CommonMultipartFileRequest
|
||||
import dev.inmo.tgbotapi.requests.send.abstracts.*
|
||||
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.message.textsources.TextSourcesList
|
||||
import dev.inmo.tgbotapi.types.message.ParseMode
|
||||
import dev.inmo.tgbotapi.types.message.parseModeField
|
||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.message.*
|
||||
import dev.inmo.tgbotapi.types.message.RawMessageEntity
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
|
||||
import dev.inmo.tgbotapi.types.message.toRawMessageEntities
|
||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
||||
import dev.inmo.tgbotapi.utils.throwRangeError
|
||||
import kotlinx.serialization.*
|
||||
|
||||
fun SendPaidMedia(
|
||||
chatId: ChatIdentifier,
|
||||
starCount: Int,
|
||||
media: List<TelegramPaidMedia>,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
showCaptionAboveMedia: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyParameters: ReplyParameters? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
): Request<ContentMessage<PaidMediaInfoContent>> {
|
||||
val data = SendPaidMediaData(
|
||||
chatId = chatId,
|
||||
starCount = starCount,
|
||||
media = media,
|
||||
text = text,
|
||||
parseMode = parseMode,
|
||||
rawEntities = null,
|
||||
showCaptionAboveMedia = showCaptionAboveMedia,
|
||||
threadId = threadId,
|
||||
businessConnectionId = businessConnectionId,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
replyParameters = replyParameters,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
|
||||
return if (media.any { it.file is MultipartFile }) {
|
||||
CommonMultipartFileRequest(
|
||||
data,
|
||||
media.mapNotNull { it.media to (it.file as? MultipartFile ?: return@mapNotNull null) }.toMap()
|
||||
)
|
||||
} else {
|
||||
data
|
||||
}
|
||||
}
|
||||
|
||||
fun SendPaidMedia(
|
||||
chatId: ChatIdentifier,
|
||||
starCount: Int,
|
||||
media: List<TelegramPaidMedia>,
|
||||
entities: TextSourcesList,
|
||||
showCaptionAboveMedia: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
replyParameters: ReplyParameters? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
): Request<ContentMessage<PaidMediaInfoContent>> {
|
||||
val data = SendPaidMediaData(
|
||||
chatId = chatId,
|
||||
starCount = starCount,
|
||||
media = media,
|
||||
text = entities.makeString(),
|
||||
parseMode = null,
|
||||
rawEntities = entities.toRawMessageEntities(),
|
||||
showCaptionAboveMedia = showCaptionAboveMedia,
|
||||
threadId = threadId,
|
||||
businessConnectionId = businessConnectionId,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
replyParameters = replyParameters,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
|
||||
return if (media.any { it.file is MultipartFile }) {
|
||||
CommonMultipartFileRequest(
|
||||
data,
|
||||
media.mapNotNull { it.media to (it.file as? MultipartFile ?: return@mapNotNull null) }.toMap()
|
||||
)
|
||||
} else {
|
||||
data
|
||||
}
|
||||
}
|
||||
|
||||
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<PaidMediaInfoContent>>
|
||||
= TelegramBotAPIMessageDeserializationStrategyClass()
|
||||
|
||||
@Serializable
|
||||
data class SendPaidMediaData internal constructor(
|
||||
@SerialName(chatIdField)
|
||||
override val chatId: ChatIdentifier,
|
||||
@SerialName(starCountField)
|
||||
val starCount: Int,
|
||||
@SerialName(mediaField)
|
||||
val media: List<TelegramPaidMedia>,
|
||||
@SerialName(captionField)
|
||||
override val text: String? = null,
|
||||
@SerialName(parseModeField)
|
||||
override val parseMode: ParseMode? = null,
|
||||
@SerialName(captionEntitiesField)
|
||||
private val rawEntities: List<RawMessageEntity>? = null,
|
||||
@SerialName(showCaptionAboveMediaField)
|
||||
override val showCaptionAboveMedia: Boolean = false,
|
||||
@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(replyParametersField)
|
||||
override val replyParameters: ReplyParameters? = null,
|
||||
@SerialName(replyMarkupField)
|
||||
override val replyMarkup: KeyboardMarkup? = null
|
||||
) : DataRequest<ContentMessage<PaidMediaInfoContent>>,
|
||||
SendContentMessageRequest<ContentMessage<PaidMediaInfoContent>>,
|
||||
ReplyingMarkupSendMessageRequest<ContentMessage<PaidMediaInfoContent>>,
|
||||
TextableSendMessageRequest<ContentMessage<PaidMediaInfoContent>>,
|
||||
WithCustomizableCaptionRequest<ContentMessage<PaidMediaInfoContent>>
|
||||
{
|
||||
override val textSources: TextSourcesList? by lazy {
|
||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
||||
}
|
||||
override val effectId: EffectId?
|
||||
get() = null
|
||||
|
||||
init {
|
||||
text ?.let {
|
||||
if (it.length !in captionLength) {
|
||||
throwRangeError("Caption length", captionLength, it.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun method(): String = "sendPaidMedia"
|
||||
override val resultDeserializer: DeserializationStrategy<ContentMessage<PaidMediaInfoContent>>
|
||||
get() = commonResultDeserializer
|
||||
override val requestSerializer: SerializationStrategy<*>
|
||||
get() = serializer()
|
||||
}
|
||||
|
||||
data class SendPaidMediaFiles internal constructor(
|
||||
val photo: MultipartFile
|
||||
) : Files by mapOf(
|
||||
photoField to photo
|
||||
)
|
@@ -1,209 +0,0 @@
|
||||
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 <T : MediaGroupPartContent> SendMediaGroup(
|
||||
chatId: ChatIdentifier,
|
||||
media: List<MediaGroupMemberTelegramMedia>,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
effectId: EffectId? = null,
|
||||
replyParameters: ReplyParameters? = null
|
||||
): Request<ContentMessage<MediaGroupContent<T>>> {
|
||||
if (media.size !in mediaCountInMediaGroup) {
|
||||
throwRangeError("Count of members in media group", mediaCountInMediaGroup, media.size)
|
||||
}
|
||||
|
||||
val files: List<MultipartFile> = 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<ContentMessage<MediaGroupContent<T>>>
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<AudioMediaGroupMemberTelegramMedia>,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
effectId: EffectId? = null,
|
||||
replyParameters: ReplyParameters? = null
|
||||
) = SendMediaGroup<AudioContent>(
|
||||
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<DocumentMediaGroupMemberTelegramMedia>,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
effectId: EffectId? = null,
|
||||
replyParameters: ReplyParameters? = null
|
||||
) = SendMediaGroup<DocumentContent>(
|
||||
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<VisualMediaGroupMemberTelegramMedia>,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
effectId: EffectId? = null,
|
||||
replyParameters: ReplyParameters? = null,
|
||||
) = SendMediaGroup<VisualMediaGroupPartContent>(
|
||||
chatId = chatId,
|
||||
media = media,
|
||||
threadId = threadId,
|
||||
businessConnectionId = businessConnectionId,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
effectId = effectId,
|
||||
replyParameters = replyParameters
|
||||
)
|
||||
|
||||
private object MessagesListSerializer: KSerializer<PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>>> {
|
||||
private val serializer = ListSerializer(TelegramBotAPIMessageDeserializeOnlySerializerClass<PossiblySentViaBotCommonMessage<MediaGroupPartContent>>())
|
||||
override val descriptor: SerialDescriptor = serializer.descriptor
|
||||
|
||||
override fun deserialize(decoder: Decoder): PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>> {
|
||||
val messages = serializer.deserialize(decoder)
|
||||
return messages.asMediaGroupMessage()
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>>) {
|
||||
serializer.serialize(encoder, value.content.group.map { it.sourceMessage })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class SendMediaGroupData internal constructor(
|
||||
@SerialName(chatIdField)
|
||||
override val chatId: ChatIdentifier,
|
||||
val media: List<MediaGroupMemberTelegramPaidMedia> = 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<PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>>>,
|
||||
SendContentMessageRequest<PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>>> {
|
||||
@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<PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>>>
|
||||
get() = MessagesListSerializer
|
||||
}
|
||||
|
||||
data class SendMediaGroupFiles internal constructor(
|
||||
val files: List<MultipartFile>
|
||||
) : Files by (files.map { it.fileId to it }.toMap())
|
@@ -242,6 +242,7 @@ const val inviteLinkField = "invite_link"
|
||||
const val viaChatFolderInviteLinkField = "via_chat_folder_invite_link"
|
||||
const val viaJoinRequestField = "via_join_request"
|
||||
const val pinnedMessageField = "pinned_message"
|
||||
const val canSendPaidMediaField = "can_send_paid_media"
|
||||
const val activeUsernamesField = "active_usernames"
|
||||
const val customTitleField = "custom_title"
|
||||
const val optionIdsField = "option_ids"
|
||||
|
@@ -34,6 +34,8 @@ data class ExtendedChannelChatImpl(
|
||||
@SerialName(pinnedMessageField)
|
||||
@Serializable(TelegramBotAPIMessageDeserializeOnlySerializer::class)
|
||||
override val pinnedMessage: Message? = null,
|
||||
@SerialName(canSendPaidMediaField)
|
||||
override val canSendPaidMedia: Boolean = false,
|
||||
@SerialName(linkedChatIdField)
|
||||
override val linkedGroupChatId: IdChatIdentifier? = null,
|
||||
@SerialName(hasHiddenMembersField)
|
||||
|
@@ -30,6 +30,7 @@ sealed interface ExtendedNonBotChat : ExtendedChat {
|
||||
@Serializable(ExtendedChatSerializer.Companion::class)
|
||||
sealed interface ExtendedChannelChat : ChannelChat, ExtendedPublicChat, ExtendedChatWithUsername {
|
||||
val linkedGroupChatId: IdChatIdentifier?
|
||||
val canSendPaidMedia: Boolean
|
||||
}
|
||||
|
||||
@Serializable(ExtendedChatSerializer.Companion::class)
|
||||
|
@@ -4,24 +4,13 @@ import dev.inmo.tgbotapi.abstracts.TextedOutput
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.StringFormat
|
||||
|
||||
@Serializable(MediaGroupMemberTelegramFreeMediaSerializer::class)
|
||||
sealed interface MediaGroupMemberTelegramMedia : TelegramMedia {
|
||||
@Serializable(MediaGroupMemberTelegramMediaSerializer::class)
|
||||
sealed interface MediaGroupMemberTelegramMedia : TelegramMedia, TextedOutput {
|
||||
fun serialize(format: StringFormat): String
|
||||
}
|
||||
|
||||
@Serializable(MediaGroupMemberTelegramFreeMediaSerializer::class)
|
||||
sealed interface MediaGroupMemberTelegramFreeMedia : MediaGroupMemberTelegramMedia, TextedOutput
|
||||
@Serializable(MediaGroupMemberTelegramFreeMediaSerializer::class)
|
||||
sealed interface MediaGroupMemberTelegramPaidMedia : MediaGroupMemberTelegramMedia
|
||||
sealed interface AudioMediaGroupMemberTelegramMedia: MediaGroupMemberTelegramMedia
|
||||
sealed interface DocumentMediaGroupMemberTelegramMedia: MediaGroupMemberTelegramMedia
|
||||
|
||||
sealed interface AudioMediaGroupMemberTelegramMedia: MediaGroupMemberTelegramFreeMedia
|
||||
sealed interface DocumentMediaGroupMemberTelegramMedia: MediaGroupMemberTelegramFreeMedia
|
||||
|
||||
@Serializable(MediaGroupMemberTelegramFreeMediaSerializer::class)
|
||||
sealed interface VisualMediaGroupMemberTelegramMedia : MediaGroupMemberTelegramMedia
|
||||
|
||||
@Serializable(MediaGroupMemberTelegramFreeMediaSerializer::class)
|
||||
sealed interface VisualMediaGroupMemberTelegramFreeMedia : MediaGroupMemberTelegramFreeMedia, VisualMediaGroupMemberTelegramMedia, SpoilerableTelegramMedia, WithCustomizableCaptionTelegramMedia
|
||||
|
||||
@Serializable(MediaGroupMemberTelegramPaidMediaSerializer::class)
|
||||
sealed interface VisualMediaGroupMemberTelegramPaidMedia : MediaGroupMemberTelegramPaidMedia, VisualMediaGroupMemberTelegramMedia
|
||||
@Serializable(MediaGroupMemberTelegramMediaSerializer::class)
|
||||
sealed interface VisualMediaGroupMemberTelegramMedia : MediaGroupMemberTelegramMedia, SpoilerableTelegramMedia, WithCustomizableCaptionTelegramMedia
|
||||
|
@@ -11,10 +11,10 @@ import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.json.*
|
||||
|
||||
@RiskFeature
|
||||
object MediaGroupMemberTelegramFreeMediaSerializer : KSerializer<MediaGroupMemberTelegramFreeMedia> {
|
||||
object MediaGroupMemberTelegramMediaSerializer : KSerializer<MediaGroupMemberTelegramMedia> {
|
||||
@OptIn(InternalSerializationApi::class)
|
||||
override val descriptor: SerialDescriptor = buildSerialDescriptor(MediaGroupMemberTelegramMedia::class.toString(), PolymorphicKind.OPEN)
|
||||
override fun serialize(encoder: Encoder, value: MediaGroupMemberTelegramFreeMedia) {
|
||||
override fun serialize(encoder: Encoder, value: MediaGroupMemberTelegramMedia) {
|
||||
when (value) {
|
||||
is TelegramMediaPhoto -> TelegramMediaPhoto.serializer().serialize(encoder, value)
|
||||
is TelegramMediaVideo -> TelegramMediaVideo.serializer().serialize(encoder, value)
|
||||
@@ -23,7 +23,7 @@ object MediaGroupMemberTelegramFreeMediaSerializer : KSerializer<MediaGroupMembe
|
||||
}
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder): MediaGroupMemberTelegramFreeMedia {
|
||||
override fun deserialize(decoder: Decoder): MediaGroupMemberTelegramMedia {
|
||||
val json = JsonObject.serializer().deserialize(decoder)
|
||||
|
||||
return when (json[typeField] ?.jsonPrimitive ?.contentOrNull) {
|
||||
@@ -35,5 +35,3 @@ object MediaGroupMemberTelegramFreeMediaSerializer : KSerializer<MediaGroupMembe
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typealias MediaGroupMemberTelegramMediaSerializer = MediaGroupMemberTelegramFreeMediaSerializer
|
@@ -1,38 +0,0 @@
|
||||
package dev.inmo.tgbotapi.types.media
|
||||
|
||||
import dev.inmo.tgbotapi.types.typeField
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.nonstrictJsonFormat
|
||||
import kotlinx.serialization.InternalSerializationApi
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.descriptors.PolymorphicKind
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.descriptors.buildSerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.contentOrNull
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
|
||||
@RiskFeature
|
||||
object MediaGroupMemberTelegramPaidMediaSerializer : KSerializer<MediaGroupMemberTelegramPaidMedia> {
|
||||
@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")
|
||||
}
|
||||
}
|
||||
}
|
@@ -5,5 +5,4 @@ import dev.inmo.tgbotapi.requests.abstracts.InputFile
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable(TelegramMediaSerializer::class)
|
||||
@ClassCastsIncluded
|
||||
sealed interface TelegramFreeMedia : TelegramMedia
|
||||
|
@@ -43,7 +43,7 @@ data class TelegramMediaPhoto internal constructor(
|
||||
override val spoilered: Boolean = false,
|
||||
@SerialName(showCaptionAboveMediaField)
|
||||
override val showCaptionAboveMedia: Boolean = false,
|
||||
) : TelegramFreeMedia, VisualMediaGroupMemberTelegramFreeMedia {
|
||||
) : TelegramFreeMedia, VisualMediaGroupMemberTelegramMedia {
|
||||
override val type: String = photoTelegramMediaType
|
||||
override val textSources: TextSourcesList? by lazy {
|
||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
||||
|
@@ -76,7 +76,7 @@ data class TelegramMediaVideo internal constructor (
|
||||
override val height: Int? = null,
|
||||
override val duration: Long? = null,
|
||||
override val thumb: InputFile? = null
|
||||
) : TelegramFreeMedia, SizedTelegramMedia, DuratedTelegramMedia, ThumbedTelegramMedia, VisualMediaGroupMemberTelegramFreeMedia {
|
||||
) : TelegramFreeMedia, SizedTelegramMedia, DuratedTelegramMedia, ThumbedTelegramMedia, VisualMediaGroupMemberTelegramMedia {
|
||||
override val type: String = videoTelegramMediaType
|
||||
override val textSources: TextSourcesList? by lazy {
|
||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
||||
|
@@ -5,5 +5,7 @@ import dev.inmo.tgbotapi.requests.abstracts.InputFile
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable(TelegramMediaSerializer::class)
|
||||
@ClassCastsIncluded
|
||||
sealed interface TelegramPaidMedia : TelegramMedia
|
||||
|
||||
@Serializable(TelegramMediaSerializer::class)
|
||||
sealed interface VisualTelegramPaidMedia : TelegramPaidMedia
|
||||
|
@@ -18,11 +18,9 @@ internal const val photoTelegramPaidMediaType = "photo"
|
||||
@Serializable
|
||||
data class TelegramPaidMediaPhoto internal constructor(
|
||||
override val file: InputFile,
|
||||
) : TelegramPaidMedia, VisualMediaGroupMemberTelegramPaidMedia {
|
||||
) : VisualTelegramPaidMedia {
|
||||
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
|
||||
|
@@ -18,11 +18,9 @@ data class TelegramPaidMediaVideo (
|
||||
override val duration: Long? = null,
|
||||
@SerialName(supportsStreamingField)
|
||||
val supportsStreaming: Boolean = false,
|
||||
) : TelegramPaidMedia, SizedTelegramMedia, DuratedTelegramMedia, ThumbedTelegramMedia, VisualMediaGroupMemberTelegramPaidMedia {
|
||||
) : TelegramPaidMedia, SizedTelegramMedia, DuratedTelegramMedia, ThumbedTelegramMedia, VisualTelegramPaidMedia {
|
||||
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
|
||||
|
@@ -72,7 +72,7 @@ internal data class RawMessage(
|
||||
private val story: Story? = null,
|
||||
private val audio: AudioFile? = null,
|
||||
private val document: DocumentFile? = null,
|
||||
private val paid_media: PaidMediaInfoContent? = null,
|
||||
private val paid_media: PaidMediaInfo? = null,
|
||||
private val animation: AnimationFile? = null,
|
||||
private val game: RawGame? = null,
|
||||
@Serializable(PhotoSerializer::class)
|
||||
@@ -202,7 +202,7 @@ internal data class RawMessage(
|
||||
quote
|
||||
)
|
||||
paid_media != null -> PaidMediaInfoContent(
|
||||
document,
|
||||
paid_media,
|
||||
caption,
|
||||
adaptedCaptionEntities,
|
||||
quote
|
||||
|
@@ -140,7 +140,7 @@ sealed interface TextedContent : MessageContent, TextedInput
|
||||
|
||||
sealed interface MediaContent: MessageContent {
|
||||
val media: TelegramMediaFile
|
||||
fun asTelegramMedia(): TelegramMedia
|
||||
fun asTelegramMedia(): TelegramFreeMedia
|
||||
}
|
||||
|
||||
sealed interface SpoilerableMediaContent : MediaContent, SpoilerableData
|
||||
|
@@ -1,7 +1,10 @@
|
||||
package dev.inmo.tgbotapi.types.message.content
|
||||
|
||||
import dev.inmo.tgbotapi.abstracts.WithCustomizableCaption
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
import dev.inmo.tgbotapi.requests.send.media.SendPaidMedia
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.abstracts.WithOptionalQuoteInfo
|
||||
import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId
|
||||
import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList
|
||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
@@ -19,16 +22,7 @@ data class PaidMediaInfoContent(
|
||||
override val textSources: TextSourcesList = emptyList(),
|
||||
override val quote: TextQuote? = null,
|
||||
override val showCaptionAboveMedia: Boolean = false
|
||||
) : TextedMediaContent, WithCustomizedCaptionMediaContent {
|
||||
override val media: TelegramMediaFile
|
||||
get() = paidMediaInfo.media.fir
|
||||
override fun asTelegramMedia(): TelegramMediaFile = when (val media = media) {
|
||||
is PaidMedia.Photo -> media.photo.biggest.toTelegramPaidMediaPhoto()
|
||||
is PaidMedia.Preview,
|
||||
is PaidMedia.Unknown -> error("Unable to create telegram media out of $media")
|
||||
is PaidMedia.Video -> media.video.toTelegramPaidMediaVideo()
|
||||
}
|
||||
|
||||
) : MessageContent, TextedContent, WithCustomizableCaption, WithOptionalQuoteInfo {
|
||||
override fun createResend(
|
||||
chatId: ChatIdentifier,
|
||||
messageThreadId: MessageThreadId?,
|
||||
@@ -38,5 +32,22 @@ data class PaidMediaInfoContent(
|
||||
effectId: EffectId?,
|
||||
replyParameters: ReplyParameters?,
|
||||
replyMarkup: KeyboardMarkup?
|
||||
): Request<ContentMessage<PaidMediaInfoContent>> = TODO()
|
||||
): Request<ContentMessage<PaidMediaInfoContent>> = SendPaidMedia(
|
||||
chatId,
|
||||
paidMediaInfo.stars,
|
||||
paidMediaInfo.media.mapNotNull {
|
||||
when (it) {
|
||||
is PaidMedia.Photo -> it.photo.biggest.toTelegramPaidMediaPhoto()
|
||||
is PaidMedia.Preview -> null
|
||||
is PaidMedia.Unknown -> null
|
||||
is PaidMedia.Video -> it.video.toTelegramPaidMediaVideo()
|
||||
}
|
||||
}.ifEmpty {
|
||||
error("Unable to create resend for paid media content without any revealed content")
|
||||
},
|
||||
textSources,
|
||||
showCaptionAboveMedia,
|
||||
messageThreadId,
|
||||
businessConnectionId, disableNotification, protectContent, replyParameters, replyMarkup
|
||||
)
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ import dev.inmo.tgbotapi.types.userField
|
||||
import dev.inmo.tgbotapi.types.withdrawalStateField
|
||||
import dev.inmo.tgbotapi.utils.decodeDataAndJson
|
||||
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
|
||||
import kotlinx.serialization.EncodeDefault
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@@ -26,6 +27,7 @@ sealed interface TransactionPartner {
|
||||
@SerialName(withdrawalStateField)
|
||||
val withdrawalState: RevenueWithdrawalState
|
||||
) : TransactionPartner {
|
||||
@EncodeDefault
|
||||
override val type: String
|
||||
get() = Companion.type
|
||||
|
||||
@@ -49,8 +51,15 @@ sealed interface TransactionPartner {
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable(TransactionPartner.Companion::class)
|
||||
data object Ads : TransactionPartner {
|
||||
@EncodeDefault
|
||||
override val type: String = "telegram_ads"
|
||||
}
|
||||
|
||||
@Serializable(TransactionPartner.Companion::class)
|
||||
data object Other : TransactionPartner {
|
||||
@EncodeDefault
|
||||
override val type: String = "other"
|
||||
}
|
||||
|
||||
@@ -84,6 +93,7 @@ sealed interface TransactionPartner {
|
||||
User.type -> User(
|
||||
data.user ?: return unknown,
|
||||
)
|
||||
Ads.type -> Ads
|
||||
Fragment.type -> Fragment(
|
||||
data.withdrawal_state ?: return unknown,
|
||||
)
|
||||
@@ -94,6 +104,7 @@ sealed interface TransactionPartner {
|
||||
override fun serialize(encoder: Encoder, value: TransactionPartner) {
|
||||
val surrogate = when (value) {
|
||||
Other -> Surrogate(value.type)
|
||||
Ads -> Surrogate(value.type)
|
||||
is User -> Surrogate(value.type, user = value.user)
|
||||
is Fragment -> Surrogate(
|
||||
value.type,
|
||||
|
@@ -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.PhotoFile
|
||||
import dev.inmo.tgbotapi.types.media.MediaGroupMemberTelegramFreeMediaSerializer
|
||||
import dev.inmo.tgbotapi.types.media.MediaGroupMemberTelegramMediaSerializer
|
||||
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(
|
||||
MediaGroupMemberTelegramFreeMediaSerializer,
|
||||
MediaGroupMemberTelegramMediaSerializer,
|
||||
inputMedia
|
||||
)
|
||||
assertEquals(
|
||||
inputMedia,
|
||||
nonstrictJsonFormat.decodeFromString(
|
||||
MediaGroupMemberTelegramFreeMediaSerializer,
|
||||
MediaGroupMemberTelegramMediaSerializer,
|
||||
encoded
|
||||
)
|
||||
)
|
||||
|
Reference in New Issue
Block a user