mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2026-01-01 19:09:20 +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`
|
* `KSP`: `2.2.20-2.0.4` -> `2.3.2`
|
||||||
* `MicroUtils`: `0.26.6` -> `0.26.8`
|
* `MicroUtils`: `0.26.6` -> `0.26.8`
|
||||||
* `KSLog`: `1.5.1` -> `1.5.2`
|
* `KSLog`: `1.5.1` -> `1.5.2`
|
||||||
|
* `Core`:
|
||||||
|
* Allow to use `SetWebhook` with `maxAllowedConnections` up to `100000`
|
||||||
* `KSP`:
|
* `KSP`:
|
||||||
* Fixed annotation property access for KSP2 compatibility using `withNoSuchElementWorkaround`
|
* Fixed annotation property access for KSP2 compatibility using `withNoSuchElementWorkaround`
|
||||||
* Removed `ksp.useKSP2=false` workaround from `gradle.properties` (KSP2 is now properly supported)
|
* Removed `ksp.useKSP2=false` workaround from `gradle.properties` (KSP2 is now properly supported)
|
||||||
* `Utils`:
|
* `Utils`:
|
||||||
* Regenerated class casts extensions
|
* Regenerated class casts extensions
|
||||||
|
* Allow to use custom `GetUpdates` in `longPollingFlow`
|
||||||
|
|
||||||
## 30.0.1
|
## 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 yShiftField Ljava/lang/String;
|
||||||
public static final field yearField Ljava/lang/String;
|
public static final field yearField Ljava/lang/String;
|
||||||
public static final fun getAllowedConnectionsLength ()Lkotlin/ranges/IntRange;
|
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 getBasketballAndFootballDiceResultLimit ()Lkotlin/ranges/IntRange;
|
||||||
public static final fun getBotCommandDescriptionLimit ()Lkotlin/ranges/IntRange;
|
public static final fun getBotCommandDescriptionLimit ()Lkotlin/ranges/IntRange;
|
||||||
public static final fun getBotCommandLengthLimit ()Lkotlin/ranges/IntRange;
|
public static final fun getBotCommandLengthLimit ()Lkotlin/ranges/IntRange;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package dev.inmo.tgbotapi.requests.webhook
|
package dev.inmo.tgbotapi.requests.webhook
|
||||||
|
|
||||||
|
import dev.inmo.kslog.common.w
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||||
import dev.inmo.tgbotapi.requests.send.media.base.DataRequest
|
import dev.inmo.tgbotapi.requests.send.media.base.DataRequest
|
||||||
import dev.inmo.tgbotapi.requests.send.media.base.MultipartRequestImpl
|
import dev.inmo.tgbotapi.requests.send.media.base.MultipartRequestImpl
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.builtins.serializer
|
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
|
* Represents a request for setting a webhook in Telegram's Bot API. A webhook allows Telegram to send updates directly
|
||||||
* for the bot, we will send an HTTPS POST request to the specified url, containing a JSON-serialized Update.
|
* 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],
|
* @constructor Creates a data class holding configuration options for the webhook.
|
||||||
* e.g. https://www.example.com/<token>. Since nobody else knows your bot's token, you can be pretty sure it's us.
|
*
|
||||||
|
* @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
|
@ConsistentCopyVisibility
|
||||||
@Serializable
|
@Serializable
|
||||||
@@ -150,8 +163,19 @@ data class SetWebhook internal constructor(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
maxAllowedConnections ?.let {
|
maxAllowedConnections ?.let {
|
||||||
if (it !in allowedConnectionsLength) {
|
when {
|
||||||
throw IllegalArgumentException("Allowed connection for webhook must be in $allowedConnectionsLength range (but passed $it)")
|
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 chatDescriptionLength = 0 until 256
|
||||||
val inlineResultQueryIdLingth = 1 until 64
|
val inlineResultQueryIdLingth = 1 until 64
|
||||||
val allowedConnectionsLength = 1 .. 100
|
val allowedConnectionsLength = 1 .. 100
|
||||||
|
val allowedConnectionsWithLocalServerLength = 1 .. 100000
|
||||||
|
|
||||||
val invoiceTitleLimit = 1 until 32
|
val invoiceTitleLimit = 1 until 32
|
||||||
val invoiceDescriptionLimit = 1 until 256
|
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;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 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;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;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;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 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;
|
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
|
package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
|
||||||
|
|
||||||
import dev.inmo.kslog.common.logger
|
|
||||||
import dev.inmo.micro_utils.coroutines.*
|
import dev.inmo.micro_utils.coroutines.*
|
||||||
import dev.inmo.tgbotapi.bot.RequestsExecutor
|
import dev.inmo.tgbotapi.bot.RequestsExecutor
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
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.BaseSentMessageUpdate
|
||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
import dev.inmo.tgbotapi.updateshandlers.*
|
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.isCausedUnresolvedAddressException
|
||||||
import dev.inmo.tgbotapi.utils.subscribeWithBotLogger
|
import dev.inmo.tgbotapi.utils.subscribeWithBotLogger
|
||||||
import io.ktor.client.network.sockets.ConnectTimeoutException
|
import io.ktor.client.network.sockets.ConnectTimeoutException
|
||||||
import io.ktor.client.plugins.HttpRequestTimeoutException
|
import io.ktor.client.plugins.HttpRequestTimeoutException
|
||||||
import io.ktor.util.network.UnresolvedAddressException
|
|
||||||
import io.ktor.utils.io.CancellationException
|
import io.ktor.utils.io.CancellationException
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mediaGroupsDebounceTimeMillis Will be used for calling of [updateHandlerWithMediaGroupsAdaptation]. Pass null
|
* Starts a long polling flow to receive updates continuously from the Telegram Bot API.
|
||||||
* 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
|
* 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(
|
fun TelegramBot.longPollingFlow(
|
||||||
timeoutSeconds: Seconds = 30,
|
|
||||||
exceptionsHandler: (ExceptionHandler<Unit>)? = null,
|
exceptionsHandler: (ExceptionHandler<Unit>)? = null,
|
||||||
allowedUpdates: List<String>? = ALL_UPDATES_LIST,
|
|
||||||
autoDisableWebhooks: Boolean = true,
|
autoDisableWebhooks: Boolean = true,
|
||||||
autoSkipTimeoutExceptions: Boolean = true,
|
autoSkipTimeoutExceptions: Boolean = true,
|
||||||
mediaGroupsDebounceTimeMillis: Long? = 1000L,
|
mediaGroupsDebounceTimeMillis: Long? = 1000L,
|
||||||
|
getUpdatesRequestCreator: (sinceUpdate: UpdateId?) -> GetUpdates
|
||||||
): Flow<Update> = channelFlow {
|
): Flow<Update> = channelFlow {
|
||||||
if (autoDisableWebhooks) {
|
if (autoDisableWebhooks) {
|
||||||
runCatchingLogging(logger = Log) {
|
runCatchingLogging(logger = Log) {
|
||||||
@@ -119,11 +124,7 @@ fun TelegramBot.longPollingFlow(
|
|||||||
while (isActive) {
|
while (isActive) {
|
||||||
runCatchingLogging(logger = Log) {
|
runCatchingLogging(logger = Log) {
|
||||||
execute(
|
execute(
|
||||||
GetUpdates(
|
getUpdatesRequestCreator(lastUpdateIdentifier ?.plus(1))
|
||||||
offset = lastUpdateIdentifier?.plus(1),
|
|
||||||
timeout = timeoutSeconds,
|
|
||||||
allowed_updates = allowedUpdates
|
|
||||||
)
|
|
||||||
).let { originalUpdates ->
|
).let { originalUpdates ->
|
||||||
updatesHandler(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
|
* @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
|
* 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