diff --git a/CHANGELOG b/CHANGELOG index f5b3309789..b9ad38e912 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -32,3 +32,6 @@ * Now all media sending factories which contains `thumb` have default `null` value * `ChatIdentifier` classes now are `data` classes * Now `MediaGroupContent` interface contains `toMediaGroupMemberInputMedia` method for easily creating mirror input media +* Change signature of `Update` + * Now `Update` is untyped and data is `Any` +* Media groups now are separated type of updates and you can subscribe on that receiving directly diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/CallbackQueryUpdate.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/CallbackQueryUpdate.kt index 2912b1afc0..a17dd76254 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/CallbackQueryUpdate.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/CallbackQueryUpdate.kt @@ -7,4 +7,4 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update data class CallbackQueryUpdate( override val updateId: UpdateIdentifier, override val data: CallbackQuery -) : Update +) : Update diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/ChosenInlineResultUpdate.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/ChosenInlineResultUpdate.kt index 329bb77d24..6dbcde4ff9 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/ChosenInlineResultUpdate.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/ChosenInlineResultUpdate.kt @@ -7,4 +7,4 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update data class ChosenInlineResultUpdate( override val updateId: UpdateIdentifier, override val data: ChosenInlineResult -) : Update \ No newline at end of file +) : Update \ No newline at end of file diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/InlineQueryUpdate.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/InlineQueryUpdate.kt index a5b82a311d..2bb00ce4bc 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/InlineQueryUpdate.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/InlineQueryUpdate.kt @@ -7,4 +7,4 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update data class InlineQueryUpdate( override val updateId: UpdateIdentifier, override val data: InlineQuery -) : Update +) : Update diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/PreCheckoutQueryUpdate.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/PreCheckoutQueryUpdate.kt index 70c22a4027..259eba0e75 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/PreCheckoutQueryUpdate.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/PreCheckoutQueryUpdate.kt @@ -7,4 +7,4 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update data class PreCheckoutQueryUpdate( override val updateId: UpdateIdentifier, override val data: PreCheckoutQuery -) : Update +) : Update diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/RawUpdate.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/RawUpdate.kt index 63991bd96b..4c5e8699e1 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/RawUpdate.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/RawUpdate.kt @@ -28,7 +28,7 @@ data class RawUpdate constructor( @Optional private val pre_checkout_query: PreCheckoutQuery? = null ) { @Transient - val asUpdate: Update<*> by lazy { + val asUpdate: Update by lazy { when { message != null -> MessageUpdate(updateId, message.asMessage) edited_message != null -> EditMessageUpdate(updateId, edited_message.asMessage) diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/ShippingQueryUpdate.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/ShippingQueryUpdate.kt index 51143da3d8..ee172c6b53 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/ShippingQueryUpdate.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/ShippingQueryUpdate.kt @@ -7,4 +7,4 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update data class ShippingQueryUpdate( override val updateId: UpdateIdentifier, override val data: ShippingQuery -) : Update +) : Update diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/BaseMessageUpdate.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/BaseMessageUpdate.kt index 147c4edea6..2387a8b2a8 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/BaseMessageUpdate.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/BaseMessageUpdate.kt @@ -2,4 +2,6 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Message -interface BaseMessageUpdate : Update \ No newline at end of file +interface BaseMessageUpdate : Update { + override val data: Message +} \ No newline at end of file diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/Update.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/Update.kt index 8b8029724c..dacc8176ab 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/Update.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/update/abstracts/Update.kt @@ -2,7 +2,7 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts import com.github.insanusmokrassar.TelegramBotAPI.types.UpdateIdentifier -interface Update { +interface Update { val updateId: UpdateIdentifier - val data: T + val data: Any } diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/extensions/RequestsExecutor.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/extensions/RequestsExecutor.kt index 72456e7e8e..fb45a37225 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/extensions/RequestsExecutor.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/extensions/RequestsExecutor.kt @@ -9,20 +9,22 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.abstracts. import com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.abstracts.InlineQuery import com.github.insanusmokrassar.TelegramBotAPI.types.ResponseParameters import com.github.insanusmokrassar.TelegramBotAPI.types.UpdateIdentifier +import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.MediaGroupMessage import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Message import com.github.insanusmokrassar.TelegramBotAPI.types.payments.PreCheckoutQuery import com.github.insanusmokrassar.TelegramBotAPI.types.payments.ShippingQuery import com.github.insanusmokrassar.TelegramBotAPI.types.update.* +import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.BaseMessageUpdate import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update import kotlinx.coroutines.* -typealias UpdateReceiver = suspend Update.() -> Unit +typealias UpdateReceiver = suspend (T) -> Unit fun RequestsExecutor.startGettingOfUpdates( requestsDelayMillis: Long = 1000, scope: CoroutineScope = GlobalScope, allowedUpdates: List? = null, - block: UpdateReceiver<*> + block: UpdateReceiver ): Job { return scope.launch { var lastHandledUpdate: UpdateIdentifier = 0L @@ -36,11 +38,57 @@ fun RequestsExecutor.startGettingOfUpdates( ) ) - for (rawUpdate in updates) { + val adaptedUpdates = mutableListOf() + var mediaGroup: MutableList? = null + + fun pushMediaGroup() { + mediaGroup ?.also { + adaptedUpdates.add(it) + mediaGroup = null + } + } + + updates.map { + it.asUpdate + }.forEach { update -> + val data = update.data + if (data is MediaGroupMessage) { + mediaGroup ?.let { + val message = it.first().data as MediaGroupMessage + if (message.mediaGroupId == data.mediaGroupId) { + it.add(update) + } else { + null + } + } ?: data.also { + pushMediaGroup() + mediaGroup = mutableListOf() + mediaGroup ?.add(update) + } + } else { + pushMediaGroup() + adaptedUpdates.add(update) + } + } + + mediaGroup ?.also { + adaptedUpdates.add(it) + mediaGroup = null + } + + for (update in adaptedUpdates) { + try { - val update = rawUpdate.asUpdate block(update) - lastHandledUpdate = update.updateId + lastHandledUpdate = when (update) { + is Update -> update.updateId + is List<*> -> (update.last() as? Update) ?.updateId ?: throw IllegalStateException( + "Found non-updates oriented list" + ) + else -> throw IllegalStateException( + "Unknown type of data" + ) + } } catch (e: Exception) { // TODO:: add exception handling e.printStackTrace() @@ -56,15 +104,16 @@ fun RequestsExecutor.startGettingOfUpdates( } fun RequestsExecutor.startGettingOfUpdates( - messageCallback: UpdateReceiver? = null, - editedMessageCallback: UpdateReceiver? = null, - channelPostCallback: UpdateReceiver? = null, - editedChannelPostCallback: UpdateReceiver? = null, - chosenInlineResultCallback: UpdateReceiver? = null, - inlineQueryCallback: UpdateReceiver? = null, - callbackQueryCallback: UpdateReceiver? = null, - shippingQueryCallback: UpdateReceiver? = null, - preCheckoutQueryCallback: UpdateReceiver? = null, + messageCallback: UpdateReceiver? = null, + mediaGroupCallback: UpdateReceiver>? = null, + editedMessageCallback: UpdateReceiver? = null, + channelPostCallback: UpdateReceiver? = null, + editedChannelPostCallback: UpdateReceiver? = null, + chosenInlineResultCallback: UpdateReceiver? = null, + inlineQueryCallback: UpdateReceiver? = null, + callbackQueryCallback: UpdateReceiver? = null, + shippingQueryCallback: UpdateReceiver? = null, + preCheckoutQueryCallback: UpdateReceiver? = null, requestsDelayMillis: Long = 1000, scope: CoroutineScope = GlobalScope ): Job { @@ -83,16 +132,21 @@ fun RequestsExecutor.startGettingOfUpdates( preCheckoutQueryCallback ?.let { UPDATE_PRE_CHECKOUT_QUERY } ) ) { - when (this) { - is MessageUpdate -> messageCallback ?.invoke(this) - is EditMessageUpdate -> editedMessageCallback ?.invoke(this) - is ChannelPostUpdate -> channelPostCallback ?.invoke(this) - is EditChannelPostUpdate -> editedChannelPostCallback ?.invoke(this) - is ChosenInlineResultUpdate -> chosenInlineResultCallback ?.invoke(this) - is InlineQueryUpdate -> inlineQueryCallback ?.invoke(this) - is CallbackQueryUpdate -> callbackQueryCallback ?.invoke(this) - is ShippingQueryUpdate -> shippingQueryCallback ?.invoke(this) - is PreCheckoutQueryUpdate -> preCheckoutQueryCallback ?.invoke(this) + when (it) { + is MessageUpdate -> messageCallback ?.invoke(it) + is List<*> -> mediaGroupCallback ?.invoke( + it.mapNotNull { + it as? BaseMessageUpdate + } + ) + is EditMessageUpdate -> editedMessageCallback ?.invoke(it) + is ChannelPostUpdate -> channelPostCallback ?.invoke(it) + is EditChannelPostUpdate -> editedChannelPostCallback ?.invoke(it) + is ChosenInlineResultUpdate -> chosenInlineResultCallback ?.invoke(it) + is InlineQueryUpdate -> inlineQueryCallback ?.invoke(it) + is CallbackQueryUpdate -> callbackQueryCallback ?.invoke(it) + is ShippingQueryUpdate -> shippingQueryCallback ?.invoke(it) + is PreCheckoutQueryUpdate -> preCheckoutQueryCallback ?.invoke(it) } } }