diff --git a/CHANGELOG.md b/CHANGELOG.md
index e483ed977b..c5207890f8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,13 @@
 # TelegramBotAPI changelog
 
-## 0.31.1
+## 0.32.0
 
 * `Common`:
     * `Version`:
         * `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
 
diff --git a/gradle.properties b/gradle.properties
index 97f5960b25..cc3412fe0d 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -17,6 +17,6 @@ micro_utils_version=0.4.18
 javax_activation_version=1.1.1
 
 library_group=dev.inmo
-library_version=0.31.1
+library_version=0.32.0
 
 github_release_plugin_version=2.2.12
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendMediaGroup.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendMediaGroup.kt
index df4a949fa1..1352d3a9b9 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendMediaGroup.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/send/media/SendMediaGroup.kt
@@ -8,6 +8,10 @@ import dev.inmo.tgbotapi.types.*
 import dev.inmo.tgbotapi.types.InputMedia.*
 import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
 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 kotlinx.serialization.*
 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"
 
 @RiskFeature(rawSendingMediaGroupsWarning)
-fun SendMediaGroup(
+fun <T : MediaGroupContent> SendMediaGroup(
     chatId: ChatIdentifier,
     media: List<MediaGroupMemberInputMedia>,
     disableNotification: Boolean = false,
     replyToMessageId: MessageIdentifier? = null,
     allowSendingWithoutReply: Boolean? = null
-): Request<List<MediaGroupMessage>> {
+): Request<List<MediaGroupMessage<T>>> {
     if (media.size !in mediaCountInMediaGroup) {
         throwRangeError("Count of members in media group", mediaCountInMediaGroup, media.size)
     }
@@ -47,14 +51,14 @@ fun SendMediaGroup(
         allowSendingWithoutReply
     )
 
-    return if (files.isEmpty()) {
+    return (if (files.isEmpty()) {
         data
     } else {
         MultipartRequestImpl(
             data,
             SendMediaGroupFiles(files)
         )
-    }
+    }) as Request<List<MediaGroupMessage<T>>>
 }
 
 /**
@@ -69,7 +73,7 @@ inline fun SendPlaylist(
     disableNotification: Boolean = false,
     replyToMessageId: MessageIdentifier? = 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
@@ -83,7 +87,7 @@ inline fun SendDocumentsGroup(
     disableNotification: Boolean = false,
     replyToMessageId: MessageIdentifier? = 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
@@ -98,9 +102,9 @@ inline fun SendVisualMediaGroup(
     disableNotification: Boolean = false,
     replyToMessageId: MessageIdentifier? = 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())
 
 @Serializable
@@ -114,7 +118,7 @@ data class SendMediaGroupData internal constructor(
     override val replyToMessageId: MessageIdentifier? = null,
     @SerialName(allowSendingWithoutReplyField)
     override val allowSendingWithoutReply: Boolean? = null
-) : DataRequest<List<MediaGroupMessage>>, SendMessageRequest<List<MediaGroupMessage>> {
+) : DataRequest<List<MediaGroupMessage<MediaGroupContent>>>, SendMessageRequest<List<MediaGroupMessage<MediaGroupContent>>> {
     @SerialName(mediaField)
     private val convertedMedia: String
         get() = buildJsonArray {
@@ -127,7 +131,7 @@ data class SendMediaGroupData internal constructor(
     override fun method(): String = "sendMediaGroup"
     override val requestSerializer: SerializationStrategy<*>
         get() = serializer()
-    override val resultDeserializer: DeserializationStrategy<List<MediaGroupMessage>>
+    override val resultDeserializer: DeserializationStrategy<List<MediaGroupMessage<MediaGroupContent>>>
         get() = messagesListSerializer
 }
 
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChannelMediaGroupMessage.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChannelMediaGroupMessage.kt
index 70d670d41e..3f3688e702 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChannelMediaGroupMessage.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/ChannelMediaGroupMessage.kt
@@ -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.content.abstracts.MediaGroupContent
 
-data class ChannelMediaGroupMessage(
+data class ChannelMediaGroupMessage<T : MediaGroupContent>(
     override val messageId: MessageIdentifier,
     override val chat: Chat,
     override val date: DateTime,
     override val mediaGroupId: MediaGroupIdentifier,
-    override val content: MediaGroupContent,
+    override val content: T,
     override val editDate: DateTime?,
     override val forwardInfo: ForwardInfo?,
     override val replyTo: Message?,
     override val replyMarkup: InlineKeyboardMarkup?
-) : MediaGroupMessage
+) : MediaGroupMessage<T>
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/CommonMediaGroupMessage.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/CommonMediaGroupMessage.kt
index 2694c7d187..49d1118e57 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/CommonMediaGroupMessage.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/CommonMediaGroupMessage.kt
@@ -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.content.abstracts.MediaGroupContent
 
-data class CommonMediaGroupMessage(
+data class CommonMediaGroupMessage<T : MediaGroupContent>(
     override val messageId: MessageIdentifier,
     override val user: User,
     override val chat: Chat,
     override val date: DateTime,
     override val mediaGroupId: MediaGroupIdentifier,
-    override val content: MediaGroupContent,
+    override val content: T,
     override val editDate: DateTime?,
     override val forwardInfo: ForwardInfo?,
     override val replyTo: Message?,
     override val replyMarkup: InlineKeyboardMarkup?
-) : MediaGroupMessage, FromUserMessage
+) : MediaGroupMessage<T>, FromUserMessage
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/MediaGroupMessage.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/MediaGroupMessage.kt
index c78ab44f77..307ba6e78c 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/MediaGroupMessage.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/abstracts/MediaGroupMessage.kt
@@ -3,6 +3,6 @@ package dev.inmo.tgbotapi.types.message.abstracts
 import dev.inmo.tgbotapi.types.MediaGroupIdentifier
 import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
 
-interface MediaGroupMessage : CommonMessage<MediaGroupContent> {
+interface MediaGroupMessage<T : MediaGroupContent> : CommonMessage<T> {
     val mediaGroupId: MediaGroupIdentifier
 }
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/abstracts/MediaGroupContent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/abstracts/MediaGroupContent.kt
index a284c0c4b8..7cf2eb6b16 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/abstracts/MediaGroupContent.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/abstracts/MediaGroupContent.kt
@@ -1,12 +1,18 @@
 package dev.inmo.tgbotapi.types.message.content.abstracts
 
 import dev.inmo.tgbotapi.CommonAbstracts.CaptionedInput
-import dev.inmo.tgbotapi.types.InputMedia.MediaGroupMemberInputMedia
+import dev.inmo.tgbotapi.types.InputMedia.*
 
 interface MediaGroupContent : MediaContent, CaptionedInput {
     fun toMediaGroupMemberInputMedia(): MediaGroupMemberInputMedia
 }
 
-interface VisualMediaGroupContent : MediaGroupContent
-interface AudioMediaGroupContent : MediaGroupContent
-interface DocumentMediaGroupContent : MediaGroupContent
+interface VisualMediaGroupContent : MediaGroupContent {
+    override fun toMediaGroupMemberInputMedia(): VisualMediaGroupMemberInputMedia
+}
+interface AudioMediaGroupContent : MediaGroupContent {
+    override fun toMediaGroupMemberInputMedia(): AudioMediaGroupMemberInputMedia
+}
+interface DocumentMediaGroupContent : MediaGroupContent {
+    override fun toMediaGroupMemberInputMedia(): DocumentMediaGroupMemberInputMedia
+}
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/ChannelPostMediaGroupUpdate.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/ChannelPostMediaGroupUpdate.kt
index fa4532d80d..505caf47ef 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/ChannelPostMediaGroupUpdate.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/ChannelPostMediaGroupUpdate.kt
@@ -2,11 +2,12 @@ package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
 
 import dev.inmo.tgbotapi.types.UpdateIdentifier
 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
 
 data class ChannelPostMediaGroupUpdate(
     override val origins: List<BaseMessageUpdate>
 ) : SentMediaGroupUpdate {
     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> }
 }
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/EditChannelPostMediaGroupUpdate.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/EditChannelPostMediaGroupUpdate.kt
index 596088bbcb..8c0935d199 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/EditChannelPostMediaGroupUpdate.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/EditChannelPostMediaGroupUpdate.kt
@@ -2,11 +2,12 @@ package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
 
 import dev.inmo.tgbotapi.types.UpdateIdentifier
 import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
+import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
 import dev.inmo.tgbotapi.types.update.EditChannelPostUpdate
 
 data class EditChannelPostMediaGroupUpdate(
     override val origin: EditChannelPostUpdate
 ) : EditMediaGroupUpdate {
     override val updateId: UpdateIdentifier = origin.updateId
-    override val data: MediaGroupMessage = origin.data as MediaGroupMessage
+    override val data: MediaGroupMessage<MediaGroupContent> = origin.data as MediaGroupMessage<MediaGroupContent>
 }
\ No newline at end of file
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/EditMessageMediaGroupUpdate.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/EditMessageMediaGroupUpdate.kt
index 0a88e5c117..075b3c38d2 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/EditMessageMediaGroupUpdate.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/EditMessageMediaGroupUpdate.kt
@@ -2,11 +2,12 @@ package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
 
 import dev.inmo.tgbotapi.types.UpdateIdentifier
 import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
+import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
 import dev.inmo.tgbotapi.types.update.EditMessageUpdate
 
 data class EditMessageMediaGroupUpdate(
     override val origin: EditMessageUpdate
 ) : EditMediaGroupUpdate {
     override val updateId: UpdateIdentifier = origin.updateId
-    override val data: MediaGroupMessage = origin.data as MediaGroupMessage
+    override val data: MediaGroupMessage<MediaGroupContent> = origin.data as MediaGroupMessage<MediaGroupContent>
 }
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/MediaGroupUpdate.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/MediaGroupUpdate.kt
index 77c7f41f8d..b50e772ba7 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/MediaGroupUpdate.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/MediaGroupUpdate.kt
@@ -1,6 +1,7 @@
 package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
 
 import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
+import dev.inmo.tgbotapi.types.message.content.abstracts.MediaGroupContent
 import dev.inmo.tgbotapi.types.update.abstracts.*
 
 /**
@@ -13,11 +14,11 @@ import dev.inmo.tgbotapi.types.update.abstracts.*
 interface MediaGroupUpdate : Update
 
 interface SentMediaGroupUpdate: MediaGroupUpdate {
-    override val data: List<MediaGroupMessage>
+    override val data: List<MediaGroupMessage<MediaGroupContent>>
     val origins: List<BaseMessageUpdate>
 }
 
 interface EditMediaGroupUpdate : BaseEditMessageUpdate, MediaGroupUpdate {
-    override val data: MediaGroupMessage
+    override val data: MediaGroupMessage<MediaGroupContent>
     val origin: BaseMessageUpdate
 }
diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/MessageMediaGroupUpdate.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/MessageMediaGroupUpdate.kt
index f5bb8e69e7..3dd3c86cb0 100644
--- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/MessageMediaGroupUpdate.kt
+++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/update/MediaGroupUpdates/MessageMediaGroupUpdate.kt
@@ -2,11 +2,12 @@ package dev.inmo.tgbotapi.types.update.MediaGroupUpdates
 
 import dev.inmo.tgbotapi.types.UpdateIdentifier
 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
 
 data class MessageMediaGroupUpdate(
     override val origins: List<BaseMessageUpdate>
 ) : SentMediaGroupUpdate {
     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> }
 }
\ No newline at end of file
diff --git a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/InternalUtils/UpdatesUtils.kt b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/InternalUtils/UpdatesUtils.kt
index 42caeeb6b8..8a35681bd7 100644
--- a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/InternalUtils/UpdatesUtils.kt
+++ b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/InternalUtils/UpdatesUtils.kt
@@ -23,7 +23,7 @@ internal fun List<Update>.convertWithMediaGroupUpdates(): List<Update> {
     val resultUpdates = mutableListOf<Update>()
     val mediaGroups = mutableMapOf<MediaGroupIdentifier, MutableList<BaseSentMessageUpdate>>()
     for (update in this) {
-        val data = (update.data as? MediaGroupMessage)
+        val data = (update.data as? MediaGroupMessage<*>)
         if (data == null) {
             resultUpdates.add(update)
             continue
diff --git a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/media/SendMediaGroup.kt b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/media/SendMediaGroup.kt
index 6a115897b8..e8cf10588f 100644
--- a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/media/SendMediaGroup.kt
+++ b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/send/media/SendMediaGroup.kt
@@ -7,6 +7,8 @@ import dev.inmo.tgbotapi.types.InputMedia.*
 import dev.inmo.tgbotapi.types.MessageIdentifier
 import dev.inmo.tgbotapi.types.chat.abstracts.Chat
 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
 
 /**
@@ -20,7 +22,7 @@ suspend fun TelegramBot.sendMediaGroup(
     replyToMessageId: MessageIdentifier? = null,
     allowSendingWithoutReply: Boolean? = null
 ) = execute(
-    SendMediaGroup(
+    SendMediaGroup<MediaGroupContent>(
         chatId, media, disableNotification, replyToMessageId, allowSendingWithoutReply
     )
 )
diff --git a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/utils/UpdatesHandling.kt b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/utils/UpdatesHandling.kt
index 3f9e249fea..54845e4c3a 100644
--- a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/utils/UpdatesHandling.kt
+++ b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/utils/UpdatesHandling.kt
@@ -31,7 +31,7 @@ fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation(
         launch {
             for (update in updatesChannel) {
                 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)
                 }
             }
diff --git a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitMediaGroup.kt b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitMediaGroup.kt
index f94531487a..0ed50f8add 100644
--- a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitMediaGroup.kt
+++ b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/expectations/WaitMediaGroup.kt
@@ -16,12 +16,12 @@ internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onM
     count: Int = 1,
     initRequest: Request<*>? = 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 ->
     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(
-                mediaGroup.map { it.content as T }
+                mediaGroup.map { it.content as T } as List<MediaGroupMessage<T>>
             )
         } else {
             null
@@ -33,29 +33,29 @@ suspend fun BehaviourContext.waitPlaylist(
     initRequest: Request<*>? = null,
     errorFactory: NullableRequestBuilder<*> = { null },
     count: Int = 1,
-    filter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null
-) = onMediaGroup<AudioMediaGroupContent>(count, initRequest, errorFactory, filter)
+    filter: (suspend (List<MediaGroupMessage<AudioMediaGroupContent>>) -> Boolean)? = null
+) = onMediaGroup(count, initRequest, errorFactory, filter)
 suspend fun BehaviourContext.waitDocumentsGroup(
     initRequest: Request<*>? = null,
     errorFactory: NullableRequestBuilder<*> = { null },
     count: Int = 1,
-    filter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null
-) = onMediaGroup<DocumentMediaGroupContent>(count, initRequest, errorFactory, filter)
+    filter: (suspend (List<MediaGroupMessage<DocumentMediaGroupContent>>) -> Boolean)? = null
+) = onMediaGroup(count, initRequest, errorFactory, filter)
 suspend fun BehaviourContext.waitVisualGallery(
     initRequest: Request<*>? = null,
     errorFactory: NullableRequestBuilder<*> = { null },
     count: Int = 1,
-    filter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null
-) = onMediaGroup<VisualMediaGroupContent>(count, initRequest, errorFactory, filter)
+    filter: (suspend (List<MediaGroupMessage<VisualMediaGroupContent>>) -> Boolean)? = null
+) = onMediaGroup(count, initRequest, errorFactory, filter)
 suspend fun BehaviourContext.waitPhotoGallery(
     initRequest: Request<*>? = null,
     errorFactory: NullableRequestBuilder<*> = { null },
     count: Int = 1,
-    filter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null
-) = onMediaGroup<PhotoContent>(count, initRequest, errorFactory, filter)
+    filter: (suspend (List<MediaGroupMessage<PhotoContent>>) -> Boolean)? = null
+) = onMediaGroup(count, initRequest, errorFactory, filter)
 suspend fun BehaviourContext.waitVideoGallery(
     initRequest: Request<*>? = null,
     errorFactory: NullableRequestBuilder<*> = { null },
     count: Int = 1,
-    filter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null
-) = onMediaGroup<VideoContent>(count, initRequest, errorFactory, filter)
+    filter: (suspend (List<MediaGroupMessage<VideoContent>>) -> Boolean)? = null
+) = onMediaGroup(count, initRequest, errorFactory, filter)
diff --git a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/MediaGroupTriggers.kt b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/MediaGroupTriggers.kt
index e273335bf8..6e195fddbc 100644
--- a/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/MediaGroupTriggers.kt
+++ b/tgbotapi.extensions.behaviour_builder/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/behaviour_builder/triggers_handling/MediaGroupTriggers.kt
@@ -12,8 +12,7 @@ import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
 import dev.inmo.tgbotapi.extensions.utils.shortcuts.chat
 import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage
 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.VideoContent
+import dev.inmo.tgbotapi.types.message.content.media.*
 import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
 import dev.inmo.tgbotapi.utils.PreviewFeature
 import kotlinx.coroutines.flow.filter
@@ -21,12 +20,12 @@ import kotlinx.coroutines.flow.filter
 @PreviewFeature
 internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onMediaGroup(
     includeFilterByChatInBehaviourSubContext: Boolean = true,
-    noinline additionalFilter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null,
-    noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage>>
+    noinline additionalFilter: (suspend (List<MediaGroupMessage<T>>) -> Boolean)? = null,
+    noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<T>>>
 ) = flowsUpdatesFilter.expectFlow(bot) { update ->
     update.asSentMediaGroupUpdate() ?.data ?.let { mediaGroup ->
-        if (mediaGroup.all { message -> message.content is T } && (additionalFilter == null || additionalFilter(mediaGroup))) {
-            listOf(mediaGroup)
+        if (mediaGroup.all { message -> message.content is T } && (additionalFilter == null || additionalFilter(mediaGroup as List<MediaGroupMessage<T>>))) {
+            listOf(mediaGroup as List<MediaGroupMessage<T>>)
         } else {
             null
         }
@@ -35,10 +34,11 @@ internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onM
     val (jobToCancel, scenario) = if (includeFilterByChatInBehaviourSubContext) {
         val subFilter = FlowsUpdatesFilter()
         val subBehaviourContext = copy(flowsUpdatesFilter = subFilter)
+        val mediaGroupChat = mediaGroup.chat!!
 
         flowsUpdatesFilter.allUpdatesFlow.filter {
             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
     } else {
         null to this
@@ -49,27 +49,27 @@ internal suspend inline fun <reified T : MediaGroupContent> BehaviourContext.onM
 
 suspend fun BehaviourContext.onPlaylist(
     includeFilterByChatInBehaviourSubContext: Boolean = true,
-    additionalFilter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null,
-    scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage>>
-) = onMediaGroup<AudioMediaGroupContent>(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
+    additionalFilter: (suspend (List<MediaGroupMessage<AudioMediaGroupContent>>) -> Boolean)? = null,
+    scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<AudioMediaGroupContent>>>
+) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
 suspend fun BehaviourContext.onDocumentsGroup(
     includeFilterByChatInBehaviourSubContext: Boolean = true,
-    additionalFilter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null,
-    scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage>>
-) = onMediaGroup<DocumentMediaGroupContent>(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
+    additionalFilter: (suspend (List<MediaGroupMessage<DocumentMediaGroupContent>>) -> Boolean)? = null,
+    scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<DocumentMediaGroupContent>>>
+) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
 suspend fun BehaviourContext.onVisualGallery(
     includeFilterByChatInBehaviourSubContext: Boolean = true,
-    additionalFilter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null,
-    scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage>>
-) = onMediaGroup<VisualMediaGroupContent>(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
+    additionalFilter: (suspend (List<MediaGroupMessage<VisualMediaGroupContent>>) -> Boolean)? = null,
+    scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<VisualMediaGroupContent>>>
+) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
 suspend fun BehaviourContext.onPhotoGallery(
     includeFilterByChatInBehaviourSubContext: Boolean = true,
-    additionalFilter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null,
-    scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage>>
-) = onMediaGroup<PhotoContent>(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
+    additionalFilter: (suspend (List<MediaGroupMessage<PhotoContent>>) -> Boolean)? = null,
+    scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<PhotoContent>>>
+) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
 suspend fun BehaviourContext.onVideoGallery(
     includeFilterByChatInBehaviourSubContext: Boolean = true,
-    additionalFilter: (suspend (List<MediaGroupMessage>) -> Boolean)? = null,
-    scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage>>
-) = onMediaGroup<VideoContent>(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
+    additionalFilter: (suspend (List<MediaGroupMessage<VideoContent>>) -> Boolean)? = null,
+    scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, List<MediaGroupMessage<VideoContent>>>
+) = onMediaGroup(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)
 
diff --git a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt
index a6956c3282..25c0e86e29 100644
--- a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt
+++ b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/ClassCasts.kt
@@ -160,17 +160,17 @@ inline fun Message.asChannelEventMessage(): ChannelEventMessage<ChannelEvent>? =
 @PreviewFeature
 inline fun Message.requireChannelEventMessage(): ChannelEventMessage<ChannelEvent> = this as ChannelEventMessage<ChannelEvent>
 @PreviewFeature
-inline fun Message.asChannelMediaGroupMessage(): ChannelMediaGroupMessage? = this as? ChannelMediaGroupMessage
+inline fun Message.asChannelMediaGroupMessage(): ChannelMediaGroupMessage<MediaGroupContent>? = this as? ChannelMediaGroupMessage<MediaGroupContent>
 @PreviewFeature
-inline fun Message.requireChannelMediaGroupMessage(): ChannelMediaGroupMessage = this as ChannelMediaGroupMessage
+inline fun Message.requireChannelMediaGroupMessage(): ChannelMediaGroupMessage<MediaGroupContent> = this as ChannelMediaGroupMessage<MediaGroupContent>
 @PreviewFeature
 inline fun Message.asCommonGroupEventMessage(): CommonGroupEventMessage<GroupEvent>? = this as? CommonGroupEventMessage<GroupEvent>
 @PreviewFeature
 inline fun Message.requireCommonGroupEventMessage(): CommonGroupEventMessage<GroupEvent> = this as CommonGroupEventMessage<GroupEvent>
 @PreviewFeature
-inline fun Message.asCommonMediaGroupMessage(): CommonMediaGroupMessage? = this as? CommonMediaGroupMessage
+inline fun Message.asCommonMediaGroupMessage(): CommonMediaGroupMessage<MediaGroupContent>? = this as? CommonMediaGroupMessage<MediaGroupContent>
 @PreviewFeature
-inline fun Message.requireCommonMediaGroupMessage(): CommonMediaGroupMessage = this as CommonMediaGroupMessage
+inline fun Message.requireCommonMediaGroupMessage(): CommonMediaGroupMessage<MediaGroupContent> = this as CommonMediaGroupMessage<MediaGroupContent>
 @PreviewFeature
 inline fun Message.asCommonSupergroupEventMessage(): CommonSupergroupEventMessage<SupergroupEvent>? = this as? CommonSupergroupEventMessage<SupergroupEvent>
 @PreviewFeature
@@ -212,9 +212,9 @@ inline fun Message.asGroupMessage(): GroupMessage<MessageContent>? = this as? Gr
 @PreviewFeature
 inline fun Message.requireGroupMessage(): GroupMessage<MessageContent> = this as GroupMessage<MessageContent>
 @PreviewFeature
-inline fun Message.asMediaGroupMessage(): MediaGroupMessage? = this as? MediaGroupMessage
+inline fun Message.asMediaGroupMessage(): MediaGroupMessage<MediaGroupContent>? = this as? MediaGroupMessage<MediaGroupContent>
 @PreviewFeature
-inline fun Message.requireMediaGroupMessage(): MediaGroupMessage = this as MediaGroupMessage
+inline fun Message.requireMediaGroupMessage(): MediaGroupMessage<MediaGroupContent> = this as MediaGroupMessage<MediaGroupContent>
 @PreviewFeature
 inline fun Message.asPossiblyEditedMessage(): PossiblyEditedMessage? = this as? PossiblyEditedMessage
 @PreviewFeature
diff --git a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/MediaGroupsShortcuts.kt b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/MediaGroupsShortcuts.kt
index 031d187697..78376ea9ad 100644
--- a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/MediaGroupsShortcuts.kt
+++ b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/shortcuts/MediaGroupsShortcuts.kt
@@ -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.update.MediaGroupUpdates.SentMediaGroupUpdate
 
-val List<CommonMessage<MediaGroupContent>>.forwardInfo: ForwardInfo?
+val List<CommonMessage<out MediaGroupContent>>.forwardInfo: ForwardInfo?
     get() = firstOrNull() ?.forwardInfo
-val List<CommonMessage<MediaGroupContent>>.replyTo: Message?
+val List<CommonMessage<out MediaGroupContent>>.replyTo: Message?
     get() = firstOrNull() ?.replyTo
-val List<CommonMessage<MediaGroupContent>>.chat: Chat?
+val List<CommonMessage<out MediaGroupContent>>.chat: Chat?
     get() = firstOrNull() ?.chat
-val List<MediaGroupMessage>.mediaGroupId: MediaGroupIdentifier?
+val List<MediaGroupMessage<*>>.mediaGroupId: MediaGroupIdentifier?
     get() = firstOrNull() ?.mediaGroupId
 
 val SentMediaGroupUpdate.forwardInfo: ForwardInfo?
@@ -30,7 +30,7 @@ fun List<CommonMessage<MediaGroupContent>>.createResend(
     chatId: ChatId,
     disableNotification: Boolean = false,
     replyTo: MessageIdentifier? = null
-) = SendMediaGroup(
+) = SendMediaGroup<MediaGroupContent>(
     chatId,
     map { it.content.toMediaGroupMemberInputMedia() },
     disableNotification,
diff --git a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/UpdatesUtils.kt b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/UpdatesUtils.kt
index 4d0963708f..63a3983c87 100644
--- a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/UpdatesUtils.kt
+++ b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/UpdatesUtils.kt
@@ -34,7 +34,7 @@ fun List<Update>.convertWithMediaGroupUpdates(): List<Update> {
     val resultUpdates = mutableListOf<Update>()
     val mediaGroups = mutableMapOf<MediaGroupIdentifier, MutableList<BaseSentMessageUpdate>>()
     for (update in this) {
-        val data = (update.data as? MediaGroupMessage)
+        val data = (update.data as? MediaGroupMessage<*>)
         if (data == null) {
             resultUpdates.add(update)
             continue
diff --git a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/retrieving/MediaGroupsIncluder.kt b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/retrieving/MediaGroupsIncluder.kt
index 75ef278a8d..bae30b47ce 100644
--- a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/retrieving/MediaGroupsIncluder.kt
+++ b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/updates/retrieving/MediaGroupsIncluder.kt
@@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
 
 import dev.inmo.tgbotapi.extensions.utils.updates.convertWithMediaGroupUpdates
 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.Update
 import dev.inmo.tgbotapi.updateshandlers.UpdateReceiver
@@ -32,7 +33,7 @@ fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation(
         launch {
             for (update in updatesChannel) {
                 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)
                 }
             }