1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2024-11-22 08:13:47 +00:00

start 0.32.0 as a migration from 0.31.1 due to breaking changes in MediaGroupMessage type

This commit is contained in:
InsanusMokrassar 2021-01-19 10:52:30 +06:00
parent a4bf6911c7
commit ae2f4579e2
21 changed files with 101 additions and 80 deletions

View File

@ -1,10 +1,13 @@
# TelegramBotAPI changelog # TelegramBotAPI changelog
## 0.31.1 ## 0.32.0
* `Common`: * `Common`:
* `Version`: * `Version`:
* `MicroUtils`: `0.4.16` -> `0.4.18` * `MicroUtils`: `0.4.16` -> `0.4.18`
* `Core`:
* Now `MediaGroupMessage` have a generic type related to `MediaGroupContent`
* Methods and types related to `MediaGroupMessage` have been modified according to their meanings
## 0.31.0 ## 0.31.0

View File

@ -17,6 +17,6 @@ micro_utils_version=0.4.18
javax_activation_version=1.1.1 javax_activation_version=1.1.1
library_group=dev.inmo library_group=dev.inmo
library_version=0.31.1 library_version=0.32.0
github_release_plugin_version=2.2.12 github_release_plugin_version=2.2.12

View File

@ -8,6 +8,10 @@ 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.types.message.content.abstracts.MediaGroupContent
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
import dev.inmo.tgbotapi.types.message.content.media.AudioContent
import dev.inmo.tgbotapi.types.message.content.media.DocumentContent
import dev.inmo.tgbotapi.utils.* import dev.inmo.tgbotapi.utils.*
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.builtins.ListSerializer
@ -17,13 +21,13 @@ const val rawSendingMediaGroupsWarning = "Media groups contains restrictions rel
" types. Currently it is possible to combine photo + video OR audio OR documents" " types. Currently it is possible to combine photo + video OR audio OR documents"
@RiskFeature(rawSendingMediaGroupsWarning) @RiskFeature(rawSendingMediaGroupsWarning)
fun SendMediaGroup( fun <T : MediaGroupContent> SendMediaGroup(
chatId: ChatIdentifier, chatId: ChatIdentifier,
media: List<MediaGroupMemberInputMedia>, media: List<MediaGroupMemberInputMedia>,
disableNotification: Boolean = false, disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null allowSendingWithoutReply: Boolean? = null
): Request<List<MediaGroupMessage>> { ): Request<List<MediaGroupMessage<T>>> {
if (media.size !in mediaCountInMediaGroup) { if (media.size !in mediaCountInMediaGroup) {
throwRangeError("Count of members in media group", mediaCountInMediaGroup, media.size) throwRangeError("Count of members in media group", mediaCountInMediaGroup, media.size)
} }
@ -47,14 +51,14 @@ fun SendMediaGroup(
allowSendingWithoutReply allowSendingWithoutReply
) )
return if (files.isEmpty()) { return (if (files.isEmpty()) {
data data
} else { } else {
MultipartRequestImpl( MultipartRequestImpl(
data, data,
SendMediaGroupFiles(files) SendMediaGroupFiles(files)
) )
} }) as Request<List<MediaGroupMessage<T>>>
} }
/** /**
@ -69,7 +73,7 @@ inline fun SendPlaylist(
disableNotification: Boolean = false, disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null allowSendingWithoutReply: Boolean? = null
) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply) ) = SendMediaGroup<AudioContent>(chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply)
/** /**
* Use this method to be sure that you are correctly sending documents media group * Use this method to be sure that you are correctly sending documents media group
@ -83,7 +87,7 @@ inline fun SendDocumentsGroup(
disableNotification: Boolean = false, disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null allowSendingWithoutReply: Boolean? = null
) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply) ) = SendMediaGroup<DocumentContent>(chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply)
/** /**
* Use this method to be sure that you are correctly sending visual media group * Use this method to be sure that you are correctly sending visual media group
@ -98,9 +102,9 @@ inline fun SendVisualMediaGroup(
disableNotification: Boolean = false, disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null allowSendingWithoutReply: Boolean? = null
) = SendMediaGroup(chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply) ) = SendMediaGroup<VisualMediaGroupContent>(chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply)
private val messagesListSerializer: KSerializer<List<MediaGroupMessage>> private val messagesListSerializer: KSerializer<List<MediaGroupMessage<MediaGroupContent>>>
= ListSerializer(TelegramBotAPIMessageDeserializeOnlySerializerClass()) = ListSerializer(TelegramBotAPIMessageDeserializeOnlySerializerClass())
@Serializable @Serializable
@ -114,7 +118,7 @@ data class SendMediaGroupData internal constructor(
override val replyToMessageId: MessageIdentifier? = null, override val replyToMessageId: MessageIdentifier? = null,
@SerialName(allowSendingWithoutReplyField) @SerialName(allowSendingWithoutReplyField)
override val allowSendingWithoutReply: Boolean? = null override val allowSendingWithoutReply: Boolean? = null
) : DataRequest<List<MediaGroupMessage>>, SendMessageRequest<List<MediaGroupMessage>> { ) : DataRequest<List<MediaGroupMessage<MediaGroupContent>>>, SendMessageRequest<List<MediaGroupMessage<MediaGroupContent>>> {
@SerialName(mediaField) @SerialName(mediaField)
private val convertedMedia: String private val convertedMedia: String
get() = buildJsonArray { get() = buildJsonArray {
@ -127,7 +131,7 @@ data class SendMediaGroupData internal constructor(
override fun method(): String = "sendMediaGroup" override fun method(): String = "sendMediaGroup"
override val requestSerializer: SerializationStrategy<*> override val requestSerializer: SerializationStrategy<*>
get() = serializer() get() = serializer()
override val resultDeserializer: DeserializationStrategy<List<MediaGroupMessage>> override val resultDeserializer: DeserializationStrategy<List<MediaGroupMessage<MediaGroupContent>>>
get() = messagesListSerializer get() = messagesListSerializer
} }

View File

@ -9,14 +9,14 @@ import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.abstracts.Message import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
data class ChannelMediaGroupMessage( data class ChannelMediaGroupMessage<T : MediaGroupContent>(
override val messageId: MessageIdentifier, override val messageId: MessageIdentifier,
override val chat: Chat, override val chat: Chat,
override val date: DateTime, override val date: DateTime,
override val mediaGroupId: MediaGroupIdentifier, override val mediaGroupId: MediaGroupIdentifier,
override val content: MediaGroupContent, override val content: T,
override val editDate: DateTime?, override val editDate: DateTime?,
override val forwardInfo: ForwardInfo?, override val forwardInfo: ForwardInfo?,
override val replyTo: Message?, override val replyTo: Message?,
override val replyMarkup: InlineKeyboardMarkup? override val replyMarkup: InlineKeyboardMarkup?
) : MediaGroupMessage ) : MediaGroupMessage<T>

View File

@ -7,15 +7,15 @@ import dev.inmo.tgbotapi.types.chat.abstracts.Chat
import dev.inmo.tgbotapi.types.message.abstracts.* import dev.inmo.tgbotapi.types.message.abstracts.*
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
data class CommonMediaGroupMessage( data class CommonMediaGroupMessage<T : MediaGroupContent>(
override val messageId: MessageIdentifier, override val messageId: MessageIdentifier,
override val user: User, override val user: User,
override val chat: Chat, override val chat: Chat,
override val date: DateTime, override val date: DateTime,
override val mediaGroupId: MediaGroupIdentifier, override val mediaGroupId: MediaGroupIdentifier,
override val content: MediaGroupContent, override val content: T,
override val editDate: DateTime?, override val editDate: DateTime?,
override val forwardInfo: ForwardInfo?, override val forwardInfo: ForwardInfo?,
override val replyTo: Message?, override val replyTo: Message?,
override val replyMarkup: InlineKeyboardMarkup? override val replyMarkup: InlineKeyboardMarkup?
) : MediaGroupMessage, FromUserMessage ) : MediaGroupMessage<T>, FromUserMessage

View File

@ -3,6 +3,6 @@ package dev.inmo.tgbotapi.types.message.abstracts
import dev.inmo.tgbotapi.types.MediaGroupIdentifier import dev.inmo.tgbotapi.types.MediaGroupIdentifier
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
interface MediaGroupMessage : CommonMessage<MediaGroupContent> { interface MediaGroupMessage<T : MediaGroupContent> : CommonMessage<T> {
val mediaGroupId: MediaGroupIdentifier val mediaGroupId: MediaGroupIdentifier
} }

View File

@ -1,12 +1,18 @@
package dev.inmo.tgbotapi.types.message.content.abstracts package dev.inmo.tgbotapi.types.message.content.abstracts
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedInput import dev.inmo.tgbotapi.CommonAbstracts.CaptionedInput
import dev.inmo.tgbotapi.types.InputMedia.MediaGroupMemberInputMedia import dev.inmo.tgbotapi.types.InputMedia.*
interface MediaGroupContent : MediaContent, CaptionedInput { interface MediaGroupContent : MediaContent, CaptionedInput {
fun toMediaGroupMemberInputMedia(): MediaGroupMemberInputMedia fun toMediaGroupMemberInputMedia(): MediaGroupMemberInputMedia
} }
interface VisualMediaGroupContent : MediaGroupContent interface VisualMediaGroupContent : MediaGroupContent {
interface AudioMediaGroupContent : MediaGroupContent override fun toMediaGroupMemberInputMedia(): VisualMediaGroupMemberInputMedia
interface DocumentMediaGroupContent : MediaGroupContent }
interface AudioMediaGroupContent : MediaGroupContent {
override fun toMediaGroupMemberInputMedia(): AudioMediaGroupMemberInputMedia
}
interface DocumentMediaGroupContent : MediaGroupContent {
override fun toMediaGroupMemberInputMedia(): DocumentMediaGroupMemberInputMedia
}

View File

@ -2,11 +2,12 @@ package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
import dev.inmo.tgbotapi.types.UpdateIdentifier import dev.inmo.tgbotapi.types.UpdateIdentifier
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate
data class ChannelPostMediaGroupUpdate( data class ChannelPostMediaGroupUpdate(
override val origins: List<BaseMessageUpdate> override val origins: List<BaseMessageUpdate>
) : SentMediaGroupUpdate { ) : SentMediaGroupUpdate {
override val updateId: UpdateIdentifier = origins.last().updateId override val updateId: UpdateIdentifier = origins.last().updateId
override val data: List<MediaGroupMessage> = origins.mapNotNull { it.data as? MediaGroupMessage } override val data: List<MediaGroupMessage<MediaGroupContent>> = origins.mapNotNull { it.data as? MediaGroupMessage<MediaGroupContent> }
} }

View File

@ -2,11 +2,12 @@ package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
import dev.inmo.tgbotapi.types.UpdateIdentifier import dev.inmo.tgbotapi.types.UpdateIdentifier
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
import dev.inmo.tgbotapi.types.update.EditChannelPostUpdate import dev.inmo.tgbotapi.types.update.EditChannelPostUpdate
data class EditChannelPostMediaGroupUpdate( data class EditChannelPostMediaGroupUpdate(
override val origin: EditChannelPostUpdate override val origin: EditChannelPostUpdate
) : EditMediaGroupUpdate { ) : EditMediaGroupUpdate {
override val updateId: UpdateIdentifier = origin.updateId override val updateId: UpdateIdentifier = origin.updateId
override val data: MediaGroupMessage = origin.data as MediaGroupMessage override val data: MediaGroupMessage<MediaGroupContent> = origin.data as MediaGroupMessage<MediaGroupContent>
} }

View File

@ -2,11 +2,12 @@ package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
import dev.inmo.tgbotapi.types.UpdateIdentifier import dev.inmo.tgbotapi.types.UpdateIdentifier
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
import dev.inmo.tgbotapi.types.update.EditMessageUpdate import dev.inmo.tgbotapi.types.update.EditMessageUpdate
data class EditMessageMediaGroupUpdate( data class EditMessageMediaGroupUpdate(
override val origin: EditMessageUpdate override val origin: EditMessageUpdate
) : EditMediaGroupUpdate { ) : EditMediaGroupUpdate {
override val updateId: UpdateIdentifier = origin.updateId override val updateId: UpdateIdentifier = origin.updateId
override val data: MediaGroupMessage = origin.data as MediaGroupMessage override val data: MediaGroupMessage<MediaGroupContent> = origin.data as MediaGroupMessage<MediaGroupContent>
} }

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types.update.MediaGroupUpdates package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
import dev.inmo.tgbotapi.types.update.abstracts.* import dev.inmo.tgbotapi.types.update.abstracts.*
/** /**
@ -13,11 +14,11 @@ import dev.inmo.tgbotapi.types.update.abstracts.*
interface MediaGroupUpdate : Update interface MediaGroupUpdate : Update
interface SentMediaGroupUpdate: MediaGroupUpdate { interface SentMediaGroupUpdate: MediaGroupUpdate {
override val data: List<MediaGroupMessage> override val data: List<MediaGroupMessage<MediaGroupContent>>
val origins: List<BaseMessageUpdate> val origins: List<BaseMessageUpdate>
} }
interface EditMediaGroupUpdate : BaseEditMessageUpdate, MediaGroupUpdate { interface EditMediaGroupUpdate : BaseEditMessageUpdate, MediaGroupUpdate {
override val data: MediaGroupMessage override val data: MediaGroupMessage<MediaGroupContent>
val origin: BaseMessageUpdate val origin: BaseMessageUpdate
} }

View File

@ -2,11 +2,12 @@ package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
import dev.inmo.tgbotapi.types.UpdateIdentifier import dev.inmo.tgbotapi.types.UpdateIdentifier
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate
data class MessageMediaGroupUpdate( data class MessageMediaGroupUpdate(
override val origins: List<BaseMessageUpdate> override val origins: List<BaseMessageUpdate>
) : SentMediaGroupUpdate { ) : SentMediaGroupUpdate {
override val updateId: UpdateIdentifier = origins.last().updateId override val updateId: UpdateIdentifier = origins.last().updateId
override val data: List<MediaGroupMessage> = origins.mapNotNull { it.data as? MediaGroupMessage } override val data: List<MediaGroupMessage<MediaGroupContent>> = origins.mapNotNull { it.data as? MediaGroupMessage<MediaGroupContent> }
} }

View File

@ -23,7 +23,7 @@ internal fun List<Update>.convertWithMediaGroupUpdates(): List<Update> {
val resultUpdates = mutableListOf<Update>() val resultUpdates = mutableListOf<Update>()
val mediaGroups = mutableMapOf<MediaGroupIdentifier, MutableList<BaseSentMessageUpdate>>() val mediaGroups = mutableMapOf<MediaGroupIdentifier, MutableList<BaseSentMessageUpdate>>()
for (update in this) { for (update in this) {
val data = (update.data as? MediaGroupMessage) val data = (update.data as? MediaGroupMessage<*>)
if (data == null) { if (data == null) {
resultUpdates.add(update) resultUpdates.add(update)
continue continue

View File

@ -7,6 +7,8 @@ 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.types.message.content.abstracts.MediaGroupContent
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
/** /**
@ -20,7 +22,7 @@ suspend fun TelegramBot.sendMediaGroup(
replyToMessageId: MessageIdentifier? = null, replyToMessageId: MessageIdentifier? = null,
allowSendingWithoutReply: Boolean? = null allowSendingWithoutReply: Boolean? = null
) = execute( ) = execute(
SendMediaGroup( SendMediaGroup<MediaGroupContent>(
chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply
) )
) )

View File

@ -31,7 +31,7 @@ fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation(
launch { launch {
for (update in updatesChannel) { for (update in updatesChannel) {
when (val data = update.data) { when (val data = update.data) {
is MediaGroupMessage -> mediaGroupChannel.send("${data.mediaGroupId}${update::class.simpleName}" to update as BaseMessageUpdate) is MediaGroupMessage<*> -> mediaGroupChannel.send("${data.mediaGroupId}${update::class.simpleName}" to update as BaseMessageUpdate)
else -> output(update) else -> output(update)
} }
} }

View File

@ -16,12 +16,12 @@ internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onM
count: Int = 1, count: Int = 1,
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null }, noinline errorFactory: NullableRequestBuilder<*> = { null },
noinline filter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null noinline filter: (suspend (List<MediaGroupMessage<T>>) -> Boolean)? = null
) = flowsUpdatesFilter.expectFlow(bot, initRequest, count, errorFactory) { update -> ) = flowsUpdatesFilter.expectFlow(bot, initRequest, count, errorFactory) { update ->
update.asSentMediaGroupUpdate() ?.data ?.let { mediaGroup -> update.asSentMediaGroupUpdate() ?.data ?.let { mediaGroup ->
if (mediaGroup.all { message -> message.content is T } && (filter == null || filter(mediaGroup))) { if (mediaGroup.all { message -> message.content is T } && (filter == null || filter(mediaGroup as List<MediaGroupMessage<T>>))) {
listOf( listOf(
mediaGroup.map { it.content as T } mediaGroup.map { it.content as T } as List<MediaGroupMessage<T>>
) )
} else { } else {
null null
@ -33,29 +33,29 @@ suspend fun BehaviourContext.waitPlaylist(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null filter: (suspend (List<MediaGroupMessage<AudioMediaGroupContent>>) -> Boolean)? = null
) = onMediaGroup<AudioMediaGroupContent>(count, initRequest, errorFactory, filter) ) = onMediaGroup(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitDocumentsGroup( suspend fun BehaviourContext.waitDocumentsGroup(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null filter: (suspend (List<MediaGroupMessage<DocumentMediaGroupContent>>) -> Boolean)? = null
) = onMediaGroup<DocumentMediaGroupContent>(count, initRequest, errorFactory, filter) ) = onMediaGroup(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitVisualGallery( suspend fun BehaviourContext.waitVisualGallery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null filter: (suspend (List<MediaGroupMessage<VisualMediaGroupContent>>) -> Boolean)? = null
) = onMediaGroup<VisualMediaGroupContent>(count, initRequest, errorFactory, filter) ) = onMediaGroup(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitPhotoGallery( suspend fun BehaviourContext.waitPhotoGallery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null filter: (suspend (List<MediaGroupMessage<PhotoContent>>) -> Boolean)? = null
) = onMediaGroup<PhotoContent>(count, initRequest, errorFactory, filter) ) = onMediaGroup(count, initRequest, errorFactory, filter)
suspend fun BehaviourContext.waitVideoGallery( suspend fun BehaviourContext.waitVideoGallery(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
count: Int = 1, count: Int = 1,
filter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null filter: (suspend (List<MediaGroupMessage<VideoContent>>) -> Boolean)? = null
) = onMediaGroup<VideoContent>(count, initRequest, errorFactory, filter) ) = onMediaGroup(count, initRequest, errorFactory, filter)

View File

@ -12,8 +12,7 @@ import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
import dev.inmo.tgbotapi.extensions.utils.shortcuts.chat import dev.inmo.tgbotapi.extensions.utils.shortcuts.chat
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.* import dev.inmo.tgbotapi.types.message.content.abstracts.*
import dev.inmo.tgbotapi.types.message.content.media.PhotoContent import dev.inmo.tgbotapi.types.message.content.media.*
import dev.inmo.tgbotapi.types.message.content.media.VideoContent
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
import dev.inmo.tgbotapi.utils.PreviewFeature import dev.inmo.tgbotapi.utils.PreviewFeature
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
@ -21,12 +20,12 @@ import kotlinx.coroutines.flow.filter
@PreviewFeature @PreviewFeature
internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onMediaGroup( internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onMediaGroup(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
noinline additionalFilter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null, noinline additionalFilter: (suspend (List<MediaGroupMessage<T>>) -> Boolean)? = null,
noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage>> noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<T>>>
) = flowsUpdatesFilter.expectFlow(bot) { update -> ) = flowsUpdatesFilter.expectFlow(bot) { update ->
update.asSentMediaGroupUpdate() ?.data ?.let { mediaGroup -> update.asSentMediaGroupUpdate() ?.data ?.let { mediaGroup ->
if (mediaGroup.all { message -> message.content is T } && (additionalFilter == null || additionalFilter(mediaGroup))) { if (mediaGroup.all { message -> message.content is T } && (additionalFilter == null || additionalFilter(mediaGroup as List<MediaGroupMessage<T>>))) {
listOf(mediaGroup) listOf(mediaGroup as List<MediaGroupMessage<T>>)
} else { } else {
null null
} }
@ -35,10 +34,11 @@ internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onM
val (jobToCancel, scenario) = if (includeFilterByChatInBehaviourSubContext) { val (jobToCancel, scenario) = if (includeFilterByChatInBehaviourSubContext) {
val subFilter = FlowsUpdatesFilter() val subFilter = FlowsUpdatesFilter()
val subBehaviourContext = copy(flowsUpdatesFilter = subFilter) val subBehaviourContext = copy(flowsUpdatesFilter = subFilter)
val mediaGroupChat = mediaGroup.chat!!
flowsUpdatesFilter.allUpdatesFlow.filter { flowsUpdatesFilter.allUpdatesFlow.filter {
val chat = it.sourceChat() ?: return@filter false val chat = it.sourceChat() ?: return@filter false
chat.id.chatId == mediaGroup.chat!!.id.chatId chat.id.chatId == mediaGroupChat.id.chatId
}.subscribeSafelyWithoutExceptions(scope, subFilter.asUpdateReceiver) to subBehaviourContext }.subscribeSafelyWithoutExceptions(scope, subFilter.asUpdateReceiver) to subBehaviourContext
} else { } else {
null to this null to this
@ -49,27 +49,27 @@ internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onM
suspend fun BehaviourContext.onPlaylist( suspend fun BehaviourContext.onPlaylist(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null, additionalFilter: (suspend (List<MediaGroupMessage<AudioMediaGroupContent>>) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<AudioMediaGroupContent>>>
) = onMediaGroup<AudioMediaGroupContent>(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) ) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onDocumentsGroup( suspend fun BehaviourContext.onDocumentsGroup(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null, additionalFilter: (suspend (List<MediaGroupMessage<DocumentMediaGroupContent>>) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<DocumentMediaGroupContent>>>
) = onMediaGroup<DocumentMediaGroupContent>(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) ) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onVisualGallery( suspend fun BehaviourContext.onVisualGallery(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null, additionalFilter: (suspend (List<MediaGroupMessage<VisualMediaGroupContent>>) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<VisualMediaGroupContent>>>
) = onMediaGroup<VisualMediaGroupContent>(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) ) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onPhotoGallery( suspend fun BehaviourContext.onPhotoGallery(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null, additionalFilter: (suspend (List<MediaGroupMessage<PhotoContent>>) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<PhotoContent>>>
) = onMediaGroup<PhotoContent>(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) ) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
suspend fun BehaviourContext.onVideoGallery( suspend fun BehaviourContext.onVideoGallery(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null, additionalFilter: (suspend (List<MediaGroupMessage<VideoContent>>) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage>> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<VideoContent>>>
) = onMediaGroup<VideoContent>(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) ) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)

View File

@ -160,17 +160,17 @@ inline fun Message.asChannelEventMessage(): ChannelEventMessage<ChannelEvent>? =
@PreviewFeature @PreviewFeature
inline fun Message.requireChannelEventMessage(): ChannelEventMessage<ChannelEvent> = this as ChannelEventMessage<ChannelEvent> inline fun Message.requireChannelEventMessage(): ChannelEventMessage<ChannelEvent> = this as ChannelEventMessage<ChannelEvent>
@PreviewFeature @PreviewFeature
inline fun Message.asChannelMediaGroupMessage(): ChannelMediaGroupMessage? = this as? ChannelMediaGroupMessage inline fun Message.asChannelMediaGroupMessage(): ChannelMediaGroupMessage<MediaGroupContent>? = this as? ChannelMediaGroupMessage<MediaGroupContent>
@PreviewFeature @PreviewFeature
inline fun Message.requireChannelMediaGroupMessage(): ChannelMediaGroupMessage = this as ChannelMediaGroupMessage inline fun Message.requireChannelMediaGroupMessage(): ChannelMediaGroupMessage<MediaGroupContent> = this as ChannelMediaGroupMessage<MediaGroupContent>
@PreviewFeature @PreviewFeature
inline fun Message.asCommonGroupEventMessage(): CommonGroupEventMessage<GroupEvent>? = this as? CommonGroupEventMessage<GroupEvent> inline fun Message.asCommonGroupEventMessage(): CommonGroupEventMessage<GroupEvent>? = this as? CommonGroupEventMessage<GroupEvent>
@PreviewFeature @PreviewFeature
inline fun Message.requireCommonGroupEventMessage(): CommonGroupEventMessage<GroupEvent> = this as CommonGroupEventMessage<GroupEvent> inline fun Message.requireCommonGroupEventMessage(): CommonGroupEventMessage<GroupEvent> = this as CommonGroupEventMessage<GroupEvent>
@PreviewFeature @PreviewFeature
inline fun Message.asCommonMediaGroupMessage(): CommonMediaGroupMessage? = this as? CommonMediaGroupMessage inline fun Message.asCommonMediaGroupMessage(): CommonMediaGroupMessage<MediaGroupContent>? = this as? CommonMediaGroupMessage<MediaGroupContent>
@PreviewFeature @PreviewFeature
inline fun Message.requireCommonMediaGroupMessage(): CommonMediaGroupMessage = this as CommonMediaGroupMessage inline fun Message.requireCommonMediaGroupMessage(): CommonMediaGroupMessage<MediaGroupContent> = this as CommonMediaGroupMessage<MediaGroupContent>
@PreviewFeature @PreviewFeature
inline fun Message.asCommonSupergroupEventMessage(): CommonSupergroupEventMessage<SupergroupEvent>? = this as? CommonSupergroupEventMessage<SupergroupEvent> inline fun Message.asCommonSupergroupEventMessage(): CommonSupergroupEventMessage<SupergroupEvent>? = this as? CommonSupergroupEventMessage<SupergroupEvent>
@PreviewFeature @PreviewFeature
@ -212,9 +212,9 @@ inline fun Message.asGroupMessage(): GroupMessage<MessageContent>? = this as? Gr
@PreviewFeature @PreviewFeature
inline fun Message.requireGroupMessage(): GroupMessage<MessageContent> = this as GroupMessage<MessageContent> inline fun Message.requireGroupMessage(): GroupMessage<MessageContent> = this as GroupMessage<MessageContent>
@PreviewFeature @PreviewFeature
inline fun Message.asMediaGroupMessage(): MediaGroupMessage? = this as? MediaGroupMessage inline fun Message.asMediaGroupMessage(): MediaGroupMessage<MediaGroupContent>? = this as? MediaGroupMessage<MediaGroupContent>
@PreviewFeature @PreviewFeature
inline fun Message.requireMediaGroupMessage(): MediaGroupMessage = this as MediaGroupMessage inline fun Message.requireMediaGroupMessage(): MediaGroupMessage<MediaGroupContent> = this as MediaGroupMessage<MediaGroupContent>
@PreviewFeature @PreviewFeature
inline fun Message.asPossiblyEditedMessage(): PossiblyEditedMessage? = this as? PossiblyEditedMessage inline fun Message.asPossiblyEditedMessage(): PossiblyEditedMessage? = this as? PossiblyEditedMessage
@PreviewFeature @PreviewFeature

View File

@ -8,13 +8,13 @@ import dev.inmo.tgbotapi.types.message.abstracts.*
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.SentMediaGroupUpdate
val List<CommonMessage<MediaGroupContent>>.forwardInfo: ForwardInfo? val List<CommonMessage<out MediaGroupContent>>.forwardInfo: ForwardInfo?
get() = firstOrNull() ?.forwardInfo get() = firstOrNull() ?.forwardInfo
val List<CommonMessage<MediaGroupContent>>.replyTo: Message? val List<CommonMessage<out MediaGroupContent>>.replyTo: Message?
get() = firstOrNull() ?.replyTo get() = firstOrNull() ?.replyTo
val List<CommonMessage<MediaGroupContent>>.chat: Chat? val List<CommonMessage<out MediaGroupContent>>.chat: Chat?
get() = firstOrNull() ?.chat get() = firstOrNull() ?.chat
val List<MediaGroupMessage>.mediaGroupId: MediaGroupIdentifier? val List<MediaGroupMessage<*>>.mediaGroupId: MediaGroupIdentifier?
get() = firstOrNull() ?.mediaGroupId get() = firstOrNull() ?.mediaGroupId
val SentMediaGroupUpdate.forwardInfo: ForwardInfo? val SentMediaGroupUpdate.forwardInfo: ForwardInfo?
@ -30,7 +30,7 @@ fun List<CommonMessage<MediaGroupContent>>.createResend(
chatId: ChatId, chatId: ChatId,
disableNotification: Boolean = false, disableNotification: Boolean = false,
replyTo: MessageIdentifier? = null replyTo: MessageIdentifier? = null
) = SendMediaGroup( ) = SendMediaGroup<MediaGroupContent>(
chatId, chatId,
map { it.content.toMediaGroupMemberInputMedia() }, map { it.content.toMediaGroupMemberInputMedia() },
disableNotification, disableNotification,

View File

@ -34,7 +34,7 @@ fun List<Update>.convertWithMediaGroupUpdates(): List<Update> {
val resultUpdates = mutableListOf<Update>() val resultUpdates = mutableListOf<Update>()
val mediaGroups = mutableMapOf<MediaGroupIdentifier, MutableList<BaseSentMessageUpdate>>() val mediaGroups = mutableMapOf<MediaGroupIdentifier, MutableList<BaseSentMessageUpdate>>()
for (update in this) { for (update in this) {
val data = (update.data as? MediaGroupMessage) val data = (update.data as? MediaGroupMessage<*>)
if (data == null) { if (data == null) {
resultUpdates.add(update) resultUpdates.add(update)
continue continue

View File

@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
import dev.inmo.tgbotapi.extensions.utils.updates.convertWithMediaGroupUpdates import dev.inmo.tgbotapi.extensions.utils.updates.convertWithMediaGroupUpdates
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.updateshandlers.UpdateReceiver import dev.inmo.tgbotapi.updateshandlers.UpdateReceiver
@ -32,7 +33,7 @@ fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation(
launch { launch {
for (update in updatesChannel) { for (update in updatesChannel) {
when (val data = update.data) { when (val data = update.data) {
is MediaGroupMessage -> mediaGroupChannel.send("${data.mediaGroupId}${update::class.simpleName}" to update as BaseMessageUpdate) is MediaGroupMessage<*> -> mediaGroupChannel.send("${data.mediaGroupId}${update::class.simpleName}" to update as BaseMessageUpdate)
else -> output(update) else -> output(update)
} }
} }