tgbotapi/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendMediaGroup.kt

176 lines
7.0 KiB
Kotlin
Raw Normal View History

2020-10-04 11:06:30 +00:00
package dev.inmo.tgbotapi.requests.send.media
2018-12-26 08:07:24 +00:00
2020-10-04 11:06:30 +00:00
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest
import dev.inmo.tgbotapi.requests.send.media.base.*
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.media.*
2022-11-06 08:07:31 +00:00
import dev.inmo.tgbotapi.types.message.abstracts.PossiblySentViaBotCommonMessage
2020-10-04 11:06:30 +00:00
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializerClass
2022-11-06 08:07:31 +00:00
import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent
import dev.inmo.tgbotapi.types.message.content.VisualMediaGroupPartContent
2022-05-01 05:52:02 +00:00
import dev.inmo.tgbotapi.types.message.content.AudioContent
import dev.inmo.tgbotapi.types.message.content.DocumentContent
2022-11-06 08:07:31 +00:00
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent
import dev.inmo.tgbotapi.utils.*
2022-11-07 19:51:27 +00:00
import dev.inmo.tgbotapi.utils.extensions.asMediaGroupMessage
2018-12-26 08:07:24 +00:00
import kotlinx.serialization.*
2020-03-22 07:37:01 +00:00
import kotlinx.serialization.builtins.ListSerializer
2022-11-06 08:07:31 +00:00
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
2022-11-07 19:51:27 +00:00
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonObject
2020-08-18 06:50:11 +00:00
import kotlinx.serialization.json.buildJsonArray
2022-11-07 19:51:27 +00:00
import kotlinx.serialization.json.jsonPrimitive
2018-12-26 08:07:24 +00:00
2020-11-02 06:39:12 +00:00
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)
2022-11-06 08:07:31 +00:00
fun <T : MediaGroupPartContent> SendMediaGroup(
2018-12-26 08:07:24 +00:00
chatId: ChatIdentifier,
media: List<MediaGroupMemberTelegramMedia>,
threadId: MessageThreadId? = chatId.threadId,
2018-12-26 08:07:24 +00:00
disableNotification: Boolean = false,
2022-01-01 14:13:22 +00:00
protectContent: Boolean = false,
replyToMessageId: MessageId? = null,
allowSendingWithoutReply: Boolean? = null
): Request<PossiblySentViaBotCommonMessage<MediaGroupContent<T>>> {
2020-06-01 05:53:33 +00:00
if (media.size !in mediaCountInMediaGroup) {
throwRangeError("Count of members in media group", mediaCountInMediaGroup, media.size)
2018-12-26 08:07:24 +00:00
}
val files: List<MultipartFile> = media.flatMap {
listOfNotNull(
it.file as? MultipartFile,
if (it is ThumbedTelegramMedia) {
2018-12-26 08:07:24 +00:00
it.thumb as? MultipartFile
} else {
null
}
)
}
val data = SendMediaGroupData(
chatId,
media,
threadId,
2018-12-26 08:07:24 +00:00
disableNotification,
2022-01-01 14:13:22 +00:00
protectContent,
replyToMessageId,
allowSendingWithoutReply
2018-12-26 08:07:24 +00:00
)
return (if (files.isEmpty()) {
2018-12-26 08:07:24 +00:00
data
} else {
MultipartRequestImpl(
data,
SendMediaGroupFiles(files)
)
}) as Request<PossiblySentViaBotCommonMessage<MediaGroupContent<T>>>
2018-12-26 08:07:24 +00:00
}
/**
* Use this method to be sure that you are correctly sending playlist with audios
2020-11-02 06:39:12 +00:00
*
* @see TelegramMediaAudio
*/
@Suppress("NOTHING_TO_INLINE")
inline fun SendPlaylist(
chatId: ChatIdentifier,
media: List<AudioMediaGroupMemberTelegramMedia>,
threadId: MessageThreadId? = chatId.threadId,
disableNotification: Boolean = false,
2022-01-01 14:13:22 +00:00
protectContent: Boolean = false,
replyToMessageId: MessageId? = null,
allowSendingWithoutReply: Boolean? = null
) = SendMediaGroup<AudioContent>(chatId, media, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
/**
* Use this method to be sure that you are correctly sending documents media group
2020-11-02 06:39:12 +00:00
*
* @see TelegramMediaDocument
*/
@Suppress("NOTHING_TO_INLINE")
inline fun SendDocumentsGroup(
chatId: ChatIdentifier,
media: List<DocumentMediaGroupMemberTelegramMedia>,
threadId: MessageThreadId? = chatId.threadId,
disableNotification: Boolean = false,
2022-01-01 14:13:22 +00:00
protectContent: Boolean = false,
replyToMessageId: MessageId? = null,
allowSendingWithoutReply: Boolean? = null
) = SendMediaGroup<DocumentContent>(chatId, media, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
/**
* Use this method to be sure that you are correctly sending visual media group
2020-11-02 06:39:12 +00:00
*
* @see TelegramMediaPhoto
* @see TelegramMediaVideo
*/
@Suppress("NOTHING_TO_INLINE")
inline fun SendVisualMediaGroup(
chatId: ChatIdentifier,
media: List<VisualMediaGroupMemberTelegramMedia>,
threadId: MessageThreadId? = chatId.threadId,
disableNotification: Boolean = false,
2022-01-01 14:13:22 +00:00
protectContent: Boolean = false,
replyToMessageId: MessageId? = null,
allowSendingWithoutReply: Boolean? = null
) = SendMediaGroup<VisualMediaGroupPartContent>(chatId, media, threadId, disableNotification, protectContent, replyToMessageId, allowSendingWithoutReply)
2022-11-06 08:07:31 +00:00
2022-11-07 20:50:22 +00:00
private object MessagesListSerializer: KSerializer<PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>>> {
2022-11-06 08:07:31 +00:00
private val serializer = ListSerializer(TelegramBotAPIMessageDeserializeOnlySerializerClass<PossiblySentViaBotCommonMessage<MediaGroupPartContent>>())
override val descriptor: SerialDescriptor = serializer.descriptor
2022-11-07 20:50:22 +00:00
override fun deserialize(decoder: Decoder): PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>> {
2022-11-06 08:07:31 +00:00
val messages = serializer.deserialize(decoder)
2022-11-07 19:51:27 +00:00
return messages.asMediaGroupMessage()
2022-11-06 08:07:31 +00:00
}
2022-11-07 20:50:22 +00:00
override fun serialize(encoder: Encoder, value: PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>>) {
2022-11-06 08:07:31 +00:00
serializer.serialize(encoder, value.content.group.map { it.sourceMessage })
}
2022-11-06 08:07:31 +00:00
}
2018-12-26 08:07:24 +00:00
@Serializable
data class SendMediaGroupData internal constructor(
@SerialName(chatIdField)
override val chatId: ChatIdentifier,
val media: List<MediaGroupMemberTelegramMedia> = emptyList(),
@SerialName(messageThreadIdField)
override val threadId: MessageThreadId? = chatId.threadId,
2018-12-26 08:07:24 +00:00
@SerialName(disableNotificationField)
override val disableNotification: Boolean = false,
2022-01-01 14:13:22 +00:00
@SerialName(protectContentField)
override val protectContent: Boolean = false,
2018-12-26 08:07:24 +00:00
@SerialName(replyToMessageIdField)
override val replyToMessageId: MessageId? = null,
@SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null
2022-11-07 20:50:22 +00:00
) : DataRequest<PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>>>,
SendMessageRequest<PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>>> {
2018-12-26 08:07:24 +00:00
@SerialName(mediaField)
private val convertedMedia: String
2020-08-18 06:50:11 +00:00
get() = buildJsonArray {
2018-12-26 08:07:24 +00:00
media.forEach {
add(it.toJsonWithoutNulls(MediaGroupMemberTelegramMediaSerializer))
2018-12-26 08:07:24 +00:00
}
}.toString()
override fun method(): String = "sendMediaGroup"
2019-12-02 08:35:37 +00:00
override val requestSerializer: SerializationStrategy<*>
get() = serializer()
2022-11-07 20:50:22 +00:00
override val resultDeserializer: DeserializationStrategy<PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>>>
get() = MessagesListSerializer
2018-12-26 08:07:24 +00:00
}
data class SendMediaGroupFiles internal constructor(
val files: List<MultipartFile>
) : Files by (files.map { it.fileId to it }.toMap())