1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-09-15 13:19:30 +00:00

add sendPaidMedia, refactor telegram media, fix build

This commit is contained in:
2024-07-09 01:56:53 +06:00
parent 9dd80be36d
commit 5baa09f0c1
27 changed files with 1231 additions and 510 deletions

View File

@@ -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()

View File

@@ -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
)

View File

@@ -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())

View File

@@ -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"

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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")
}
}
}

View File

@@ -5,5 +5,4 @@ import dev.inmo.tgbotapi.requests.abstracts.InputFile
import kotlinx.serialization.Serializable
@Serializable(TelegramMediaSerializer::class)
@ClassCastsIncluded
sealed interface TelegramFreeMedia : TelegramMedia

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
)
}

View File

@@ -5,6 +5,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
@@ -24,6 +25,7 @@ sealed interface TransactionPartner {
@SerialName(withdrawalStateField)
val withdrawalState: RevenueWithdrawalState
) : TransactionPartner {
@EncodeDefault
override val type: String
get() = Companion.type
@@ -45,8 +47,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"
}
@@ -78,6 +87,7 @@ sealed interface TransactionPartner {
User.type -> User(
data.user ?: return unknown,
)
Ads.type -> Ads
Fragment.type -> Fragment(
data.withdrawal_state ?: return unknown,
)
@@ -88,6 +98,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,

View File

@@ -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
)
)