mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-12-16 11:15:50 +00:00
fix of #1019 and improve longPollingFlow
This commit is contained in:
@@ -8,11 +8,14 @@
|
||||
* `KSP`: `2.2.20-2.0.4` -> `2.3.2`
|
||||
* `MicroUtils`: `0.26.6` -> `0.26.8`
|
||||
* `KSLog`: `1.5.1` -> `1.5.2`
|
||||
* `Core`:
|
||||
* Allow to use `SetWebhook` with `maxAllowedConnections` up to `100000`
|
||||
* `KSP`:
|
||||
* Fixed annotation property access for KSP2 compatibility using `withNoSuchElementWorkaround`
|
||||
* Removed `ksp.useKSP2=false` workaround from `gradle.properties` (KSP2 is now properly supported)
|
||||
* `Utils`:
|
||||
* Regenerated class casts extensions
|
||||
* Allow to use custom `GetUpdates` in `longPollingFlow`
|
||||
|
||||
## 30.0.1
|
||||
|
||||
|
||||
@@ -10654,6 +10654,7 @@ public final class dev/inmo/tgbotapi/types/CommonKt {
|
||||
public static final field yShiftField Ljava/lang/String;
|
||||
public static final field yearField Ljava/lang/String;
|
||||
public static final fun getAllowedConnectionsLength ()Lkotlin/ranges/IntRange;
|
||||
public static final fun getAllowedConnectionsWithLocalServerLength ()Lkotlin/ranges/IntRange;
|
||||
public static final fun getBasketballAndFootballDiceResultLimit ()Lkotlin/ranges/IntRange;
|
||||
public static final fun getBotCommandDescriptionLimit ()Lkotlin/ranges/IntRange;
|
||||
public static final fun getBotCommandLengthLimit ()Lkotlin/ranges/IntRange;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package dev.inmo.tgbotapi.requests.webhook
|
||||
|
||||
import dev.inmo.kslog.common.w
|
||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||
import dev.inmo.tgbotapi.requests.send.media.base.DataRequest
|
||||
import dev.inmo.tgbotapi.requests.send.media.base.MultipartRequestImpl
|
||||
import dev.inmo.tgbotapi.types.*
|
||||
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
@@ -118,11 +120,22 @@ fun SetWebhook(
|
||||
)
|
||||
|
||||
/**
|
||||
* Use this method to specify a url and receive incoming updates via an outgoing webhook. Whenever there is an update
|
||||
* for the bot, we will send an HTTPS POST request to the specified url, containing a JSON-serialized Update.
|
||||
* Represents a request for setting a webhook in Telegram's Bot API. A webhook allows Telegram to send updates directly
|
||||
* to the bot via an HTTPS POST request to the provided URL, enabling real-time interaction.
|
||||
*
|
||||
* If you'd like to make sure that the Webhook request comes from Telegram, we recommend using a secret path in the [url],
|
||||
* e.g. https://www.example.com/<token>. Since nobody else knows your bot's token, you can be pretty sure it's us.
|
||||
* @constructor Creates a data class holding configuration options for the webhook.
|
||||
*
|
||||
* @property url The HTTPS URL to which updates will be posted. Must be valid and accessible.
|
||||
* @property certificateFile An optional path to a public certificate file for webhook verification. Use only if a self-signed certificate is applied.
|
||||
* @property ipAddress The fixed IP address for incoming webhook connections.
|
||||
* @property maxAllowedConnections The maximum number of simultaneous HTTPS connections allowed to the webhook for
|
||||
* delivering updates. You may use value outside of [allowedConnectionsLength], but be sure that it is in
|
||||
* [allowedConnectionsWithLocalServerLength] and you are using local bot api url
|
||||
* @property allowedUpdates A list of update types the bot will receive. Defaults to all update types.
|
||||
* @property dropPendingUpdates If true, all pending updates will be dropped when the webhook is changed.
|
||||
* @property secretToken An optional arbitrary secret key to ensure the webhook updates are coming from Telegram.
|
||||
*
|
||||
* @throws IllegalArgumentException if the provided maxAllowedConnections value is outside the permitted range (both [allowedConnectionsLength] and [allowedConnectionsWithLocalServerLength])
|
||||
*/
|
||||
@ConsistentCopyVisibility
|
||||
@Serializable
|
||||
@@ -150,8 +163,19 @@ data class SetWebhook internal constructor(
|
||||
|
||||
init {
|
||||
maxAllowedConnections ?.let {
|
||||
if (it !in allowedConnectionsLength) {
|
||||
throw IllegalArgumentException("Allowed connection for webhook must be in $allowedConnectionsLength range (but passed $it)")
|
||||
when {
|
||||
it !in allowedConnectionsLength && it in allowedConnectionsWithLocalServerLength -> {
|
||||
DefaultKTgBotAPIKSLog.w {
|
||||
"""
|
||||
Passed amount of allowed connections to server is $it and it exceeds default amount of
|
||||
connections $allowedConnectionsLength, but can be used with local bot api server. Make sure
|
||||
you are using local bot api url in your bot.
|
||||
""".trimIndent()
|
||||
}
|
||||
}
|
||||
it !in allowedConnectionsLength -> {
|
||||
throw IllegalArgumentException("Allowed connection for webhook must be in $allowedConnectionsLength range (but passed $it)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ val threadNameLength = 1 until 128
|
||||
val chatDescriptionLength = 0 until 256
|
||||
val inlineResultQueryIdLingth = 1 until 64
|
||||
val allowedConnectionsLength = 1 .. 100
|
||||
val allowedConnectionsWithLocalServerLength = 1 .. 100000
|
||||
|
||||
val invoiceTitleLimit = 1 until 32
|
||||
val invoiceDescriptionLimit = 1 until 256
|
||||
|
||||
@@ -3705,7 +3705,9 @@ public final class dev/inmo/tgbotapi/extensions/utils/updates/retrieving/LongPol
|
||||
public static synthetic fun longPolling$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;ILkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;IZZLjava/lang/Long;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||
public static synthetic fun longPolling$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/updateshandlers/UpdatesFilter;ILkotlinx/coroutines/CoroutineScope;ZZLjava/lang/Long;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||
public static final fun longPollingFlow (Ldev/inmo/tgbotapi/bot/RequestsExecutor;ILkotlin/jvm/functions/Function2;Ljava/util/List;ZZLjava/lang/Long;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun longPollingFlow (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Lkotlin/jvm/functions/Function2;ZZLjava/lang/Long;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static synthetic fun longPollingFlow$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;ILkotlin/jvm/functions/Function2;Ljava/util/List;ZZLjava/lang/Long;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static synthetic fun longPollingFlow$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Lkotlin/jvm/functions/Function2;ZZLjava/lang/Long;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
|
||||
public static final fun retrieveAccumulatedUpdates (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/updateshandlers/FlowsUpdatesFilter;ZZLkotlinx/coroutines/CoroutineScope;ZLjava/lang/Long;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
|
||||
public static final fun retrieveAccumulatedUpdates (Ldev/inmo/tgbotapi/bot/RequestsExecutor;ZZLkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;Ljava/util/List;ZLjava/lang/Long;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Job;
|
||||
public static synthetic fun retrieveAccumulatedUpdates$default (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/updateshandlers/FlowsUpdatesFilter;ZZLkotlinx/coroutines/CoroutineScope;ZLjava/lang/Long;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
|
||||
|
||||
import dev.inmo.kslog.common.logger
|
||||
import dev.inmo.micro_utils.coroutines.*
|
||||
import dev.inmo.tgbotapi.bot.RequestsExecutor
|
||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||
@@ -15,30 +14,36 @@ import dev.inmo.tgbotapi.types.update.*
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.BaseSentMessageUpdate
|
||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||
import dev.inmo.tgbotapi.updateshandlers.*
|
||||
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
|
||||
import dev.inmo.tgbotapi.utils.causedCancellationException
|
||||
import dev.inmo.tgbotapi.utils.isCausedByCancellation
|
||||
import dev.inmo.tgbotapi.utils.isCausedUnresolvedAddressException
|
||||
import dev.inmo.tgbotapi.utils.subscribeWithBotLogger
|
||||
import io.ktor.client.network.sockets.ConnectTimeoutException
|
||||
import io.ktor.client.plugins.HttpRequestTimeoutException
|
||||
import io.ktor.util.network.UnresolvedAddressException
|
||||
import io.ktor.utils.io.CancellationException
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
/**
|
||||
* @param mediaGroupsDebounceTimeMillis Will be used for calling of [updateHandlerWithMediaGroupsAdaptation]. Pass null
|
||||
* in case you wish to enable classic way of updates handling, but in that mode some media group messages can be
|
||||
* retrieved in different updates
|
||||
* Starts a long polling flow to receive updates continuously from the Telegram Bot API.
|
||||
*
|
||||
* This method retrieves updates from the bot, processes them, and emits them as a flow of `Update` objects.
|
||||
* It allows handling of updates with features like automatic webhook disabling, timeout exception skipping,
|
||||
* and media group handling with debounce time.
|
||||
*
|
||||
* @param exceptionsHandler Optional exception handler to manage exceptions that occur during the polling process.
|
||||
* @param autoDisableWebhooks Specifies whether to automatically disable existing webhooks before starting the long polling flow (default: `true`).
|
||||
* @param autoSkipTimeoutExceptions Defines if timeout-related exceptions should automatically be skipped during the polling (default: `true`).
|
||||
* @param mediaGroupsDebounceTimeMillis The debounce time in milliseconds for processing media group updates.
|
||||
* If set to `null`, media group handling is disabled (default: `1000L`).
|
||||
* @param getUpdatesRequestCreator A function that creates a `GetUpdates` request for retrieving updates.
|
||||
* This function accepts the identifier of the most recent update as an input and returns the new request.
|
||||
* @return A [Flow] of [Update] objects that represents the continuous stream of updates received.
|
||||
*/
|
||||
fun TelegramBot.longPollingFlow(
|
||||
timeoutSeconds: Seconds = 30,
|
||||
exceptionsHandler: (ExceptionHandler<Unit>)? = null,
|
||||
allowedUpdates: List<String>? = ALL_UPDATES_LIST,
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
autoSkipTimeoutExceptions: Boolean = true,
|
||||
mediaGroupsDebounceTimeMillis: Long? = 1000L,
|
||||
getUpdatesRequestCreator: (sinceUpdate: UpdateId?) -> GetUpdates
|
||||
): Flow<Update> = channelFlow {
|
||||
if (autoDisableWebhooks) {
|
||||
runCatchingLogging(logger = Log) {
|
||||
@@ -119,11 +124,7 @@ fun TelegramBot.longPollingFlow(
|
||||
while (isActive) {
|
||||
runCatchingLogging(logger = Log) {
|
||||
execute(
|
||||
GetUpdates(
|
||||
offset = lastUpdateIdentifier?.plus(1),
|
||||
timeout = timeoutSeconds,
|
||||
allowed_updates = allowedUpdates
|
||||
)
|
||||
getUpdatesRequestCreator(lastUpdateIdentifier ?.plus(1))
|
||||
).let { originalUpdates ->
|
||||
updatesHandler(originalUpdates)
|
||||
}
|
||||
@@ -148,6 +149,45 @@ fun TelegramBot.longPollingFlow(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates a long polling flow for receiving updates continuously from the Telegram Bot API.
|
||||
* This method provides a customized way to handle the retrieval of updates with options
|
||||
* to configure timeouts, update types, exception handling, and media group processing.
|
||||
*
|
||||
* @param timeoutSeconds The maximum time in seconds for the server to wait for available updates
|
||||
* before responding (default: `30`).
|
||||
* @param exceptionsHandler An optional exception handler for managing exceptions that occur during the
|
||||
* long polling process. If not provided, exceptions will pass through unhandled.
|
||||
* @param allowedUpdates A list of the update types to retrieve. By default, retrieves all possible
|
||||
* update types as defined in `ALL_UPDATES_LIST`.
|
||||
* @param autoDisableWebhooks Whether the current webhook should be disabled automatically before starting the
|
||||
* long polling flow (default: `true`).
|
||||
* @param autoSkipTimeoutExceptions Determines if timeout-related exceptions should be automatically skipped
|
||||
* during the polling process (default: `true`).
|
||||
* @param mediaGroupsDebounceTimeMillis The debounce time in milliseconds for processing updates containing
|
||||
* media groups. If set to `null`, media group handling is disabled (default: `1000L`).
|
||||
* @return A Flow that emits Update objects representing the updates fetched from the Telegram Bot API.
|
||||
*/
|
||||
fun TelegramBot.longPollingFlow(
|
||||
timeoutSeconds: Seconds = 30,
|
||||
exceptionsHandler: (ExceptionHandler<Unit>)? = null,
|
||||
allowedUpdates: List<String>? = ALL_UPDATES_LIST,
|
||||
autoDisableWebhooks: Boolean = true,
|
||||
autoSkipTimeoutExceptions: Boolean = true,
|
||||
mediaGroupsDebounceTimeMillis: Long? = 1000L,
|
||||
): Flow<Update> = longPollingFlow(
|
||||
exceptionsHandler = exceptionsHandler,
|
||||
autoDisableWebhooks = autoDisableWebhooks,
|
||||
autoSkipTimeoutExceptions = autoSkipTimeoutExceptions,
|
||||
mediaGroupsDebounceTimeMillis = mediaGroupsDebounceTimeMillis,
|
||||
) {
|
||||
GetUpdates(
|
||||
offset = it,
|
||||
timeout = timeoutSeconds,
|
||||
allowed_updates = allowedUpdates
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mediaGroupsDebounceTimeMillis Will be used for calling of [updateHandlerWithMediaGroupsAdaptation]. Pass null
|
||||
* in case you wish to enable classic way of updates handling, but in that mode some media group messages can be
|
||||
|
||||
Reference in New Issue
Block a user