mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2026-06-18 09:15:10 +00:00
add LivePhotos support
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
@file:Suppress("FunctionName")
|
||||
|
||||
package dev.inmo.tgbotapi.requests.send.media
|
||||
|
||||
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.buttons.KeyboardMarkup
|
||||
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.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.content.LivePhotoContent
|
||||
import dev.inmo.tgbotapi.types.message.toRawMessageEntities
|
||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
||||
import dev.inmo.tgbotapi.utils.mapOfNotNull
|
||||
import dev.inmo.tgbotapi.utils.throwRangeError
|
||||
import kotlinx.serialization.*
|
||||
|
||||
fun SendLivePhoto(
|
||||
chatId: ChatIdentifier,
|
||||
livePhoto: InputFile,
|
||||
photo: InputFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
showCaptionAboveMedia: Boolean = false,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
directMessageThreadId: DirectMessageThreadId? = chatId.directMessageThreadId,
|
||||
businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowPaidBroadcast: Boolean = false,
|
||||
effectId: EffectId? = null,
|
||||
suggestedPostParameters: SuggestedPostParameters? = null,
|
||||
replyParameters: ReplyParameters? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
): Request<ContentMessage<LivePhotoContent>> {
|
||||
val livePhotoAsFile = livePhoto as? MultipartFile
|
||||
val photoAsFile = photo as? MultipartFile
|
||||
|
||||
val data = SendLivePhotoData(
|
||||
chatId = chatId,
|
||||
livePhoto = livePhoto,
|
||||
photo = photo,
|
||||
text = text,
|
||||
parseMode = parseMode,
|
||||
rawEntities = null,
|
||||
showCaptionAboveMedia = showCaptionAboveMedia,
|
||||
spoilered = spoilered,
|
||||
threadId = threadId,
|
||||
directMessageThreadId = directMessageThreadId,
|
||||
businessConnectionId = businessConnectionId,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowPaidBroadcast = allowPaidBroadcast,
|
||||
effectId = effectId,
|
||||
suggestedPostParameters = suggestedPostParameters,
|
||||
replyParameters = replyParameters,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
|
||||
return if (livePhotoAsFile == null && photoAsFile == null) {
|
||||
data
|
||||
} else {
|
||||
CommonMultipartFileRequest(
|
||||
data,
|
||||
listOfNotNull(livePhotoAsFile, photoAsFile).associateBy { it.fileId }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun SendLivePhoto(
|
||||
chatId: ChatIdentifier,
|
||||
livePhoto: InputFile,
|
||||
photo: InputFile,
|
||||
entities: TextSourcesList,
|
||||
showCaptionAboveMedia: Boolean = false,
|
||||
spoilered: Boolean = false,
|
||||
threadId: MessageThreadId? = chatId.threadId,
|
||||
directMessageThreadId: DirectMessageThreadId? = chatId.directMessageThreadId,
|
||||
businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,
|
||||
disableNotification: Boolean = false,
|
||||
protectContent: Boolean = false,
|
||||
allowPaidBroadcast: Boolean = false,
|
||||
effectId: EffectId? = null,
|
||||
suggestedPostParameters: SuggestedPostParameters? = null,
|
||||
replyParameters: ReplyParameters? = null,
|
||||
replyMarkup: KeyboardMarkup? = null
|
||||
): Request<ContentMessage<LivePhotoContent>> {
|
||||
val livePhotoAsFile = livePhoto as? MultipartFile
|
||||
val photoAsFile = photo as? MultipartFile
|
||||
|
||||
val data = SendLivePhotoData(
|
||||
chatId = chatId,
|
||||
livePhoto = livePhoto,
|
||||
photo = photo,
|
||||
text = entities.makeString(),
|
||||
parseMode = null,
|
||||
rawEntities = entities.toRawMessageEntities(),
|
||||
showCaptionAboveMedia = showCaptionAboveMedia,
|
||||
spoilered = spoilered,
|
||||
threadId = threadId,
|
||||
directMessageThreadId = directMessageThreadId,
|
||||
businessConnectionId = businessConnectionId,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowPaidBroadcast = allowPaidBroadcast,
|
||||
effectId = effectId,
|
||||
suggestedPostParameters = suggestedPostParameters,
|
||||
replyParameters = replyParameters,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
|
||||
return if (livePhotoAsFile == null && photoAsFile == null) {
|
||||
data
|
||||
} else {
|
||||
CommonMultipartFileRequest(
|
||||
data,
|
||||
listOfNotNull(livePhotoAsFile, photoAsFile).associateBy { it.fileId }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<LivePhotoContent>>
|
||||
= TelegramBotAPIMessageDeserializationStrategyClass()
|
||||
|
||||
@ConsistentCopyVisibility
|
||||
@Serializable
|
||||
data class SendLivePhotoData internal constructor(
|
||||
@SerialName(chatIdField)
|
||||
override val chatId: ChatIdentifier,
|
||||
@SerialName(livePhotoField)
|
||||
val livePhoto: InputFile,
|
||||
@SerialName(photoField)
|
||||
val photo: InputFile,
|
||||
@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(hasSpoilerField)
|
||||
override val spoilered: Boolean = false,
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@SerialName(messageThreadIdField)
|
||||
@EncodeDefault
|
||||
override val threadId: MessageThreadId? = chatId.threadId,
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@EncodeDefault
|
||||
@SerialName(directMessagesTopicIdField)
|
||||
override val directMessageThreadId: DirectMessageThreadId? = chatId.directMessageThreadId,
|
||||
@SerialName(businessConnectionIdField)
|
||||
override val businessConnectionId: BusinessConnectionId? = chatId.businessConnectionId,
|
||||
@SerialName(disableNotificationField)
|
||||
override val disableNotification: Boolean = false,
|
||||
@SerialName(protectContentField)
|
||||
override val protectContent: Boolean = false,
|
||||
@SerialName(allowPaidBroadcastField)
|
||||
override val allowPaidBroadcast: Boolean = false,
|
||||
@SerialName(messageEffectIdField)
|
||||
override val effectId: EffectId? = null,
|
||||
@SerialName(suggestedPostParametersField)
|
||||
override val suggestedPostParameters: SuggestedPostParameters? = null,
|
||||
@SerialName(replyParametersField)
|
||||
override val replyParameters: ReplyParameters? = null,
|
||||
@SerialName(replyMarkupField)
|
||||
override val replyMarkup: KeyboardMarkup? = null
|
||||
) : DataRequest<ContentMessage<LivePhotoContent>>,
|
||||
SendContentMessageRequest<ContentMessage<LivePhotoContent>>,
|
||||
ReplyingMarkupSendMessageRequest<ContentMessage<LivePhotoContent>>,
|
||||
TextableSendMessageRequest<ContentMessage<LivePhotoContent>>,
|
||||
WithCustomizableCaptionRequest<ContentMessage<LivePhotoContent>>,
|
||||
OptionallyWithSpoilerRequest
|
||||
{
|
||||
override val textSources: TextSourcesList? by lazy {
|
||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
||||
}
|
||||
|
||||
init {
|
||||
text ?.let {
|
||||
if (it.length !in captionLength) {
|
||||
throwRangeError("Caption length", captionLength, it.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun method(): String = "sendLivePhoto"
|
||||
override val resultDeserializer: DeserializationStrategy<ContentMessage<LivePhotoContent>>
|
||||
get() = commonResultDeserializer
|
||||
override val requestSerializer: SerializationStrategy<*>
|
||||
get() = serializer()
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
@ConsistentCopyVisibility
|
||||
data class SendLivePhotoFiles internal constructor(
|
||||
val livePhoto: MultipartFile? = null,
|
||||
val photo: MultipartFile? = null
|
||||
) : Files by mapOfNotNull(
|
||||
livePhotoField to livePhoto,
|
||||
photoField to photo
|
||||
)
|
||||
@@ -697,6 +697,7 @@ const val documentField = "document"
|
||||
const val photoField = "photo"
|
||||
const val audioField = "audio"
|
||||
const val videoField = "video"
|
||||
const val livePhotoField = "live_photo"
|
||||
const val animationField = "animation"
|
||||
const val venueField = "venue"
|
||||
const val voiceField = "voice"
|
||||
|
||||
@@ -120,6 +120,7 @@ sealed interface ReplyInfo {
|
||||
private val photo: PhotoFile? = null,
|
||||
private val sticker: Sticker? = null,
|
||||
private val video: VideoFile? = null,
|
||||
private val live_photo: LivePhotoFile? = null,
|
||||
private val voice: VoiceFile? = null,
|
||||
private val video_note: VideoNoteFile? = null,
|
||||
private val contact: Contact? = null,
|
||||
@@ -146,6 +147,7 @@ sealed interface ReplyInfo {
|
||||
story != null -> story
|
||||
audio != null -> audio
|
||||
video != null -> video
|
||||
live_photo != null -> live_photo
|
||||
video_note != null -> video_note
|
||||
animation != null -> animation
|
||||
document != null -> document
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package dev.inmo.tgbotapi.types.files
|
||||
|
||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.media.PollMedia
|
||||
import dev.inmo.tgbotapi.types.media.TelegramMediaLivePhoto
|
||||
import dev.inmo.tgbotapi.types.media.TelegramPaidMediaLivePhoto
|
||||
import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList
|
||||
import dev.inmo.tgbotapi.types.message.ParseMode
|
||||
import dev.inmo.tgbotapi.utils.MimeType
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class LivePhotoFile(
|
||||
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
|
||||
@SerialName(fileIdField)
|
||||
override val fileId: FileId,
|
||||
@SerialName(fileUniqueIdField)
|
||||
override val fileUniqueId: TgFileUniqueId,
|
||||
@SerialName(widthField)
|
||||
override val width: Int,
|
||||
@SerialName(heightField)
|
||||
override val height: Int,
|
||||
@SerialName(durationField)
|
||||
override val duration: Long,
|
||||
@Serializable(PhotoSerializer::class)
|
||||
@SerialName(photoField)
|
||||
val photo: PhotoFile? = null,
|
||||
@SerialName(mimeTypeField)
|
||||
override val mimeType: MimeType? = null,
|
||||
@SerialName(fileSizeField)
|
||||
override val fileSize: FileSize? = null
|
||||
) : TelegramMediaFile,
|
||||
PollMedia,
|
||||
MimedMediaFile,
|
||||
PlayableMediaFile,
|
||||
SizedMediaFile,
|
||||
MediaContentVariant,
|
||||
UsefulAsPaidMediaFile
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun LivePhotoFile.toTelegramMediaLivePhoto(
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
showCaptionAboveMedia: Boolean = false
|
||||
) = TelegramMediaLivePhoto(
|
||||
file = fileId,
|
||||
photo = photo ?.fileId ?: fileId,
|
||||
text = text,
|
||||
parseMode = parseMode,
|
||||
spoilered = spoilered,
|
||||
showCaptionAboveMedia = showCaptionAboveMedia
|
||||
)
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun LivePhotoFile.toTelegramMediaLivePhoto(
|
||||
textSources: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
showCaptionAboveMedia: Boolean = false
|
||||
) = TelegramMediaLivePhoto(
|
||||
file = fileId,
|
||||
photo = photo ?.fileId ?: fileId,
|
||||
entities = textSources,
|
||||
spoilered = spoilered,
|
||||
showCaptionAboveMedia = showCaptionAboveMedia
|
||||
)
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun LivePhotoFile.toTelegramPaidMediaLivePhoto() = TelegramPaidMediaLivePhoto(
|
||||
file = fileId,
|
||||
photo = photo ?.fileId ?: fileId
|
||||
)
|
||||
@@ -29,7 +29,7 @@ object InputPollMediaSerializer : KSerializer<InputPollMedia> {
|
||||
is TelegramMediaAnimation -> TelegramMediaAnimation.serializer().serialize(encoder, value)
|
||||
is TelegramMediaAudio -> TelegramMediaAudio.serializer().serialize(encoder, value)
|
||||
is TelegramMediaDocument -> TelegramMediaDocument.serializer().serialize(encoder, value)
|
||||
// TODO::ADD TelegramMediaLivePhoto
|
||||
is TelegramMediaLivePhoto -> TelegramMediaLivePhoto.serializer().serialize(encoder, value)
|
||||
is TelegramMediaLocation -> TelegramMediaLocation.serializer().serialize(encoder, value)
|
||||
is TelegramMediaPhoto -> TelegramMediaPhoto.serializer().serialize(encoder, value)
|
||||
is TelegramMediaVenue -> TelegramMediaVenue.serializer().serialize(encoder, value)
|
||||
|
||||
@@ -27,7 +27,7 @@ object InputPollOptionMediaSerializer : KSerializer<InputPollOptionMedia> {
|
||||
override fun serialize(encoder: Encoder, value: InputPollOptionMedia) {
|
||||
when (value) {
|
||||
is TelegramMediaAnimation -> TelegramMediaAnimation.serializer().serialize(encoder, value)
|
||||
// TODO::Add TelegramMediaLivePhoto
|
||||
is TelegramMediaLivePhoto -> TelegramMediaLivePhoto.serializer().serialize(encoder, value)
|
||||
is TelegramMediaLocation -> TelegramMediaLocation.serializer().serialize(encoder, value)
|
||||
is TelegramMediaPhoto -> TelegramMediaPhoto.serializer().serialize(encoder, value)
|
||||
is TelegramMediaSticker -> TelegramMediaSticker.serializer().serialize(encoder, value)
|
||||
|
||||
@@ -19,6 +19,7 @@ object MediaGroupMemberTelegramMediaSerializer : KSerializer<MediaGroupMemberTel
|
||||
when (value) {
|
||||
is TelegramMediaPhoto -> TelegramMediaPhoto.serializer().serialize(encoder, value)
|
||||
is TelegramMediaVideo -> TelegramMediaVideo.serializer().serialize(encoder, value)
|
||||
is TelegramMediaLivePhoto -> TelegramMediaLivePhoto.serializer().serialize(encoder, value)
|
||||
is TelegramMediaAudio -> TelegramMediaAudio.serializer().serialize(encoder, value)
|
||||
is TelegramMediaDocument -> TelegramMediaDocument.serializer().serialize(encoder, value)
|
||||
}
|
||||
@@ -30,6 +31,7 @@ object MediaGroupMemberTelegramMediaSerializer : KSerializer<MediaGroupMemberTel
|
||||
return when (json[typeField] ?.jsonPrimitive ?.contentOrNull) {
|
||||
TelegramMediaPhoto.TYPE -> nonstrictJsonFormat.decodeFromJsonElement(TelegramMediaPhoto.serializer(), json)
|
||||
TelegramMediaVideo.TYPE -> nonstrictJsonFormat.decodeFromJsonElement(TelegramMediaVideo.serializer(), json)
|
||||
TelegramMediaLivePhoto.TYPE -> nonstrictJsonFormat.decodeFromJsonElement(TelegramMediaLivePhoto.serializer(), json)
|
||||
TelegramMediaAudio.TYPE -> nonstrictJsonFormat.decodeFromJsonElement(TelegramMediaAudio.serializer(), json)
|
||||
TelegramMediaDocument.TYPE -> nonstrictJsonFormat.decodeFromJsonElement(TelegramMediaDocument.serializer(), json)
|
||||
else -> error("Illegal type of incoming MediaGroupMemberTelegramMedia")
|
||||
|
||||
@@ -6,9 +6,11 @@ import dev.inmo.tgbotapi.types.documentField
|
||||
import dev.inmo.tgbotapi.types.files.AnimationFile
|
||||
import dev.inmo.tgbotapi.types.files.AudioFile
|
||||
import dev.inmo.tgbotapi.types.files.DocumentFile
|
||||
import dev.inmo.tgbotapi.types.files.LivePhotoFile
|
||||
import dev.inmo.tgbotapi.types.files.PhotoFile
|
||||
import dev.inmo.tgbotapi.types.files.Sticker
|
||||
import dev.inmo.tgbotapi.types.files.VideoFile
|
||||
import dev.inmo.tgbotapi.types.livePhotoField
|
||||
import dev.inmo.tgbotapi.types.location.StaticLocation
|
||||
import dev.inmo.tgbotapi.types.locationField
|
||||
import dev.inmo.tgbotapi.types.photoField
|
||||
@@ -34,6 +36,8 @@ interface PollMedia : BaseTelegramMediaFile {
|
||||
val audio: AudioFile? = null,
|
||||
@SerialName(documentField)
|
||||
val document: DocumentFile? = null,
|
||||
@SerialName(livePhotoField)
|
||||
val livePhoto: LivePhotoFile? = null,
|
||||
@SerialName(photoField)
|
||||
val photo: PhotoFile? = null,
|
||||
@SerialName(stickerField)
|
||||
@@ -57,6 +61,7 @@ interface PollMedia : BaseTelegramMediaFile {
|
||||
surrogate.animation != null -> surrogate.animation
|
||||
surrogate.audio != null -> surrogate.audio
|
||||
surrogate.document != null -> surrogate.document
|
||||
surrogate.livePhoto != null -> surrogate.livePhoto
|
||||
surrogate.photo != null -> surrogate.photo
|
||||
surrogate.sticker != null -> surrogate.sticker
|
||||
surrogate.video != null -> surrogate.video
|
||||
@@ -71,6 +76,7 @@ interface PollMedia : BaseTelegramMediaFile {
|
||||
animation = value as? AnimationFile,
|
||||
audio = value as? AudioFile,
|
||||
document = value as? DocumentFile,
|
||||
livePhoto = value as? LivePhotoFile,
|
||||
photo = value as? PhotoFile,
|
||||
sticker = value as? Sticker,
|
||||
video = value as? VideoFile,
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
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.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.*
|
||||
|
||||
fun TelegramMediaLivePhoto(
|
||||
file: InputFile,
|
||||
photo: InputFile,
|
||||
text: String? = null,
|
||||
parseMode: ParseMode? = null,
|
||||
spoilered: Boolean = false,
|
||||
showCaptionAboveMedia: Boolean = false
|
||||
) = TelegramMediaLivePhoto(
|
||||
file = file,
|
||||
photo = photo,
|
||||
text = text,
|
||||
parseMode = parseMode,
|
||||
rawEntities = null,
|
||||
spoilered = spoilered,
|
||||
showCaptionAboveMedia = showCaptionAboveMedia
|
||||
)
|
||||
|
||||
fun TelegramMediaLivePhoto(
|
||||
file: InputFile,
|
||||
photo: InputFile,
|
||||
entities: TextSourcesList,
|
||||
spoilered: Boolean = false,
|
||||
showCaptionAboveMedia: Boolean = false
|
||||
) = TelegramMediaLivePhoto(
|
||||
file = file,
|
||||
photo = photo,
|
||||
text = entities.makeString(),
|
||||
parseMode = null,
|
||||
rawEntities = entities.toRawMessageEntities(),
|
||||
spoilered = spoilered,
|
||||
showCaptionAboveMedia = showCaptionAboveMedia
|
||||
)
|
||||
|
||||
@ConsistentCopyVisibility
|
||||
@Serializable
|
||||
data class TelegramMediaLivePhoto internal constructor(
|
||||
override val file: InputFile,
|
||||
@SerialName(photoField)
|
||||
val photo: InputFile,
|
||||
@SerialName(captionField)
|
||||
override val text: String? = null,
|
||||
@SerialName(parseModeField)
|
||||
override val parseMode: ParseMode? = null,
|
||||
@SerialName(captionEntitiesField)
|
||||
private val rawEntities: List<RawMessageEntity>? = null,
|
||||
@SerialName(hasSpoilerField)
|
||||
override val spoilered: Boolean = false,
|
||||
@SerialName(showCaptionAboveMediaField)
|
||||
override val showCaptionAboveMedia: Boolean = false,
|
||||
) : TelegramFreeMedia,
|
||||
VisualMediaGroupMemberTelegramMedia,
|
||||
InputPollMedia,
|
||||
InputPollOptionMedia {
|
||||
@EncodeDefault
|
||||
override val type: String = TYPE
|
||||
override val textSources: TextSourcesList? by lazy {
|
||||
rawEntities ?.asTextSources(text ?: return@lazy null)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
companion object {
|
||||
const val TYPE = "live_photo"
|
||||
}
|
||||
}
|
||||
@@ -18,10 +18,12 @@ object TelegramMediaSerializer : KSerializer<TelegramMedia> {
|
||||
is TelegramMediaVideo -> TelegramMediaVideo.serializer().serialize(encoder, value)
|
||||
is TelegramMediaAudio -> TelegramMediaAudio.serializer().serialize(encoder, value)
|
||||
is TelegramMediaPhoto -> TelegramMediaPhoto.serializer().serialize(encoder, value)
|
||||
is TelegramMediaLivePhoto -> TelegramMediaLivePhoto.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)
|
||||
is TelegramPaidMediaLivePhoto -> TelegramPaidMediaLivePhoto.serializer().serialize(encoder, value)
|
||||
is TelegramMediaSticker -> TelegramMediaSticker.serializer().serialize(encoder, value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
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.LivePhotoFile
|
||||
import dev.inmo.tgbotapi.types.files.toTelegramPaidMediaLivePhoto
|
||||
import dev.inmo.tgbotapi.types.message.payments.PaidMedia
|
||||
import kotlinx.serialization.*
|
||||
|
||||
@Serializable
|
||||
data class TelegramPaidMediaLivePhoto(
|
||||
override val file: InputFile,
|
||||
@SerialName(photoField)
|
||||
val photo: InputFile,
|
||||
) : VisualTelegramPaidMedia {
|
||||
override val type: String = TYPE
|
||||
|
||||
@SerialName(mediaField)
|
||||
override val media: String
|
||||
init { media = file.fileIdToSend } // crutch until js compiling will be fixed
|
||||
|
||||
companion object {
|
||||
const val TYPE = "live_photo"
|
||||
}
|
||||
}
|
||||
|
||||
fun PaidMedia.LivePhoto.toTelegramPaidMediaLivePhoto(): TelegramPaidMediaLivePhoto = livePhoto.toTelegramPaidMediaLivePhoto()
|
||||
@@ -102,6 +102,7 @@ internal data class RawMessage(
|
||||
private val photo: PhotoFile? = null,
|
||||
private val sticker: Sticker? = null,
|
||||
private val video: VideoFile? = null,
|
||||
private val live_photo: LivePhotoFile? = null,
|
||||
private val voice: VoiceFile? = null,
|
||||
private val video_note: VideoNoteFile? = null,
|
||||
private val contact: Contact? = null,
|
||||
@@ -243,6 +244,14 @@ internal data class RawMessage(
|
||||
quote,
|
||||
show_caption_above_media
|
||||
)
|
||||
live_photo != null -> LivePhotoContent(
|
||||
live_photo,
|
||||
caption,
|
||||
adaptedCaptionEntities,
|
||||
has_media_spoiler ?: false,
|
||||
quote,
|
||||
show_caption_above_media
|
||||
)
|
||||
animation != null -> AnimationContent(
|
||||
animation,
|
||||
document,
|
||||
|
||||
@@ -43,6 +43,7 @@ sealed interface MessageContent: ResendableContent {
|
||||
|
||||
subclass(PhotoContent::class)
|
||||
subclass(VideoContent::class)
|
||||
subclass(LivePhotoContent::class)
|
||||
subclass(AudioContent::class)
|
||||
subclass(DocumentContent::class)
|
||||
|
||||
@@ -65,6 +66,7 @@ sealed interface MessageContent: ResendableContent {
|
||||
subclass(AudioContent::class)
|
||||
subclass(DocumentContent::class)
|
||||
subclass(VideoContent::class)
|
||||
subclass(LivePhotoContent::class)
|
||||
subclass(PhotoContent::class)
|
||||
subclass(AnimationContent::class)
|
||||
}
|
||||
@@ -77,6 +79,7 @@ sealed interface MessageContent: ResendableContent {
|
||||
polymorphic(MediaContent::class) {
|
||||
subclass(VideoNoteContent::class)
|
||||
subclass(VideoContent::class)
|
||||
subclass(LivePhotoContent::class)
|
||||
subclass(StickerContent::class)
|
||||
subclass(PhotoContent::class)
|
||||
subclass(VoiceContent::class)
|
||||
@@ -88,6 +91,7 @@ sealed interface MessageContent: ResendableContent {
|
||||
}
|
||||
polymorphic(SpoilerableMediaContent::class) {
|
||||
subclass(VideoContent::class)
|
||||
subclass(LivePhotoContent::class)
|
||||
subclass(PhotoContent::class)
|
||||
subclass(AnimationContent::class)
|
||||
|
||||
@@ -122,6 +126,7 @@ sealed interface MessageContent: ResendableContent {
|
||||
polymorphic(VisualMediaGroupPartContent::class) {
|
||||
subclass(PhotoContent::class)
|
||||
subclass(VideoContent::class)
|
||||
subclass(LivePhotoContent::class)
|
||||
|
||||
visualMediaGroupContentAdditionalBuilder()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package dev.inmo.tgbotapi.types.message.content
|
||||
|
||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||
import dev.inmo.tgbotapi.requests.send.media.SendLivePhoto
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId
|
||||
import dev.inmo.tgbotapi.types.media.TelegramMediaLivePhoto
|
||||
import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList
|
||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||
import dev.inmo.tgbotapi.types.files.LivePhotoFile
|
||||
import dev.inmo.tgbotapi.types.files.toTelegramMediaLivePhoto
|
||||
import dev.inmo.tgbotapi.types.message.SuggestedPostParameters
|
||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class LivePhotoContent(
|
||||
override val media: LivePhotoFile,
|
||||
override val text: String? = null,
|
||||
override val textSources: TextSourcesList = emptyList(),
|
||||
override val spoilered: Boolean = false,
|
||||
override val quote: TextQuote? = null,
|
||||
override val showCaptionAboveMedia: Boolean = false
|
||||
) : VisualMediaGroupPartContent {
|
||||
override fun createResend(
|
||||
chatId: ChatIdentifier,
|
||||
messageThreadId: MessageThreadId?,
|
||||
directMessageThreadId: DirectMessageThreadId?,
|
||||
businessConnectionId: BusinessConnectionId?,
|
||||
disableNotification: Boolean,
|
||||
protectContent: Boolean,
|
||||
allowPaidBroadcast: Boolean,
|
||||
effectId: EffectId?,
|
||||
suggestedPostParameters: SuggestedPostParameters?,
|
||||
replyParameters: ReplyParameters?,
|
||||
replyMarkup: KeyboardMarkup?
|
||||
): Request<ContentMessage<LivePhotoContent>> = SendLivePhoto(
|
||||
chatId = chatId,
|
||||
livePhoto = media.fileId,
|
||||
photo = media.photo ?.fileId ?: media.fileId,
|
||||
entities = textSources,
|
||||
showCaptionAboveMedia = showCaptionAboveMedia,
|
||||
spoilered = spoilered,
|
||||
threadId = messageThreadId,
|
||||
directMessageThreadId = directMessageThreadId,
|
||||
businessConnectionId = businessConnectionId,
|
||||
disableNotification = disableNotification,
|
||||
protectContent = protectContent,
|
||||
allowPaidBroadcast = allowPaidBroadcast,
|
||||
effectId = effectId,
|
||||
suggestedPostParameters = suggestedPostParameters,
|
||||
replyParameters = replyParameters,
|
||||
replyMarkup = replyMarkup
|
||||
)
|
||||
|
||||
override fun toMediaGroupMemberTelegramMedia(): TelegramMediaLivePhoto = asTelegramMedia()
|
||||
|
||||
override fun asTelegramMedia(): TelegramMediaLivePhoto = media.toTelegramMediaLivePhoto(
|
||||
textSources = textSources,
|
||||
spoilered = spoilered,
|
||||
showCaptionAboveMedia = showCaptionAboveMedia
|
||||
)
|
||||
}
|
||||
@@ -45,6 +45,7 @@ data class PaidMediaInfoContent(
|
||||
is PaidMedia.Preview -> null
|
||||
is PaidMedia.Unknown -> null
|
||||
is PaidMedia.Video -> it.video.toTelegramPaidMediaVideo()
|
||||
is PaidMedia.LivePhoto -> it.livePhoto.toTelegramPaidMediaLivePhoto()
|
||||
}
|
||||
}.ifEmpty {
|
||||
error("Unable to create resend for paid media content without any revealed content")
|
||||
|
||||
@@ -30,6 +30,7 @@ typealias DocumentMediaGroupMessage = CommonMessage<DocumentMediaGroupPartConten
|
||||
typealias DocumentMessage = CommonMessage<DocumentContent>
|
||||
typealias VisualMediaGroupMessage = CommonMessage<VisualMediaGroupPartContent>
|
||||
typealias VideoMessage = CommonMessage<VideoContent>
|
||||
typealias LivePhotoMessage = CommonMessage<LivePhotoContent>
|
||||
typealias PhotoMessage = CommonMessage<PhotoContent>
|
||||
typealias AnimationMessage = CommonMessage<AnimationContent>
|
||||
typealias ScheduledGiveawayContentMessage = CommonMessage<GiveawayContent>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package dev.inmo.tgbotapi.types.message.payments
|
||||
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.types.files.LivePhotoFile
|
||||
import dev.inmo.tgbotapi.types.files.PhotoFile
|
||||
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||
import dev.inmo.tgbotapi.types.files.VideoFile
|
||||
@@ -68,6 +69,20 @@ sealed interface PaidMedia {
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class LivePhoto(
|
||||
@SerialName(livePhotoField)
|
||||
val livePhoto: LivePhotoFile
|
||||
) : PaidMedia {
|
||||
@EncodeDefault
|
||||
@SerialName(typeField)
|
||||
override val type: String = Companion.type
|
||||
|
||||
companion object {
|
||||
val type: String = "live_photo"
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable(Companion::class)
|
||||
data class Unknown(
|
||||
@SerialName(typeField)
|
||||
@@ -89,7 +104,9 @@ sealed interface PaidMedia {
|
||||
@SerialName(photoField)
|
||||
val photo: PhotoFile? = null,
|
||||
@SerialName(videoField)
|
||||
val video: VideoFile? = null
|
||||
val video: VideoFile? = null,
|
||||
@SerialName(livePhotoField)
|
||||
val livePhoto: LivePhotoFile? = null
|
||||
)
|
||||
|
||||
override val descriptor: SerialDescriptor
|
||||
@@ -112,6 +129,9 @@ sealed interface PaidMedia {
|
||||
Video.type -> Video(
|
||||
data.video ?: return unknown
|
||||
)
|
||||
LivePhoto.type -> LivePhoto(
|
||||
data.livePhoto ?: return unknown
|
||||
)
|
||||
else -> unknown
|
||||
}
|
||||
}
|
||||
@@ -127,6 +147,7 @@ sealed interface PaidMedia {
|
||||
(value as? Preview) ?.duration,
|
||||
(value as? Photo) ?.photo,
|
||||
(value as? Video) ?.video,
|
||||
(value as? LivePhoto) ?.livePhoto,
|
||||
)
|
||||
Surrogate.serializer().serialize(encoder, surrogate)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import dev.inmo.tgbotapi.types.media.*
|
||||
fun PaidMedia.toTelegramPaidMediaOrNull(): TelegramPaidMedia? = when (this) {
|
||||
is PaidMedia.Photo -> toTelegramMediaPhoto()
|
||||
is PaidMedia.Video -> toTelegramPaidMediaVideo()
|
||||
is PaidMedia.LivePhoto -> toTelegramPaidMediaLivePhoto()
|
||||
is PaidMedia.Preview, is PaidMedia.Unknown -> null
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user