diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e75892d38..2d7f8fb055 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,15 @@ * Fixes in edition of inline messages and their result types * Replace basic exception and add `ReplyMessageNotFound` exception +### 0.10.1 + +* Change algorithm of `executeUnsafe`: now it use loop instead of recursive calling +* Add additional `startGettingUpdates` with better management of received updates for media groups +* Now `MediaGroupMessage` is `CommonMessage` with `MediaGroupContent` content +* Added extensions `replyTo`, `forwarded` and `chat` for `List` for comfortable +work with media groups lists +* Fix `parseMode` of `InputTextMessageContent` + ## 0.9.0 * Old extension `OkHttpClient.Builder#useWith` now deprecated and must be replaced by the same in diff --git a/build.gradle b/build.gradle index 810ac6ef59..6688104501 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -project.version = "0.10.0" +project.version = "0.10.1" project.group = "com.github.insanusmokrassar" buildscript { diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InlineQueries/InputMessageContent/InputTextMessageContent.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InlineQueries/InputMessageContent/InputTextMessageContent.kt index a6b8012e64..b93ae41b47 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InlineQueries/InputMessageContent/InputTextMessageContent.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InlineQueries/InputMessageContent/InputTextMessageContent.kt @@ -14,7 +14,8 @@ data class InputTextMessageContent( @SerialName(messageTextField) override val caption: String, @SerialName(parseModeField) - override val parseMode: ParseMode, + @Optional + override val parseMode: ParseMode? = null, @SerialName(disableWebPagePreviewField) @Optional override val disableWebPagePreview: Boolean? = null diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/CommonMediaGroupMessage.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/CommonMediaGroupMessage.kt index d91fc439a3..878dc837c4 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/CommonMediaGroupMessage.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/CommonMediaGroupMessage.kt @@ -13,5 +13,8 @@ data class CommonMediaGroupMessage( override val chat: Chat, override val date: DateTime, override val mediaGroupId: MediaGroupIdentifier, - override val content: MediaGroupContent + override val content: MediaGroupContent, + override val editDate: DateTime?, + override val forwarded: ForwardedMessage?, + override val replyTo: Message? ) : Message, MediaGroupMessage, FromUserMessage diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/MediaGroupMessage.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/MediaGroupMessage.kt index b20c3eaf3a..904cda00d6 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/MediaGroupMessage.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/MediaGroupMessage.kt @@ -13,5 +13,8 @@ data class MediaGroupMessage( override val chat: Chat, override val date: DateTime, override val mediaGroupId: MediaGroupIdentifier, - override val content: MediaGroupContent + override val content: MediaGroupContent, + override val editDate: DateTime?, + override val forwarded: ForwardedMessage?, + override val replyTo: Message? ) : Message, MediaGroupMessage diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/RawMessage.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/RawMessage.kt index 1806b20c20..d42a935102 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/RawMessage.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/RawMessage.kt @@ -219,7 +219,10 @@ data class RawMessage( is PhotoContent -> content is VideoContent -> content else -> throw IllegalStateException("Unsupported content for media group") - } + }, + edit_date ?.asDate, + forwarded, + reply_to_message ?.asMessage ) else -> CommonMediaGroupMessage( messageId, @@ -231,7 +234,10 @@ data class RawMessage( is PhotoContent -> content is VideoContent -> content else -> throw IllegalStateException("Unsupported content for media group") - } + }, + edit_date ?.asDate, + forwarded, + reply_to_message ?.asMessage ) } } ?: when (chat) { diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/abstracts/MediaGroupMessage.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/abstracts/MediaGroupMessage.kt index 29b53ca253..56d76252b1 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/abstracts/MediaGroupMessage.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/abstracts/MediaGroupMessage.kt @@ -3,7 +3,6 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts import com.github.insanusmokrassar.TelegramBotAPI.types.MediaGroupIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MediaGroupContent -interface MediaGroupMessage : Message { +interface MediaGroupMessage : CommonMessage { val mediaGroupId: MediaGroupIdentifier - val content: MediaGroupContent } diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MediaGroupList.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MediaGroupList.kt new file mode 100644 index 0000000000..08866b8335 --- /dev/null +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MediaGroupList.kt @@ -0,0 +1,19 @@ +package com.github.insanusmokrassar.TelegramBotAPI.utils + +import com.github.insanusmokrassar.TelegramBotAPI.types.chat.Chat +import com.github.insanusmokrassar.TelegramBotAPI.types.message.ForwardedMessage +import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.* +import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.BaseMessageUpdate + +val List.forwarded: ForwardedMessage? + get() = first().let { + (it as? AbleToBeForwardedMessage) ?.forwarded + } + +val List.replyTo: Message? + get() = first().let { + (it as? AbleToReplyMessage) ?.replyTo + } + +val List.chat: Chat? + get() = first().data.chat 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 1c621db8b0..d44cdb5871 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 @@ -99,10 +99,13 @@ fun RequestsExecutor.startGettingOfUpdates( fun RequestsExecutor.startGettingOfUpdates( messageCallback: UpdateReceiver? = null, - mediaGroupCallback: UpdateReceiver>? = null, + messageMediaGroupCallback: UpdateReceiver>? = null, editedMessageCallback: UpdateReceiver? = null, + editedMessageMediaGroupCallback: UpdateReceiver>? = null, channelPostCallback: UpdateReceiver? = null, + channelPostMediaGroupCallback: UpdateReceiver>? = null, editedChannelPostCallback: UpdateReceiver? = null, + editedChannelPostMediaGroupCallback: UpdateReceiver>? = null, chosenInlineResultCallback: UpdateReceiver? = null, inlineQueryCallback: UpdateReceiver? = null, callbackQueryCallback: UpdateReceiver? = null, @@ -115,36 +118,92 @@ fun RequestsExecutor.startGettingOfUpdates( requestsDelayMillis, scope, listOfNotNull( - messageCallback ?.let { UPDATE_MESSAGE }, - editedMessageCallback ?.let { UPDATE_EDITED_MESSAGE }, - channelPostCallback ?.let { UPDATE_CHANNEL_POST }, - editedChannelPostCallback ?.let { UPDATE_EDITED_CHANNEL_POST }, + (messageCallback ?: messageMediaGroupCallback) ?.let { UPDATE_MESSAGE }, + (editedMessageCallback ?: editedMessageMediaGroupCallback) ?.let { UPDATE_EDITED_MESSAGE }, + (channelPostCallback ?: channelPostMediaGroupCallback) ?.let { UPDATE_CHANNEL_POST }, + (editedChannelPostCallback ?: editedChannelPostMediaGroupCallback) ?.let { UPDATE_EDITED_CHANNEL_POST }, chosenInlineResultCallback ?.let { UPDATE_CHOSEN_INLINE_RESULT }, inlineQueryCallback ?.let { UPDATE_INLINE_QUERY }, callbackQueryCallback ?.let { UPDATE_CALLBACK_QUERY }, shippingQueryCallback ?.let { UPDATE_SHIPPING_QUERY }, preCheckoutQueryCallback ?.let { UPDATE_PRE_CHECKOUT_QUERY } ) - ) { - when (it) { - is MessageUpdate -> messageCallback ?.invoke(it) - is List<*> -> mediaGroupCallback ?.invoke( - it.mapNotNull { - it as? BaseMessageUpdate + ) { update -> + when (update) { + is MessageUpdate -> messageCallback ?.invoke(update) + is List<*> -> when (update.firstOrNull()) { + is MessageUpdate -> update.mapNotNull { it as? MessageUpdate }.let { mappedList -> + messageMediaGroupCallback ?.also { receiver -> + receiver(mappedList) + } ?: messageCallback ?.also { receiver -> + mappedList.forEach { receiver(it) } + } } - ) - 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) + is EditMessageUpdate -> update.mapNotNull { it as? EditMessageUpdate }.let { mappedList -> + editedMessageMediaGroupCallback ?.also { receiver -> + receiver(mappedList) + } ?: editedMessageCallback ?.also { receiver -> + mappedList.forEach { receiver(it) } + } + } + is ChannelPostUpdate -> update.mapNotNull { it as? ChannelPostUpdate }.let { mappedList -> + channelPostMediaGroupCallback ?.also { receiver -> + receiver(mappedList) + } ?: channelPostCallback ?.also { receiver -> + mappedList.forEach { receiver(it) } + } + } + is EditChannelPostUpdate -> update.mapNotNull { it as? EditChannelPostUpdate }.let { mappedList -> + editedChannelPostMediaGroupCallback ?.also { receiver -> + receiver(mappedList) + } ?: editedChannelPostCallback ?.also { receiver -> + mappedList.forEach { receiver(it) } + } + } + } + is EditMessageUpdate -> editedMessageCallback ?.invoke(update) + is ChannelPostUpdate -> channelPostCallback ?.invoke(update) + is EditChannelPostUpdate -> editedChannelPostCallback ?.invoke(update) + is ChosenInlineResultUpdate -> chosenInlineResultCallback ?.invoke(update) + is InlineQueryUpdate -> inlineQueryCallback ?.invoke(update) + is CallbackQueryUpdate -> callbackQueryCallback ?.invoke(update) + is ShippingQueryUpdate -> shippingQueryCallback ?.invoke(update) + is PreCheckoutQueryUpdate -> preCheckoutQueryCallback ?.invoke(update) } } } +fun RequestsExecutor.startGettingOfUpdates( + 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 = startGettingOfUpdates( + messageCallback = messageCallback, + messageMediaGroupCallback = mediaGroupCallback, + editedMessageCallback = editedMessageCallback, + editedMessageMediaGroupCallback = mediaGroupCallback, + channelPostCallback = channelPostCallback, + channelPostMediaGroupCallback = mediaGroupCallback, + editedChannelPostCallback = editedChannelPostCallback, + editedChannelPostMediaGroupCallback = mediaGroupCallback, + chosenInlineResultCallback = chosenInlineResultCallback, + inlineQueryCallback = inlineQueryCallback, + callbackQueryCallback = callbackQueryCallback, + shippingQueryCallback = shippingQueryCallback, + preCheckoutQueryCallback = preCheckoutQueryCallback, + requestsDelayMillis = requestsDelayMillis, + scope = scope +) + fun RequestsExecutor.executeAsync( request: Request, onFail: (suspend (Response<*>) -> Unit)? = null, @@ -173,14 +232,17 @@ suspend fun RequestsExecutor.executeUnsafe( retries: Int = 0, retriesDelay: Long = 1000L ): T? { - return try { - execute(request) - } catch (e: RequestException) { - if (retries > 0) { - delay(retriesDelay) - executeUnsafe(request, retries - 1, retriesDelay) - } else { - null + var leftRetries = retries + while(true) { + try { + return execute(request) + } catch (e: RequestException) { + if (leftRetries > 0) { + leftRetries-- + delay(retriesDelay) + } else { + return null + } } } }