mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-11-26 03:58:44 +00:00
commit
f377d61bf0
56
CHANGELOG.md
56
CHANGELOG.md
@ -1,5 +1,61 @@
|
|||||||
# TelegramBotAPI changelog
|
# TelegramBotAPI changelog
|
||||||
|
|
||||||
|
## 0.29.3
|
||||||
|
|
||||||
|
* `Common`:
|
||||||
|
* Version updates:
|
||||||
|
* `Serialization`: `1.0.0` -> `1.0.1`
|
||||||
|
* `Core`:
|
||||||
|
* New annotation `RiskFeature`. This annotation will be applied to the things which contains unsafe types usage
|
||||||
|
* `SendMediaGroup` factory now marked with `RiskFeature`
|
||||||
|
* Media groups updates:
|
||||||
|
* New functions `SendPlaylist`
|
||||||
|
* New functions `SendDocumentsGroup`
|
||||||
|
* New functions `SendVisualMediaGroup`
|
||||||
|
* New type `VisualMediaGroupMemberInputMedia : MediaGroupMemberInputMedia`
|
||||||
|
* `InputMediaPhoto` now implements `VisualMediaGroupMemberInputMedia` instead of `MediaGroupMemberInputMedia`
|
||||||
|
* `InputMediaVideo` now implements `VisualMediaGroupMemberInputMedia` instead of `MediaGroupMemberInputMedia`
|
||||||
|
* New type `VisualMediaGroupContent : MediaGroupContent`
|
||||||
|
* `PhotoContent` now implements `VisualMediaGroupContent` instead of `MediaGroupContent`
|
||||||
|
* `VideoContent` now implements `VisualMediaGroupContent` instead of `MediaGroupContent`
|
||||||
|
* New type `AudioMediaGroupContent : MediaGroupContent`
|
||||||
|
* `AudioContent` now implements `AudioMediaGroupContent` instead of `MediaContent` and `CaptionedInput`
|
||||||
|
* New type `DocumentMediaGroupContent : MediaGroupContent`
|
||||||
|
* `DocumentContent` now implements `DocumentMediaGroupContent` instead of `MediaContent` and `CaptionedInput`
|
||||||
|
* New type `AudioMediaGroupMemberInputMedia : MediaGroupMemberInputMedia`
|
||||||
|
* `InputMediaAudio` now implements `AudioMediaGroupMemberInputMedia`
|
||||||
|
* New type `DocumentMediaGroupMemberInputMedia : MediaGroupMemberInputMedia`
|
||||||
|
* `InputMediaDocument` now implements `DocumentMediaGroupMemberInputMedia`
|
||||||
|
* New extension `AudioFile#toInputMediaAudio`
|
||||||
|
* `AudioContent` now implements `MediaGroupContent`
|
||||||
|
* New extension `DocumentFile#toInputMediaDocument`
|
||||||
|
* `DocumentContent` now implements `MediaGroupContent`
|
||||||
|
* New dice type `SlotMachineDiceAnimationType`
|
||||||
|
* New extension `TelegramMediaFile#asDocumentFile`
|
||||||
|
* New extension `VideoFile#toInputMediaVideo`
|
||||||
|
* New exception `WrongFileIdentifierException`
|
||||||
|
* Extension `String#toInputMediaFileAttachmentName` now is deprecated
|
||||||
|
* Property `ThumbedInputMedia#thumbMedia` now is deprecated
|
||||||
|
* `API`:
|
||||||
|
* New extensions for media groups:
|
||||||
|
* `TelegramBot#sendPlaylist`
|
||||||
|
* `TelegramBot#replyWithPlaylist`
|
||||||
|
* `TelegramBot#sendDocumentsGroup`
|
||||||
|
* `TelegramBot#replyWithDocumentsGroup`
|
||||||
|
* `TelegramBot#sendVisualMediaGroup`
|
||||||
|
* `TelegramBot#replyWithVisualMediaGroup`
|
||||||
|
* `Utils`:
|
||||||
|
* New extensions for `Flow`s:
|
||||||
|
* `Flow<SentMediaGroupUpdate>#mediaGroupVisualMessages`
|
||||||
|
* `Flow<SentMediaGroupUpdate>#mediaGroupAudioMessages`
|
||||||
|
* `Flow<SentMediaGroupUpdate>#mediaGroupDocumentMessages`
|
||||||
|
* New extensions for `FlowsUpdatesFilter`:
|
||||||
|
* `FlowsUpdatesFilter#audioMessagesWithMediaGroups`
|
||||||
|
* `FlowsUpdatesFilter#mediaGroupAudioMessages`
|
||||||
|
* `FlowsUpdatesFilter#documentMessagesWithMediaGroups`
|
||||||
|
* `FlowsUpdatesFilter#mediaGroupDocumentMessages`
|
||||||
|
* `FlowsUpdatesFilter#mediaGroupVisualMessages`
|
||||||
|
|
||||||
## 0.29.2
|
## 0.29.2
|
||||||
|
|
||||||
* `Common`:
|
* `Common`:
|
||||||
|
@ -7,7 +7,7 @@ kotlin.incremental.js=true
|
|||||||
|
|
||||||
kotlin_version=1.4.10
|
kotlin_version=1.4.10
|
||||||
kotlin_coroutines_version=1.4.0
|
kotlin_coroutines_version=1.4.0
|
||||||
kotlin_serialisation_runtime_version=1.0.0
|
kotlin_serialisation_runtime_version=1.0.1
|
||||||
klock_version=1.12.1
|
klock_version=1.12.1
|
||||||
uuid_version=0.2.2
|
uuid_version=0.2.2
|
||||||
ktor_version=1.4.1
|
ktor_version=1.4.1
|
||||||
@ -15,7 +15,7 @@ ktor_version=1.4.1
|
|||||||
javax_activation_version=1.1.1
|
javax_activation_version=1.1.1
|
||||||
|
|
||||||
library_group=dev.inmo
|
library_group=dev.inmo
|
||||||
library_version=0.29.2
|
library_version=0.29.3
|
||||||
|
|
||||||
gradle_bintray_plugin_version=1.8.5
|
gradle_bintray_plugin_version=1.8.5
|
||||||
github_release_plugin_version=2.2.12
|
github_release_plugin_version=2.2.12
|
||||||
|
@ -15,6 +15,7 @@ fun newRequestException(
|
|||||||
description.contains("Bad Request: message is not modified") -> MessageIsNotModifiedException(response, plainAnswer, message, cause)
|
description.contains("Bad Request: message is not modified") -> MessageIsNotModifiedException(response, plainAnswer, message, cause)
|
||||||
description == "Unauthorized" -> UnauthorizedException(response, plainAnswer, message, cause)
|
description == "Unauthorized" -> UnauthorizedException(response, plainAnswer, message, cause)
|
||||||
description.contains("PHOTO_INVALID_DIMENSIONS") -> InvalidPhotoDimensionsException(response, plainAnswer, message, cause)
|
description.contains("PHOTO_INVALID_DIMENSIONS") -> InvalidPhotoDimensionsException(response, plainAnswer, message, cause)
|
||||||
|
description.contains("wrong file identifier") -> WrongFileIdentifierException(response, plainAnswer, message, cause)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
} ?: CommonRequestException(response, plainAnswer, message, cause)
|
} ?: CommonRequestException(response, plainAnswer, message, cause)
|
||||||
@ -45,3 +46,6 @@ class MessageToEditNotFoundException(response: Response, plainAnswer: String, me
|
|||||||
|
|
||||||
class InvalidPhotoDimensionsException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
|
class InvalidPhotoDimensionsException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
|
||||||
RequestException(response, plainAnswer, message, cause)
|
RequestException(response, plainAnswer, message, cause)
|
||||||
|
|
||||||
|
class WrongFileIdentifierException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
|
||||||
|
RequestException(response, plainAnswer, message, cause)
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package dev.inmo.tgbotapi.requests.abstracts
|
package dev.inmo.tgbotapi.requests.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.toInputMediaFileAttachmentName
|
|
||||||
import dev.inmo.tgbotapi.utils.StorageFile
|
import dev.inmo.tgbotapi.utils.StorageFile
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.descriptors.*
|
import kotlinx.serialization.descriptors.*
|
||||||
@ -12,6 +11,14 @@ sealed class InputFile {
|
|||||||
abstract val fileId: String
|
abstract val fileId: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal inline val InputFile.attachFileId
|
||||||
|
get() = "attach://$fileId"
|
||||||
|
internal inline val InputFile.fileIdToSend
|
||||||
|
get() = when (this) {
|
||||||
|
is FileId -> fileId
|
||||||
|
is MultipartFile -> attachFileId
|
||||||
|
}
|
||||||
|
|
||||||
// TODO:: add checks for file url/file id regex
|
// TODO:: add checks for file url/file id regex
|
||||||
/**
|
/**
|
||||||
* Contains file id or file url
|
* Contains file id or file url
|
||||||
@ -30,12 +37,6 @@ internal object InputFileSerializer : KSerializer<InputFile> {
|
|||||||
override fun deserialize(decoder: Decoder): FileId = FileId(decoder.decodeString())
|
override fun deserialize(decoder: Decoder): FileId = FileId(decoder.decodeString())
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val InputFile.asMediaData: String
|
|
||||||
get() = when (this) {
|
|
||||||
is FileId -> fileId
|
|
||||||
is MultipartFile -> fileId.toInputMediaFileAttachmentName()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO:: add checks for files size
|
// TODO:: add checks for files size
|
||||||
/**
|
/**
|
||||||
* Contains info about file for sending
|
* Contains info about file for sending
|
||||||
|
@ -8,12 +8,16 @@ import dev.inmo.tgbotapi.types.*
|
|||||||
import dev.inmo.tgbotapi.types.InputMedia.*
|
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializerClass
|
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializerClass
|
||||||
|
import dev.inmo.tgbotapi.utils.*
|
||||||
import dev.inmo.tgbotapi.utils.throwRangeError
|
import dev.inmo.tgbotapi.utils.throwRangeError
|
||||||
import dev.inmo.tgbotapi.utils.toJsonWithoutNulls
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.builtins.ListSerializer
|
import kotlinx.serialization.builtins.ListSerializer
|
||||||
import kotlinx.serialization.json.buildJsonArray
|
import kotlinx.serialization.json.buildJsonArray
|
||||||
|
|
||||||
|
const val rawSendingMediaGroupsWarning = "Media groups contains restrictions related to combinations of media" +
|
||||||
|
" types. Currently it is possible to combine photo + video OR audio OR documents"
|
||||||
|
|
||||||
|
@RiskFeature(rawSendingMediaGroupsWarning)
|
||||||
fun SendMediaGroup(
|
fun SendMediaGroup(
|
||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
media: List<MediaGroupMemberInputMedia>,
|
media: List<MediaGroupMemberInputMedia>,
|
||||||
@ -52,6 +56,46 @@ fun SendMediaGroup(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this method to be sure that you are correctly sending playlist with audios
|
||||||
|
*
|
||||||
|
* @see InputMediaAudio
|
||||||
|
*/
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun SendPlaylist(
|
||||||
|
chatId: ChatIdentifier,
|
||||||
|
media: List<AudioMediaGroupMemberInputMedia>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null
|
||||||
|
) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this method to be sure that you are correctly sending documents media group
|
||||||
|
*
|
||||||
|
* @see InputMediaDocument
|
||||||
|
*/
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun SendDocumentsGroup(
|
||||||
|
chatId: ChatIdentifier,
|
||||||
|
media: List<DocumentMediaGroupMemberInputMedia>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null
|
||||||
|
) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this method to be sure that you are correctly sending visual media group
|
||||||
|
*
|
||||||
|
* @see InputMediaPhoto
|
||||||
|
* @see InputMediaVideo
|
||||||
|
*/
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun SendVisualMediaGroup(
|
||||||
|
chatId: ChatIdentifier,
|
||||||
|
media: List<VisualMediaGroupMemberInputMedia>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null
|
||||||
|
) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId)
|
||||||
|
|
||||||
private val messagesListSerializer: KSerializer<List<MediaGroupMessage>>
|
private val messagesListSerializer: KSerializer<List<MediaGroupMessage>>
|
||||||
= ListSerializer(TelegramBotAPIMessageDeserializeOnlySerializerClass())
|
= ListSerializer(TelegramBotAPIMessageDeserializeOnlySerializerClass())
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.types.InputMedia
|
|||||||
import dev.inmo.tgbotapi.requests.abstracts.InputFile
|
import dev.inmo.tgbotapi.requests.abstracts.InputFile
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Deprecated("Will be removed due to redundancy for end-side users")
|
||||||
fun String.toInputMediaFileAttachmentName() = "attach://$this"
|
fun String.toInputMediaFileAttachmentName() = "attach://$this"
|
||||||
|
|
||||||
@Serializable(InputMediaSerializer::class)
|
@Serializable(InputMediaSerializer::class)
|
||||||
|
@ -23,5 +23,5 @@ data class InputMediaAnimation(
|
|||||||
|
|
||||||
@SerialName(mediaField)
|
@SerialName(mediaField)
|
||||||
override val media: String
|
override val media: String
|
||||||
init { media = file.fileId } // crutch until js compiling will be fixed
|
init { media = file.fileIdToSend } // crutch until js compiling will be fixed
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,13 @@ import dev.inmo.tgbotapi.CommonAbstracts.Performerable
|
|||||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
|
import dev.inmo.tgbotapi.types.files.AudioFile
|
||||||
|
import dev.inmo.tgbotapi.types.files.PhotoSize
|
||||||
import dev.inmo.tgbotapi.types.mediaField
|
import dev.inmo.tgbotapi.types.mediaField
|
||||||
import kotlinx.serialization.SerialName
|
import dev.inmo.tgbotapi.types.message.content.media.AudioContent
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
|
internal const val audioInputMediaType = "audio"
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class InputMediaAudio(
|
data class InputMediaAudio(
|
||||||
@ -19,10 +23,26 @@ data class InputMediaAudio(
|
|||||||
override val performer: String? = null,
|
override val performer: String? = null,
|
||||||
override val title: String? = null,
|
override val title: String? = null,
|
||||||
override val thumb: InputFile? = null
|
override val thumb: InputFile? = null
|
||||||
) : InputMedia, DuratedInputMedia, ThumbedInputMedia, TitledInputMedia, CaptionedOutput, Performerable {
|
) : InputMedia, AudioMediaGroupMemberInputMedia, DuratedInputMedia, ThumbedInputMedia, TitledInputMedia, CaptionedOutput, Performerable {
|
||||||
override val type: String = "audio"
|
override val type: String = audioInputMediaType
|
||||||
|
|
||||||
|
override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this)
|
||||||
|
|
||||||
@SerialName(mediaField)
|
@SerialName(mediaField)
|
||||||
override val media: String
|
override val media: String
|
||||||
init { media = file.fileId } // crutch until js compiling will be fixed
|
init { media = file.fileIdToSend } // crutch until js compiling will be fixed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun AudioFile.toInputMediaAudio(
|
||||||
|
caption: String? = null,
|
||||||
|
parseMode: ParseMode? = null,
|
||||||
|
title: String? = this.title
|
||||||
|
): InputMediaAudio = InputMediaAudio(
|
||||||
|
fileId,
|
||||||
|
caption,
|
||||||
|
parseMode,
|
||||||
|
duration,
|
||||||
|
performer,
|
||||||
|
title,
|
||||||
|
thumb ?.fileId
|
||||||
|
)
|
||||||
|
@ -4,9 +4,11 @@ import dev.inmo.tgbotapi.CommonAbstracts.CaptionedOutput
|
|||||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
import dev.inmo.tgbotapi.types.ParseMode.parseModeField
|
||||||
|
import dev.inmo.tgbotapi.types.files.DocumentFile
|
||||||
import dev.inmo.tgbotapi.types.mediaField
|
import dev.inmo.tgbotapi.types.mediaField
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
|
internal const val documentInputMediaType = "document"
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class InputMediaDocument(
|
data class InputMediaDocument(
|
||||||
@ -15,10 +17,22 @@ data class InputMediaDocument(
|
|||||||
@SerialName(parseModeField)
|
@SerialName(parseModeField)
|
||||||
override val parseMode: ParseMode? = null,
|
override val parseMode: ParseMode? = null,
|
||||||
override val thumb: InputFile? = null
|
override val thumb: InputFile? = null
|
||||||
) : InputMedia, ThumbedInputMedia, CaptionedOutput {
|
) : InputMedia, DocumentMediaGroupMemberInputMedia, ThumbedInputMedia, CaptionedOutput {
|
||||||
override val type: String = "document"
|
override val type: String = documentInputMediaType
|
||||||
|
|
||||||
|
override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this)
|
||||||
|
|
||||||
@SerialName(mediaField)
|
@SerialName(mediaField)
|
||||||
override val media: String
|
override val media: String
|
||||||
init { media = file.fileId } // crutch until js compiling will be fixed
|
init { media = file.fileIdToSend } // crutch until js compiling will be fixed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun DocumentFile.toInputMediaDocument(
|
||||||
|
caption: String? = null,
|
||||||
|
parseMode: ParseMode? = null
|
||||||
|
) = InputMediaDocument(
|
||||||
|
fileId,
|
||||||
|
caption,
|
||||||
|
parseMode,
|
||||||
|
thumb ?.fileId
|
||||||
|
)
|
||||||
|
@ -17,14 +17,14 @@ data class InputMediaPhoto(
|
|||||||
override val caption: String? = null,
|
override val caption: String? = null,
|
||||||
@SerialName(parseModeField)
|
@SerialName(parseModeField)
|
||||||
override val parseMode: ParseMode? = null
|
override val parseMode: ParseMode? = null
|
||||||
) : InputMedia, MediaGroupMemberInputMedia {
|
) : InputMedia, VisualMediaGroupMemberInputMedia {
|
||||||
override val type: String = photoInputMediaType
|
override val type: String = photoInputMediaType
|
||||||
|
|
||||||
override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this)
|
override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this)
|
||||||
|
|
||||||
@SerialName(mediaField)
|
@SerialName(mediaField)
|
||||||
override val media: String
|
override val media: String
|
||||||
init { media = file.fileId } // crutch until js compiling will be fixed
|
init { media = file.fileIdToSend } // crutch until js compiling will be fixed
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PhotoSize.toInputMediaPhoto(
|
fun PhotoSize.toInputMediaPhoto(
|
||||||
|
@ -19,12 +19,12 @@ data class InputMediaVideo(
|
|||||||
override val height: Int? = null,
|
override val height: Int? = null,
|
||||||
override val duration: Long? = null,
|
override val duration: Long? = null,
|
||||||
override val thumb: InputFile? = null
|
override val thumb: InputFile? = null
|
||||||
) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, MediaGroupMemberInputMedia {
|
) : InputMedia, SizedInputMedia, DuratedInputMedia, ThumbedInputMedia, VisualMediaGroupMemberInputMedia {
|
||||||
override val type: String = videoInputMediaType
|
override val type: String = videoInputMediaType
|
||||||
|
|
||||||
override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this)
|
override fun serialize(format: StringFormat): String = format.encodeToString(serializer(), this)
|
||||||
|
|
||||||
@SerialName(mediaField)
|
@SerialName(mediaField)
|
||||||
override val media: String
|
override val media: String
|
||||||
init { media = file.fileId } // crutch until js compiling will be fixed
|
init { media = file.fileIdToSend } // crutch until js compiling will be fixed
|
||||||
}
|
}
|
||||||
|
@ -18,3 +18,9 @@ internal fun <T> T.buildArguments(withSerializer: SerializationStrategy<T>) = ar
|
|||||||
interface MediaGroupMemberInputMedia : InputMedia, CaptionedOutput {
|
interface MediaGroupMemberInputMedia : InputMedia, CaptionedOutput {
|
||||||
fun serialize(format: StringFormat): String
|
fun serialize(format: StringFormat): String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface AudioMediaGroupMemberInputMedia: MediaGroupMemberInputMedia
|
||||||
|
interface DocumentMediaGroupMemberInputMedia: MediaGroupMemberInputMedia
|
||||||
|
|
||||||
|
@Serializable(MediaGroupMemberInputMediaSerializer::class)
|
||||||
|
interface VisualMediaGroupMemberInputMedia : MediaGroupMemberInputMedia
|
||||||
|
@ -16,6 +16,8 @@ internal object MediaGroupMemberInputMediaSerializer : KSerializer<MediaGroupMem
|
|||||||
when (value) {
|
when (value) {
|
||||||
is InputMediaPhoto -> InputMediaPhoto.serializer().serialize(encoder, value)
|
is InputMediaPhoto -> InputMediaPhoto.serializer().serialize(encoder, value)
|
||||||
is InputMediaVideo -> InputMediaVideo.serializer().serialize(encoder, value)
|
is InputMediaVideo -> InputMediaVideo.serializer().serialize(encoder, value)
|
||||||
|
is InputMediaAudio -> InputMediaAudio.serializer().serialize(encoder, value)
|
||||||
|
is InputMediaDocument -> InputMediaDocument.serializer().serialize(encoder, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +27,8 @@ internal object MediaGroupMemberInputMediaSerializer : KSerializer<MediaGroupMem
|
|||||||
return when (json[typeField] ?.jsonPrimitive ?.contentOrNull) {
|
return when (json[typeField] ?.jsonPrimitive ?.contentOrNull) {
|
||||||
photoInputMediaType -> nonstrictJsonFormat.decodeFromJsonElement(InputMediaPhoto.serializer(), json)
|
photoInputMediaType -> nonstrictJsonFormat.decodeFromJsonElement(InputMediaPhoto.serializer(), json)
|
||||||
videoInputMediaType -> nonstrictJsonFormat.decodeFromJsonElement(InputMediaVideo.serializer(), json)
|
videoInputMediaType -> nonstrictJsonFormat.decodeFromJsonElement(InputMediaVideo.serializer(), json)
|
||||||
|
audioInputMediaType -> nonstrictJsonFormat.decodeFromJsonElement(InputMediaAudio.serializer(), json)
|
||||||
|
documentInputMediaType -> nonstrictJsonFormat.decodeFromJsonElement(InputMediaDocument.serializer(), json)
|
||||||
else -> error("Illegal type of incoming MediaGroupMemberInputMedia")
|
else -> error("Illegal type of incoming MediaGroupMemberInputMedia")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ interface ThumbedInputMedia : InputMedia {
|
|||||||
val thumb: InputFile?
|
val thumb: InputFile?
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName(thumbField)
|
@SerialName(thumbField)
|
||||||
|
@Deprecated("Will be removed due to useless state")
|
||||||
val thumbMedia: String?
|
val thumbMedia: String?
|
||||||
get() = thumb ?.let {
|
get() = thumb ?.let {
|
||||||
when (it) {
|
when (it) {
|
||||||
|
@ -22,6 +22,10 @@ object BasketballDiceAnimationType : DiceAnimationType() {
|
|||||||
override val emoji: String = "\uD83C\uDFC0"
|
override val emoji: String = "\uD83C\uDFC0"
|
||||||
}
|
}
|
||||||
@Serializable(DiceAnimationTypeSerializer::class)
|
@Serializable(DiceAnimationTypeSerializer::class)
|
||||||
|
object SlotMachineDiceAnimationType : DiceAnimationType() {
|
||||||
|
override val emoji: String = "\uD83C\uDFB0"
|
||||||
|
}
|
||||||
|
@Serializable(DiceAnimationTypeSerializer::class)
|
||||||
data class CustomDiceAnimationType(
|
data class CustomDiceAnimationType(
|
||||||
override val emoji: String
|
override val emoji: String
|
||||||
) : DiceAnimationType()
|
) : DiceAnimationType()
|
||||||
@ -34,6 +38,7 @@ internal object DiceAnimationTypeSerializer : KSerializer<DiceAnimationType> {
|
|||||||
CubeDiceAnimationType.emoji -> CubeDiceAnimationType
|
CubeDiceAnimationType.emoji -> CubeDiceAnimationType
|
||||||
DartsDiceAnimationType.emoji -> DartsDiceAnimationType
|
DartsDiceAnimationType.emoji -> DartsDiceAnimationType
|
||||||
BasketballDiceAnimationType.emoji -> BasketballDiceAnimationType
|
BasketballDiceAnimationType.emoji -> BasketballDiceAnimationType
|
||||||
|
SlotMachineDiceAnimationType.emoji -> SlotMachineDiceAnimationType
|
||||||
else -> CustomDiceAnimationType(type)
|
else -> CustomDiceAnimationType(type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,3 +22,13 @@ data class DocumentFile(
|
|||||||
@SerialName(fileNameField)
|
@SerialName(fileNameField)
|
||||||
override val fileName: String? = null
|
override val fileName: String? = null
|
||||||
) : TelegramMediaFile, MimedMediaFile, ThumbedMediaFile, CustomNamedMediaFile
|
) : TelegramMediaFile, MimedMediaFile, ThumbedMediaFile, CustomNamedMediaFile
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun TelegramMediaFile.asDocumentFile() = DocumentFile(
|
||||||
|
fileId,
|
||||||
|
fileUniqueId,
|
||||||
|
fileSize,
|
||||||
|
(this as? ThumbedMediaFile) ?.thumb,
|
||||||
|
(this as? MimedMediaFile) ?.mimeType,
|
||||||
|
(this as? CustomNamedMediaFile) ?.fileName
|
||||||
|
)
|
||||||
|
@ -2,9 +2,13 @@ package dev.inmo.tgbotapi.types.files
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.FileUniqueId
|
import dev.inmo.tgbotapi.types.FileUniqueId
|
||||||
|
import dev.inmo.tgbotapi.types.InputMedia.InputMediaVideo
|
||||||
|
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
|
||||||
|
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
|
||||||
import dev.inmo.tgbotapi.types.fileUniqueIdField
|
import dev.inmo.tgbotapi.types.fileUniqueIdField
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
import dev.inmo.tgbotapi.types.files.abstracts.*
|
||||||
import dev.inmo.tgbotapi.utils.MimeType
|
import dev.inmo.tgbotapi.utils.MimeType
|
||||||
|
import dev.inmo.tgbotapi.utils.toHtmlCaptions
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@ -23,3 +27,17 @@ data class VideoFile(
|
|||||||
@SerialName(fileSizeField)
|
@SerialName(fileSizeField)
|
||||||
override val fileSize: Long? = null
|
override val fileSize: Long? = null
|
||||||
) : TelegramMediaFile, MimedMediaFile, ThumbedMediaFile, PlayableMediaFile, SizedMediaFile
|
) : TelegramMediaFile, MimedMediaFile, ThumbedMediaFile, PlayableMediaFile, SizedMediaFile
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun VideoFile.toInputMediaVideo(
|
||||||
|
caption: String? = null,
|
||||||
|
parseMode: ParseMode? = null
|
||||||
|
) = InputMediaVideo(
|
||||||
|
fileId,
|
||||||
|
caption,
|
||||||
|
parseMode,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
duration,
|
||||||
|
thumb ?.fileId
|
||||||
|
)
|
||||||
|
@ -220,17 +220,20 @@ internal data class RawMessage(
|
|||||||
}
|
}
|
||||||
} ?: content?.let { content ->
|
} ?: content?.let { content ->
|
||||||
media_group_id?.let {
|
media_group_id?.let {
|
||||||
|
val checkedContent = when (content) {
|
||||||
|
is PhotoContent -> content
|
||||||
|
is VideoContent -> content
|
||||||
|
is AudioContent -> content
|
||||||
|
is DocumentContent -> content
|
||||||
|
else -> error("Unsupported content for media group")
|
||||||
|
}
|
||||||
when (from) {
|
when (from) {
|
||||||
null -> ChannelMediaGroupMessage(
|
null -> ChannelMediaGroupMessage(
|
||||||
messageId,
|
messageId,
|
||||||
chat,
|
chat,
|
||||||
date.asDate,
|
date.asDate,
|
||||||
it,
|
it,
|
||||||
when (content) {
|
checkedContent,
|
||||||
is PhotoContent -> content
|
|
||||||
is VideoContent -> content
|
|
||||||
else -> error("Unsupported content for media group")
|
|
||||||
},
|
|
||||||
edit_date?.asDate,
|
edit_date?.asDate,
|
||||||
forwarded,
|
forwarded,
|
||||||
reply_to_message?.asMessage,
|
reply_to_message?.asMessage,
|
||||||
@ -242,11 +245,7 @@ internal data class RawMessage(
|
|||||||
chat,
|
chat,
|
||||||
date.asDate,
|
date.asDate,
|
||||||
it,
|
it,
|
||||||
when (content) {
|
checkedContent,
|
||||||
is PhotoContent -> content
|
|
||||||
is VideoContent -> content
|
|
||||||
else -> error("Unsupported content for media group")
|
|
||||||
},
|
|
||||||
edit_date?.asDate,
|
edit_date?.asDate,
|
||||||
forwarded,
|
forwarded,
|
||||||
reply_to_message?.asMessage,
|
reply_to_message?.asMessage,
|
||||||
|
@ -5,4 +5,8 @@ import dev.inmo.tgbotapi.types.InputMedia.MediaGroupMemberInputMedia
|
|||||||
|
|
||||||
interface MediaGroupContent : MediaContent, CaptionedInput {
|
interface MediaGroupContent : MediaContent, CaptionedInput {
|
||||||
fun toMediaGroupMemberInputMedia(): MediaGroupMemberInputMedia
|
fun toMediaGroupMemberInputMedia(): MediaGroupMemberInputMedia
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface VisualMediaGroupContent : MediaGroupContent
|
||||||
|
interface AudioMediaGroupContent : MediaGroupContent
|
||||||
|
interface DocumentMediaGroupContent : MediaGroupContent
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
package dev.inmo.tgbotapi.types.message.content.media
|
package dev.inmo.tgbotapi.types.message.content.media
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedInput
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.requests.send.media.SendAudio
|
import dev.inmo.tgbotapi.requests.send.media.SendAudio
|
||||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.InputMediaAudio
|
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
|
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.files.AudioFile
|
import dev.inmo.tgbotapi.types.files.AudioFile
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||||
import dev.inmo.tgbotapi.utils.toHtmlCaptions
|
import dev.inmo.tgbotapi.utils.toHtmlCaptions
|
||||||
import dev.inmo.tgbotapi.utils.toMarkdownV2Captions
|
import dev.inmo.tgbotapi.utils.toMarkdownV2Captions
|
||||||
|
|
||||||
@ -20,7 +19,7 @@ data class AudioContent(
|
|||||||
override val media: AudioFile,
|
override val media: AudioFile,
|
||||||
override val caption: String? = null,
|
override val caption: String? = null,
|
||||||
override val captionEntities: List<TextPart> = emptyList()
|
override val captionEntities: List<TextPart> = emptyList()
|
||||||
) : MediaContent, CaptionedInput {
|
) : AudioMediaGroupContent {
|
||||||
override fun createResend(
|
override fun createResend(
|
||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
disableNotification: Boolean,
|
disableNotification: Boolean,
|
||||||
@ -40,13 +39,10 @@ data class AudioContent(
|
|||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun asInputMedia(): InputMediaAudio = InputMediaAudio(
|
override fun toMediaGroupMemberInputMedia(): InputMediaAudio = asInputMedia()
|
||||||
media.fileId,
|
|
||||||
toMarkdownV2Captions().firstOrNull(),
|
override fun asInputMedia(): InputMediaAudio = media.toInputMediaAudio(
|
||||||
MarkdownV2,
|
toHtmlCaptions().firstOrNull(),
|
||||||
media.duration,
|
HTMLParseMode
|
||||||
media.performer,
|
|
||||||
media.title,
|
|
||||||
media.thumb ?.fileId
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,14 +5,15 @@ import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
|||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.requests.send.media.SendDocument
|
import dev.inmo.tgbotapi.requests.send.media.SendDocument
|
||||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.InputMediaDocument
|
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
|
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.files.DocumentFile
|
import dev.inmo.tgbotapi.types.files.DocumentFile
|
||||||
|
import dev.inmo.tgbotapi.types.files.asDocumentFile
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||||
import dev.inmo.tgbotapi.utils.toHtmlCaptions
|
import dev.inmo.tgbotapi.utils.toHtmlCaptions
|
||||||
import dev.inmo.tgbotapi.utils.toMarkdownV2Captions
|
import dev.inmo.tgbotapi.utils.toMarkdownV2Captions
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ data class DocumentContent(
|
|||||||
override val media: DocumentFile,
|
override val media: DocumentFile,
|
||||||
override val caption: String? = null,
|
override val caption: String? = null,
|
||||||
override val captionEntities: List<TextPart> = emptyList()
|
override val captionEntities: List<TextPart> = emptyList()
|
||||||
) : MediaContent, CaptionedInput {
|
) : DocumentMediaGroupContent {
|
||||||
override fun createResend(
|
override fun createResend(
|
||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
disableNotification: Boolean,
|
disableNotification: Boolean,
|
||||||
@ -37,10 +38,22 @@ data class DocumentContent(
|
|||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun asInputMedia(): InputMediaDocument = InputMediaDocument(
|
override fun toMediaGroupMemberInputMedia(): InputMediaDocument = asInputMedia()
|
||||||
media.fileId,
|
|
||||||
toMarkdownV2Captions().firstOrNull(),
|
override fun asInputMedia(): InputMediaDocument = media.toInputMediaDocument(
|
||||||
MarkdownV2,
|
toHtmlCaptions().firstOrNull(),
|
||||||
media.thumb ?.fileId
|
HTMLParseMode
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun MediaContent.asDocumentContent() = when (this) {
|
||||||
|
is CaptionedInput -> DocumentContent(
|
||||||
|
media.asDocumentFile(),
|
||||||
|
caption,
|
||||||
|
captionEntities
|
||||||
|
)
|
||||||
|
else -> DocumentContent(
|
||||||
|
media.asDocumentFile()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,14 @@ import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
|||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.requests.send.media.SendPhoto
|
import dev.inmo.tgbotapi.requests.send.media.SendPhoto
|
||||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.InputMediaPhoto
|
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.MediaGroupMemberInputMedia
|
|
||||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
|
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
|
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.files.*
|
import dev.inmo.tgbotapi.types.files.*
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaCollectionContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
|
||||||
import dev.inmo.tgbotapi.utils.toHtmlCaptions
|
import dev.inmo.tgbotapi.utils.toHtmlCaptions
|
||||||
import dev.inmo.tgbotapi.utils.toMarkdownV2Captions
|
import dev.inmo.tgbotapi.utils.toMarkdownV2Captions
|
||||||
|
|
||||||
@ -21,7 +19,7 @@ data class PhotoContent(
|
|||||||
override val mediaCollection: Photo,
|
override val mediaCollection: Photo,
|
||||||
override val caption: String? = null,
|
override val caption: String? = null,
|
||||||
override val captionEntities: List<TextPart> = emptyList()
|
override val captionEntities: List<TextPart> = emptyList()
|
||||||
) : MediaCollectionContent<PhotoSize>, MediaGroupContent {
|
) : MediaCollectionContent<PhotoSize>, VisualMediaGroupContent {
|
||||||
override val media: PhotoSize = mediaCollection.biggest() ?: throw IllegalStateException("Can't locate any photo size for this content")
|
override val media: PhotoSize = mediaCollection.biggest() ?: throw IllegalStateException("Can't locate any photo size for this content")
|
||||||
|
|
||||||
override fun createResend(
|
override fun createResend(
|
||||||
@ -39,15 +37,10 @@ data class PhotoContent(
|
|||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun toMediaGroupMemberInputMedia(): MediaGroupMemberInputMedia = InputMediaPhoto(
|
override fun toMediaGroupMemberInputMedia(): InputMediaPhoto = asInputMedia()
|
||||||
media.fileId,
|
|
||||||
|
override fun asInputMedia(): InputMediaPhoto = media.toInputMediaPhoto(
|
||||||
toHtmlCaptions().firstOrNull(),
|
toHtmlCaptions().firstOrNull(),
|
||||||
HTMLParseMode
|
HTMLParseMode
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun asInputMedia(): InputMediaPhoto = InputMediaPhoto(
|
|
||||||
media.fileId,
|
|
||||||
toMarkdownV2Captions().firstOrNull(),
|
|
||||||
MarkdownV2
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,10 @@ import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
|
|||||||
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
|
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.files.VideoFile
|
import dev.inmo.tgbotapi.types.files.VideoFile
|
||||||
|
import dev.inmo.tgbotapi.types.files.toInputMediaVideo
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
|
||||||
import dev.inmo.tgbotapi.utils.toHtmlCaptions
|
import dev.inmo.tgbotapi.utils.toHtmlCaptions
|
||||||
import dev.inmo.tgbotapi.utils.toMarkdownV2Captions
|
import dev.inmo.tgbotapi.utils.toMarkdownV2Captions
|
||||||
|
|
||||||
@ -20,7 +22,7 @@ data class VideoContent(
|
|||||||
override val media: VideoFile,
|
override val media: VideoFile,
|
||||||
override val caption: String? = null,
|
override val caption: String? = null,
|
||||||
override val captionEntities: List<TextPart> = emptyList()
|
override val captionEntities: List<TextPart> = emptyList()
|
||||||
) : MediaGroupContent {
|
) : VisualMediaGroupContent {
|
||||||
override fun createResend(
|
override fun createResend(
|
||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
disableNotification: Boolean,
|
disableNotification: Boolean,
|
||||||
@ -41,23 +43,10 @@ data class VideoContent(
|
|||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun toMediaGroupMemberInputMedia(): MediaGroupMemberInputMedia = InputMediaVideo(
|
override fun toMediaGroupMemberInputMedia(): InputMediaVideo = asInputMedia()
|
||||||
media.fileId,
|
|
||||||
toHtmlCaptions().firstOrNull(),
|
|
||||||
HTMLParseMode,
|
|
||||||
media.width,
|
|
||||||
media.height,
|
|
||||||
media.duration,
|
|
||||||
media.thumb ?.fileId
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun asInputMedia(): InputMediaVideo = InputMediaVideo(
|
override fun asInputMedia(): InputMediaVideo = media.toInputMediaVideo(
|
||||||
media.fileId,
|
toHtmlCaptions().firstOrNull(),
|
||||||
toMarkdownV2Captions().firstOrNull(),
|
HTMLParseMode
|
||||||
MarkdownV2,
|
|
||||||
media.width,
|
|
||||||
media.height,
|
|
||||||
media.duration,
|
|
||||||
media.thumb ?.fileId
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -17,3 +17,21 @@ package dev.inmo.tgbotapi.utils
|
|||||||
AnnotationTarget.TYPE_PARAMETER
|
AnnotationTarget.TYPE_PARAMETER
|
||||||
)
|
)
|
||||||
annotation class PreviewFeature
|
annotation class PreviewFeature
|
||||||
|
|
||||||
|
@RequiresOptIn(
|
||||||
|
"This feature can work unstable and may have some restrictions in Telegram System",
|
||||||
|
RequiresOptIn.Level.WARNING
|
||||||
|
)
|
||||||
|
@Target(
|
||||||
|
AnnotationTarget.CLASS,
|
||||||
|
AnnotationTarget.CONSTRUCTOR,
|
||||||
|
AnnotationTarget.FIELD,
|
||||||
|
AnnotationTarget.PROPERTY,
|
||||||
|
AnnotationTarget.PROPERTY_GETTER,
|
||||||
|
AnnotationTarget.PROPERTY_SETTER,
|
||||||
|
AnnotationTarget.FUNCTION,
|
||||||
|
AnnotationTarget.TYPE,
|
||||||
|
AnnotationTarget.TYPEALIAS,
|
||||||
|
AnnotationTarget.TYPE_PARAMETER
|
||||||
|
)
|
||||||
|
annotation class RiskFeature(val message: String)
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
package dev.inmo.tgbotapi.extensions.api.send.media
|
package dev.inmo.tgbotapi.extensions.api.send.media
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.requests.send.media.SendMediaGroup
|
import dev.inmo.tgbotapi.requests.send.media.*
|
||||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.MediaGroupMemberInputMedia
|
import dev.inmo.tgbotapi.types.InputMedia.*
|
||||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
||||||
|
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendMediaGroup
|
||||||
|
*/
|
||||||
|
@RiskFeature(rawSendingMediaGroupsWarning)
|
||||||
suspend fun TelegramBot.sendMediaGroup(
|
suspend fun TelegramBot.sendMediaGroup(
|
||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
media: List<MediaGroupMemberInputMedia>,
|
media: List<MediaGroupMemberInputMedia>,
|
||||||
@ -19,6 +24,10 @@ suspend fun TelegramBot.sendMediaGroup(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendMediaGroup
|
||||||
|
*/
|
||||||
|
@RiskFeature(rawSendingMediaGroupsWarning)
|
||||||
suspend fun TelegramBot.sendMediaGroup(
|
suspend fun TelegramBot.sendMediaGroup(
|
||||||
chat: Chat,
|
chat: Chat,
|
||||||
media: List<MediaGroupMemberInputMedia>,
|
media: List<MediaGroupMemberInputMedia>,
|
||||||
@ -28,12 +37,108 @@ suspend fun TelegramBot.sendMediaGroup(
|
|||||||
chat.id, media, disableNotification, replyToMessageId
|
chat.id, media, disableNotification, replyToMessageId
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendPlaylist
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.sendPlaylist(
|
||||||
|
chatId: ChatIdentifier,
|
||||||
|
media: List<AudioMediaGroupMemberInputMedia>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null
|
||||||
|
) = execute(
|
||||||
|
SendPlaylist(
|
||||||
|
chatId, media, disableNotification, replyToMessageId
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendPlaylist
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.sendPlaylist(
|
||||||
|
chat: Chat,
|
||||||
|
media: List<AudioMediaGroupMemberInputMedia>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null
|
||||||
|
) = sendPlaylist(
|
||||||
|
chat.id, media, disableNotification, replyToMessageId
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendDocumentsGroup
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.sendDocumentsGroup(
|
||||||
|
chatId: ChatIdentifier,
|
||||||
|
media: List<DocumentMediaGroupMemberInputMedia>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null
|
||||||
|
) = execute(
|
||||||
|
SendDocumentsGroup(
|
||||||
|
chatId, media, disableNotification, replyToMessageId
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendDocumentsGroup
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.sendDocumentsGroup(
|
||||||
|
chat: Chat,
|
||||||
|
media: List<DocumentMediaGroupMemberInputMedia>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null
|
||||||
|
) = sendDocumentsGroup(
|
||||||
|
chat.id, media, disableNotification, replyToMessageId
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendVisualMediaGroup
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.sendVisualMediaGroup(
|
||||||
|
chatId: ChatIdentifier,
|
||||||
|
media: List<VisualMediaGroupMemberInputMedia>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null
|
||||||
|
) = execute(
|
||||||
|
SendVisualMediaGroup(
|
||||||
|
chatId, media, disableNotification, replyToMessageId
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SendVisualMediaGroup
|
||||||
|
*/
|
||||||
|
suspend fun TelegramBot.sendVisualMediaGroup(
|
||||||
|
chat: Chat,
|
||||||
|
media: List<VisualMediaGroupMemberInputMedia>,
|
||||||
|
disableNotification: Boolean = false,
|
||||||
|
replyToMessageId: MessageIdentifier? = null
|
||||||
|
) = sendVisualMediaGroup(
|
||||||
|
chat.id, media, disableNotification, replyToMessageId
|
||||||
|
)
|
||||||
|
|
||||||
suspend inline fun TelegramBot.replyWithMediaGroup(
|
suspend inline fun TelegramBot.replyWithMediaGroup(
|
||||||
to: Message,
|
to: Message,
|
||||||
media: List<MediaGroupMemberInputMedia>,
|
media: List<MediaGroupMemberInputMedia>,
|
||||||
disableNotification: Boolean = false
|
disableNotification: Boolean = false
|
||||||
) = sendMediaGroup(to.chat, media, disableNotification, to.messageId)
|
) = sendMediaGroup(to.chat, media, disableNotification, to.messageId)
|
||||||
|
|
||||||
|
suspend inline fun TelegramBot.replyWithPlaylist(
|
||||||
|
to: Message,
|
||||||
|
media: List<AudioMediaGroupMemberInputMedia>,
|
||||||
|
disableNotification: Boolean = false
|
||||||
|
) = sendPlaylist(to.chat, media, disableNotification, to.messageId)
|
||||||
|
|
||||||
|
suspend inline fun TelegramBot.replyWithDocumentsGroup(
|
||||||
|
to: Message,
|
||||||
|
media: List<DocumentMediaGroupMemberInputMedia>,
|
||||||
|
disableNotification: Boolean = false
|
||||||
|
) = sendDocumentsGroup(to.chat, media, disableNotification, to.messageId)
|
||||||
|
|
||||||
|
suspend inline fun TelegramBot.replyWithVisualMediaGroup(
|
||||||
|
to: Message,
|
||||||
|
media: List<VisualMediaGroupMemberInputMedia>,
|
||||||
|
disableNotification: Boolean = false
|
||||||
|
) = sendVisualMediaGroup(to.chat, media, disableNotification, to.messageId)
|
||||||
|
|
||||||
suspend inline fun TelegramBot.reply(
|
suspend inline fun TelegramBot.reply(
|
||||||
to: Message,
|
to: Message,
|
||||||
media: List<MediaGroupMemberInputMedia>,
|
media: List<MediaGroupMemberInputMedia>,
|
||||||
|
@ -6,8 +6,7 @@ import dev.inmo.tgbotapi.extensions.utils.updates.asContentMessagesFlow
|
|||||||
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.*
|
import dev.inmo.tgbotapi.types.message.content.*
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
|
|
||||||
import dev.inmo.tgbotapi.types.message.content.media.*
|
import dev.inmo.tgbotapi.types.message.content.media.*
|
||||||
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
import dev.inmo.tgbotapi.types.message.payments.InvoiceContent
|
||||||
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
|
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
|
||||||
@ -101,6 +100,12 @@ fun Flow<BaseSentMessageUpdate>.audioMessages() = filterContentMessages<AudioCon
|
|||||||
fun FlowsUpdatesFilter.audioMessages(
|
fun FlowsUpdatesFilter.audioMessages(
|
||||||
scopeToIncludeChannels: CoroutineScope? = null
|
scopeToIncludeChannels: CoroutineScope? = null
|
||||||
) = filterContentMessages<AudioContent>(scopeToIncludeChannels)
|
) = filterContentMessages<AudioContent>(scopeToIncludeChannels)
|
||||||
|
fun FlowsUpdatesFilter.audioMessagesWithMediaGroups(
|
||||||
|
scopeToIncludeChannels: CoroutineScope? = null
|
||||||
|
) = merge(
|
||||||
|
filterContentMessages<AudioContent>(scopeToIncludeChannels),
|
||||||
|
mediaGroupAudioMessages(scopeToIncludeChannels).flatMap()
|
||||||
|
)
|
||||||
|
|
||||||
fun Flow<BaseSentMessageUpdate>.contactMessages() = filterContentMessages<ContactContent>()
|
fun Flow<BaseSentMessageUpdate>.contactMessages() = filterContentMessages<ContactContent>()
|
||||||
fun FlowsUpdatesFilter.contactMessages(
|
fun FlowsUpdatesFilter.contactMessages(
|
||||||
@ -116,6 +121,12 @@ fun Flow<BaseSentMessageUpdate>.documentMessages() = filterContentMessages<Docum
|
|||||||
fun FlowsUpdatesFilter.documentMessages(
|
fun FlowsUpdatesFilter.documentMessages(
|
||||||
scopeToIncludeChannels: CoroutineScope? = null
|
scopeToIncludeChannels: CoroutineScope? = null
|
||||||
) = filterContentMessages<DocumentContent>(scopeToIncludeChannels)
|
) = filterContentMessages<DocumentContent>(scopeToIncludeChannels)
|
||||||
|
fun FlowsUpdatesFilter.documentMessagesWithMediaGroups(
|
||||||
|
scopeToIncludeChannels: CoroutineScope? = null
|
||||||
|
) = merge(
|
||||||
|
filterContentMessages<DocumentContent>(scopeToIncludeChannels),
|
||||||
|
mediaGroupDocumentMessages(scopeToIncludeChannels).flatMap()
|
||||||
|
)
|
||||||
|
|
||||||
fun Flow<BaseSentMessageUpdate>.gameMessages() = filterContentMessages<GameContent>()
|
fun Flow<BaseSentMessageUpdate>.gameMessages() = filterContentMessages<GameContent>()
|
||||||
fun FlowsUpdatesFilter.gameMessages(
|
fun FlowsUpdatesFilter.gameMessages(
|
||||||
@ -210,3 +221,18 @@ fun Flow<SentMediaGroupUpdate>.mediaGroupVideosMessages() = filterMediaGroupMess
|
|||||||
fun FlowsUpdatesFilter.mediaGroupVideosMessages(
|
fun FlowsUpdatesFilter.mediaGroupVideosMessages(
|
||||||
scopeToIncludeChannels: CoroutineScope? = null
|
scopeToIncludeChannels: CoroutineScope? = null
|
||||||
) = filterMediaGroupMessages<VideoContent>(scopeToIncludeChannels)
|
) = filterMediaGroupMessages<VideoContent>(scopeToIncludeChannels)
|
||||||
|
|
||||||
|
fun Flow<SentMediaGroupUpdate>.mediaGroupVisualMessages() = filterMediaGroupMessages<VisualMediaGroupContent>()
|
||||||
|
fun FlowsUpdatesFilter.mediaGroupVisualMessages(
|
||||||
|
scopeToIncludeChannels: CoroutineScope? = null
|
||||||
|
) = filterMediaGroupMessages<VisualMediaGroupContent>(scopeToIncludeChannels)
|
||||||
|
|
||||||
|
fun Flow<SentMediaGroupUpdate>.mediaGroupAudioMessages() = filterMediaGroupMessages<AudioContent>()
|
||||||
|
fun FlowsUpdatesFilter.mediaGroupAudioMessages(
|
||||||
|
scopeToIncludeChannels: CoroutineScope? = null
|
||||||
|
) = filterMediaGroupMessages<AudioContent>(scopeToIncludeChannels)
|
||||||
|
|
||||||
|
fun Flow<SentMediaGroupUpdate>.mediaGroupDocumentMessages() = filterMediaGroupMessages<DocumentContent>()
|
||||||
|
fun FlowsUpdatesFilter.mediaGroupDocumentMessages(
|
||||||
|
scopeToIncludeChannels: CoroutineScope? = null
|
||||||
|
) = filterMediaGroupMessages<DocumentContent>(scopeToIncludeChannels)
|
||||||
|
Loading…
Reference in New Issue
Block a user