mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2025-12-30 18:09:25 +00:00
Compare commits
5 Commits
b1931900e7
...
3.2.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 99f16e33a6 | |||
| e029b29f7f | |||
| c04f795fdd | |||
| b873898100 | |||
| 61ac9df5e3 |
@@ -1,6 +1,8 @@
|
|||||||
# TelegramBotAPI changelog
|
# TelegramBotAPI changelog
|
||||||
|
|
||||||
## 3.1.2
|
## 3.2.0
|
||||||
|
|
||||||
|
**Since this update, `RequestsExecutor#execute` may throw only `BotException`. In case you wish to handle some exceptions from `execute` you must catch `BotException` and handle its `cause`**
|
||||||
|
|
||||||
* `Versions`:
|
* `Versions`:
|
||||||
* `Serialization`: `1.4.0-RC` -> `1.4.0`
|
* `Serialization`: `1.4.0-RC` -> `1.4.0`
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ kotlin.incremental=true
|
|||||||
kotlin.incremental.js=true
|
kotlin.incremental.js=true
|
||||||
|
|
||||||
library_group=dev.inmo
|
library_group=dev.inmo
|
||||||
library_version=3.1.2
|
library_version=3.2.0
|
||||||
|
|||||||
@@ -19,5 +19,5 @@ suspend fun BehaviourContext.waitDeepLinks(
|
|||||||
.requireSingleCommand()
|
.requireSingleCommand()
|
||||||
.requireCommandAtStart()
|
.requireCommandAtStart()
|
||||||
.flattenCommandsWithParams().mapNotNull {
|
.flattenCommandsWithParams().mapNotNull {
|
||||||
it.first to (it.second.second.singleOrNull() ?.regularTextSourceOrNull() ?.source ?: return@mapNotNull null)
|
it.first to (it.second.second.singleOrNull() ?.regularTextSourceOrNull() ?.source ?.removePrefix(" ") ?: return@mapNotNull null)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,11 @@ import dev.inmo.tgbotapi.types.message.content.TextContent
|
|||||||
import dev.inmo.tgbotapi.types.message.content.TextMessage
|
import dev.inmo.tgbotapi.types.message.content.TextMessage
|
||||||
import dev.inmo.tgbotapi.types.message.textsources.RegularTextSource
|
import dev.inmo.tgbotapi.types.message.textsources.RegularTextSource
|
||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
|
import io.ktor.http.decodeURLQueryComponent
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
|
|
||||||
|
private val startRegex = Regex("start")
|
||||||
suspend fun <BC : BehaviourContext> BC.onDeepLink(
|
suspend fun <BC : BehaviourContext> BC.onDeepLink(
|
||||||
initialFilter: SimpleFilter<Pair<TextMessage, String>>? = null,
|
initialFilter: SimpleFilter<Pair<TextMessage, String>>? = null,
|
||||||
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, Pair<TextMessage, String>, Update> = { (message, _), update -> MessageFilterByChat(this, message, update) },
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, Pair<TextMessage, String>, Update> = { (message, _), update -> MessageFilterByChat(this, message, update) },
|
||||||
@@ -36,6 +38,11 @@ suspend fun <BC : BehaviourContext> BC.onDeepLink(
|
|||||||
scenarioReceiver,
|
scenarioReceiver,
|
||||||
) {
|
) {
|
||||||
(it.messageUpdateOrNull()) ?.data ?.commonMessageOrNull() ?.withContentOrNull<TextContent>() ?.let { message ->
|
(it.messageUpdateOrNull()) ?.data ?.commonMessageOrNull() ?.withContentOrNull<TextContent>() ?.let { message ->
|
||||||
message to message.content.textSources[1].source
|
message to message.content.textSources[1].source.removePrefix(" ").decodeURLQueryComponent()
|
||||||
} ?.let(::listOfNotNull)
|
} ?.let(::listOfNotNull)
|
||||||
|
}.also {
|
||||||
|
triggersHolder.handleableCommandsHolder.registerHandleable(startRegex)
|
||||||
|
it.invokeOnCompletion {
|
||||||
|
this@onDeepLink.launchSafelyWithoutExceptions { triggersHolder.handleableCommandsHolder.unregisterHandleable(startRegex) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,13 +35,18 @@ fun newRequestException(
|
|||||||
}
|
}
|
||||||
} ?: CommonRequestException(response, plainAnswer, message, cause)
|
} ?: CommonRequestException(response, plainAnswer, message, cause)
|
||||||
|
|
||||||
|
sealed class BotException(message: String = "Something went wrong", cause: Throwable? = null) : IOException(message, cause)
|
||||||
|
|
||||||
|
class CommonBotException(message: String = "Something went wrong", cause: Throwable? = null) : BotException(message, cause)
|
||||||
|
|
||||||
sealed class RequestException constructor(
|
sealed class RequestException constructor(
|
||||||
val response: Response,
|
val response: Response,
|
||||||
val plainAnswer: String,
|
val plainAnswer: String,
|
||||||
message: String? = null,
|
message: String? = null,
|
||||||
override val cause: Throwable? = null
|
cause: Throwable? = null
|
||||||
) : IOException(
|
) : BotException(
|
||||||
message ?: "Something went wrong"
|
message ?: "Something went wrong",
|
||||||
|
cause
|
||||||
)
|
)
|
||||||
|
|
||||||
class CommonRequestException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
|
class CommonRequestException(response: Response, plainAnswer: String, message: String?, cause: Throwable?) :
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
package dev.inmo.tgbotapi.bot.ktor
|
package dev.inmo.tgbotapi.bot.ktor
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.coroutines.runCatchingSafely
|
||||||
import dev.inmo.micro_utils.coroutines.safely
|
import dev.inmo.micro_utils.coroutines.safely
|
||||||
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
|
import dev.inmo.tgbotapi.bot.exceptions.*
|
||||||
import dev.inmo.tgbotapi.bot.ktor.base.*
|
import dev.inmo.tgbotapi.bot.ktor.base.*
|
||||||
import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter
|
import dev.inmo.tgbotapi.bot.settings.limiters.ExceptionsOnlyLimiter
|
||||||
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
|
import dev.inmo.tgbotapi.bot.settings.limiters.RequestLimiter
|
||||||
@@ -48,12 +49,36 @@ class KtorRequestsExecutor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun <T : Any> execute(request: Request<T>): T {
|
override suspend fun <T : Any> execute(request: Request<T>): T {
|
||||||
return runCatching {
|
return runCatchingSafely {
|
||||||
safely(
|
pipelineStepsHolder.onBeforeSearchCallFactory(request, callsFactories)
|
||||||
{ e ->
|
requestsLimiter.limit {
|
||||||
pipelineStepsHolder.onRequestException(request, e) ?.let { return@safely it }
|
var result: T? = null
|
||||||
|
lateinit var factoryHandledRequest: KtorCallFactory
|
||||||
|
for (potentialFactory in callsFactories) {
|
||||||
|
pipelineStepsHolder.onBeforeCallFactoryMakeCall(request, potentialFactory)
|
||||||
|
result = potentialFactory.makeCall(
|
||||||
|
client,
|
||||||
|
telegramAPIUrlsKeeper,
|
||||||
|
request,
|
||||||
|
jsonFormatter
|
||||||
|
)
|
||||||
|
result = pipelineStepsHolder.onAfterCallFactoryMakeCall(result, request, potentialFactory)
|
||||||
|
if (result != null) {
|
||||||
|
factoryHandledRequest = potentialFactory
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw if (e is ClientRequestException) {
|
result ?.let {
|
||||||
|
pipelineStepsHolder.onRequestResultPresented(it, request, factoryHandledRequest, callsFactories)
|
||||||
|
} ?: pipelineStepsHolder.onRequestResultAbsent(request, callsFactories) ?: error("Can't execute request: $request")
|
||||||
|
}
|
||||||
|
}.let {
|
||||||
|
val result = it.exceptionOrNull() ?.let { e ->
|
||||||
|
pipelineStepsHolder.onRequestException(request, e) ?.let { return@let it }
|
||||||
|
|
||||||
|
if (e is ClientRequestException) {
|
||||||
|
val exceptionResult = runCatchingSafely {
|
||||||
val content = e.response.bodyAsText()
|
val content = e.response.bodyAsText()
|
||||||
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
|
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
|
||||||
newRequestException(
|
newRequestException(
|
||||||
@@ -61,38 +86,15 @@ class KtorRequestsExecutor(
|
|||||||
content,
|
content,
|
||||||
"Can't get result object from $content"
|
"Can't get result object from $content"
|
||||||
)
|
)
|
||||||
} else {
|
|
||||||
e
|
|
||||||
}
|
}
|
||||||
|
exceptionResult.exceptionOrNull() ?.let {
|
||||||
|
CommonBotException(cause = e)
|
||||||
|
} ?: exceptionResult.getOrThrow()
|
||||||
|
} else {
|
||||||
|
CommonBotException(cause = e)
|
||||||
}
|
}
|
||||||
) {
|
} ?.let { Result.failure(it) } ?: it
|
||||||
pipelineStepsHolder.onBeforeSearchCallFactory(request, callsFactories)
|
pipelineStepsHolder.onRequestReturnResult(result, request, callsFactories)
|
||||||
requestsLimiter.limit {
|
|
||||||
var result: T? = null
|
|
||||||
lateinit var factoryHandledRequest: KtorCallFactory
|
|
||||||
for (potentialFactory in callsFactories) {
|
|
||||||
pipelineStepsHolder.onBeforeCallFactoryMakeCall(request, potentialFactory)
|
|
||||||
result = potentialFactory.makeCall(
|
|
||||||
client,
|
|
||||||
telegramAPIUrlsKeeper,
|
|
||||||
request,
|
|
||||||
jsonFormatter
|
|
||||||
)
|
|
||||||
result = pipelineStepsHolder.onAfterCallFactoryMakeCall(result, request, potentialFactory)
|
|
||||||
if (result != null) {
|
|
||||||
factoryHandledRequest = potentialFactory
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result ?.let {
|
|
||||||
pipelineStepsHolder.onRequestResultPresented(it, request, factoryHandledRequest, callsFactories)
|
|
||||||
} ?: pipelineStepsHolder.onRequestResultAbsent(request, callsFactories) ?: error("Can't execute request: $request")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.let {
|
|
||||||
pipelineStepsHolder.onRequestReturnResult(it, request, callsFactories)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import dev.inmo.tgbotapi.types.*
|
|||||||
import dev.inmo.tgbotapi.types.chat.*
|
import dev.inmo.tgbotapi.types.chat.*
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
import dev.inmo.tgbotapi.types.message.abstracts.Message
|
||||||
import dev.inmo.tgbotapi.types.message.textsources.link
|
import dev.inmo.tgbotapi.types.message.textsources.link
|
||||||
|
import io.ktor.http.encodeURLQueryComponent
|
||||||
|
|
||||||
|
|
||||||
fun makeUsernameLink(username: String) = "$internalLinkBeginning/$username"
|
fun makeUsernameLink(username: String) = "$internalLinkBeginning/$username"
|
||||||
@@ -17,11 +18,11 @@ inline val Username.deepLinkPrefix
|
|||||||
inline val Username.startattachPrefix
|
inline val Username.startattachPrefix
|
||||||
get() = makeUsernameStartattachPrefix(usernameWithoutAt)
|
get() = makeUsernameStartattachPrefix(usernameWithoutAt)
|
||||||
inline fun makeLink(username: Username) = username.link
|
inline fun makeLink(username: Username) = username.link
|
||||||
inline fun makeTelegramDeepLink(username: String, startParameter: String) = "${makeUsernameDeepLinkPrefix(username)}$startParameter"
|
inline fun makeTelegramDeepLink(username: String, startParameter: String) = "${makeUsernameDeepLinkPrefix(username)}$startParameter".encodeURLQueryComponent()
|
||||||
inline fun makeTelegramStartattach(username: String, data: String? = null) = makeUsernameStartattachLink(username, data)
|
inline fun makeTelegramStartattach(username: String, data: String? = null) = makeUsernameStartattachLink(username, data)
|
||||||
inline fun makeDeepLink(username: Username, startParameter: String) = "${username.deepLinkPrefix}$startParameter"
|
inline fun makeDeepLink(username: Username, startParameter: String) = makeTelegramDeepLink(username.usernameWithoutAt, startParameter)
|
||||||
inline fun makeTelegramDeepLink(username: Username, startParameter: String) = makeDeepLink(username, startParameter)
|
inline fun makeTelegramDeepLink(username: Username, startParameter: String) = makeDeepLink(username, startParameter)
|
||||||
inline fun makeTelegramStartattach(username: Username, data: String? = null) = makeTelegramStartattach(username.username, data)
|
inline fun makeTelegramStartattach(username: Username, data: String? = null) = makeTelegramStartattach(username.usernameWithoutAt, data)
|
||||||
|
|
||||||
fun makeLinkToMessage(
|
fun makeLinkToMessage(
|
||||||
username: String,
|
username: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user