1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-09-03 15:19:30 +00:00

WAT A HUGE REFACTOR

This commit is contained in:
2025-07-12 15:42:48 +06:00
parent 586a61157d
commit 9e4d7dd9f9
292 changed files with 1337 additions and 509 deletions

View File

@@ -15,7 +15,7 @@ fun <T> aggregateFlows(
val sharedFlow = MutableSharedFlow<T>(extraBufferCapacity = internalBufferSize)
flows.forEach {
it.onEach {
safely { sharedFlow.emit(it) }
runCatching { sharedFlow.emit(it) }
}.launchIn(withScope)
}
return sharedFlow

View File

@@ -5,11 +5,12 @@ import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import io.ktor.client.HttpClient
import io.ktor.client.request.get
import io.ktor.client.statement.readBytes
import io.ktor.client.statement.readRawBytes
suspend fun HttpClient.loadFile(
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
filePath: String
) = get("${telegramAPIUrlsKeeper.fileBaseUrl}/$filePath").readBytes()
) = get("${telegramAPIUrlsKeeper.fileBaseUrl}/$filePath").readRawBytes()
suspend fun HttpClient.loadFile(
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,

View File

@@ -1,3 +1,5 @@
@file:Suppress("unused")
package dev.inmo.tgbotapi.extensions.utils.formatting
import dev.inmo.tgbotapi.types.*
@@ -25,20 +27,20 @@ inline val Username.usernameLink
val IdChatIdentifier.chatLink: String
get() = makeChatLink(chatId, threadId)
fun ChatId.link(threadId: MessageThreadId?) = makeChatLink(chatId, threadId)
inline fun Username.link(threadId: MessageThreadId?) = makeUsernameLink(withoutAt, threadId)
fun Username.link(threadId: MessageThreadId?) = makeUsernameLink(withoutAt, threadId)
inline val Username.deepLinkPrefix
get() = makeUsernameDeepLinkPrefix(withoutAt)
inline val Username.startattachPrefix
get() = makeUsernameStartattachPrefix(withoutAt)
inline fun makeLink(username: Username, threadId: MessageThreadId? = null) = username.link(threadId)
inline fun makeTelegramDeepLink(username: String, startParameter: String) = "${makeUsernameDeepLinkPrefix(username)}$startParameter".encodeURLQueryComponent()
inline fun makeInternalTgDeepLink(username: String, startParameter: String) = "${makeInternalTgUsernameDeepLinkPrefix(username)}$startParameter".encodeURLQueryComponent()
inline fun makeInternalTgDeepLink(username: Username, startParameter: String) =
fun makeLink(username: Username, threadId: MessageThreadId? = null) = username.link(threadId)
fun makeTelegramDeepLink(username: String, startParameter: String) = "${makeUsernameDeepLinkPrefix(username)}$startParameter".encodeURLQueryComponent()
fun makeInternalTgDeepLink(username: String, startParameter: String) = "${makeInternalTgUsernameDeepLinkPrefix(username)}$startParameter".encodeURLQueryComponent()
fun makeInternalTgDeepLink(username: Username, startParameter: String) =
makeInternalTgDeepLink(username.withoutAt, startParameter)
inline fun makeTelegramStartattach(username: String, data: String? = null) = makeUsernameStartattachLink(username, data)
inline fun makeDeepLink(username: Username, startParameter: String) = makeTelegramDeepLink(username.withoutAt, startParameter)
inline fun makeTelegramDeepLink(username: Username, startParameter: String) = makeDeepLink(username, startParameter)
inline fun makeTelegramStartattach(username: Username, data: String? = null) = makeTelegramStartattach(username.withoutAt, data)
fun makeTelegramStartattach(username: String, data: String? = null) = makeUsernameStartattachLink(username, data)
fun makeDeepLink(username: Username, startParameter: String) = makeTelegramDeepLink(username.withoutAt, startParameter)
fun makeTelegramDeepLink(username: Username, startParameter: String) = makeDeepLink(username, startParameter)
fun makeTelegramStartattach(username: Username, data: String? = null) = makeTelegramStartattach(username.withoutAt, data)
private val linkIdRedundantPartRegex = Regex("^-100")
private val usernameBeginSymbolRegex = Regex("^@")

View File

@@ -7,6 +7,6 @@ import dev.inmo.tgbotapi.types.message.content.MessageContent
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filterIsInstance
inline fun Flow<AccessibleMessage>.businessMessages() = filterIsInstance<BusinessContentMessage<*>>()
fun Flow<AccessibleMessage>.businessMessages() = filterIsInstance<BusinessContentMessage<*>>()
inline fun <reified T : MessageContent> Flow<ContentMessage<T>>.businessMessagesWithType() = filterIsInstance<BusinessContentMessage<T>>()
inline fun Flow<ContentMessage<*>>.allBusinessMessages() = businessMessagesWithType()
fun Flow<ContentMessage<*>>.allBusinessMessages() = businessMessagesWithType()

View File

@@ -39,13 +39,10 @@ inline fun <reified T: MessageContent> Flow<BaseSentMessageUpdate>.filterContent
inline fun <reified T: MessageContent> FlowsUpdatesFilter.filterContentMessages(
scopeToIncludeChannels: CoroutineScope? = null
): Flow<ContentMessage<T>> {
return (scopeToIncludeChannels ?.let { scope ->
aggregateFlows(
scope,
messagesFlow,
channelPostsFlow
)
} ?: messagesFlow).filterContentMessages()
return merge(
messagesFlow,
channelPostsFlow
).filterContentMessages()
}
fun FlowsUpdatesFilter.sentMessages(

View File

@@ -1,5 +1,7 @@
package dev.inmo.tgbotapi.extensions.utils.shortcuts
import dev.inmo.micro_utils.coroutines.replaceIfFailure
import dev.inmo.micro_utils.coroutines.runCatchingLogging
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.RequestsExecutor
import dev.inmo.tgbotapi.requests.abstracts.Request
@@ -10,9 +12,9 @@ fun <T: Any> RequestsExecutor.executeAsync(
request: Request<T>,
scope: CoroutineScope
): Deferred<T> = scope.async {
safely {
runCatchingLogging(logger = Log) {
execute(request)
}
}.getOrThrow()
}
suspend fun <T: Any> RequestsExecutor.executeAsync(
@@ -28,16 +30,14 @@ suspend fun <T: Any> RequestsExecutor.executeUnsafe(
var leftRetries = retries
val exceptions = onAllFailed ?.let { mutableListOf<Throwable>() }
do {
return safely (
{
leftRetries--
delay(retriesDelay)
exceptions ?.add(it)
null
}
) {
return runCatching {
execute(request)
} ?: continue
}.replaceIfFailure {
leftRetries--
delay(retriesDelay)
exceptions?.add(it)
null
}.getOrThrow() ?: continue
} while(leftRetries >= 0)
onAllFailed ?.invoke(exceptions ?.toTypedArray() ?: emptyArray())
return null

View File

@@ -69,7 +69,7 @@ inline fun InlineKeyboardMarkup.modified(
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/
inline fun InlineKeyboardRowBuilder.payButton(
fun InlineKeyboardRowBuilder.payButton(
text: String
) = add(PayInlineKeyboardButton(text))
@@ -79,7 +79,7 @@ inline fun InlineKeyboardRowBuilder.payButton(
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/
inline fun InlineKeyboardRowBuilder.dataButton(
fun InlineKeyboardRowBuilder.dataButton(
text: String,
data: String
) = add(CallbackDataInlineKeyboardButton(text, data))
@@ -90,7 +90,7 @@ inline fun InlineKeyboardRowBuilder.dataButton(
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/
inline fun InlineKeyboardRowBuilder.gameButton(
fun InlineKeyboardRowBuilder.gameButton(
text: String
) = add(CallbackGameInlineKeyboardButton(text))
@@ -100,7 +100,7 @@ inline fun InlineKeyboardRowBuilder.gameButton(
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/
inline fun InlineKeyboardRowBuilder.loginButton(
fun InlineKeyboardRowBuilder.loginButton(
text: String,
loginUrl: LoginURL
) = add(LoginURLInlineKeyboardButton(text, loginUrl))
@@ -111,7 +111,7 @@ inline fun InlineKeyboardRowBuilder.loginButton(
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/
inline fun InlineKeyboardRowBuilder.copyTextButton(
fun InlineKeyboardRowBuilder.copyTextButton(
text: String,
data: CopyTextButtonData
) = add(CopyTextButton(text, data))
@@ -122,7 +122,7 @@ inline fun InlineKeyboardRowBuilder.copyTextButton(
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/
inline fun InlineKeyboardRowBuilder.copyTextButton(
fun InlineKeyboardRowBuilder.copyTextButton(
text: String,
data: String
) = copyTextButton(text, CopyTextButtonData(data))
@@ -133,7 +133,7 @@ inline fun InlineKeyboardRowBuilder.copyTextButton(
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/
inline fun InlineKeyboardRowBuilder.inlineQueryInCurrentChatButton(
fun InlineKeyboardRowBuilder.inlineQueryInCurrentChatButton(
text: String,
data: String
) = add(SwitchInlineQueryCurrentChatInlineKeyboardButton(text, data))
@@ -144,7 +144,7 @@ inline fun InlineKeyboardRowBuilder.inlineQueryInCurrentChatButton(
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/
inline fun InlineKeyboardRowBuilder.inlineQueryInChosenChatButton(
fun InlineKeyboardRowBuilder.inlineQueryInChosenChatButton(
text: String,
parameters: SwitchInlineQueryChosenChat
) = add(SwitchInlineQueryChosenChatInlineKeyboardButton(text, parameters))
@@ -155,7 +155,7 @@ inline fun InlineKeyboardRowBuilder.inlineQueryInChosenChatButton(
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/
inline fun InlineKeyboardRowBuilder.inlineQueryInChosenChatButton(
fun InlineKeyboardRowBuilder.inlineQueryInChosenChatButton(
text: String,
query: String? = null,
allowUsers: Boolean = false,
@@ -172,7 +172,7 @@ inline fun InlineKeyboardRowBuilder.inlineQueryInChosenChatButton(
allowChannels = allowChannels
)
)
inline fun InlineKeyboardRowBuilder.inlineQueryInAnyChosenChatButton(
fun InlineKeyboardRowBuilder.inlineQueryInAnyChosenChatButton(
text: String,
query: String? = null,
) = inlineQueryInChosenChatButton(text, query, allowUsers = true, allowBots = true, allowGroups = true, allowChannels = true)
@@ -183,7 +183,7 @@ inline fun InlineKeyboardRowBuilder.inlineQueryInAnyChosenChatButton(
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/
inline fun InlineKeyboardRowBuilder.inlineQueryButton(
fun InlineKeyboardRowBuilder.inlineQueryButton(
text: String,
data: String
) = add(SwitchInlineQueryInlineKeyboardButton(text, data))
@@ -194,7 +194,7 @@ inline fun InlineKeyboardRowBuilder.inlineQueryButton(
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/
inline fun InlineKeyboardRowBuilder.urlButton(
fun InlineKeyboardRowBuilder.urlButton(
text: String,
url: String
) = add(URLInlineKeyboardButton(text, url))
@@ -205,7 +205,7 @@ inline fun InlineKeyboardRowBuilder.urlButton(
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/
inline fun InlineKeyboardRowBuilder.webAppButton(
fun InlineKeyboardRowBuilder.webAppButton(
text: String,
webApp: WebAppInfo
) = add(WebAppInlineKeyboardButton(text, webApp))
@@ -216,7 +216,7 @@ inline fun InlineKeyboardRowBuilder.webAppButton(
* @see inlineKeyboard
* @see InlineKeyboardBuilder.row
*/
inline fun InlineKeyboardRowBuilder.webAppButton(
fun InlineKeyboardRowBuilder.webAppButton(
text: String,
url: String
) = webAppButton(text, WebAppInfo(url))

View File

@@ -1,3 +1,5 @@
@file:Suppress("unused", "RemoveExplicitTypeArguments")
package dev.inmo.tgbotapi.extensions.utils.types.buttons
import dev.inmo.tgbotapi.types.buttons.*
@@ -75,7 +77,7 @@ inline fun flatReplyKeyboard(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.simpleButton(
fun ReplyKeyboardRowBuilder.simpleButton(
text: String
) = add(SimpleKeyboardButton(text))
@@ -85,7 +87,7 @@ inline fun ReplyKeyboardRowBuilder.simpleButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestContactButton(
fun ReplyKeyboardRowBuilder.requestContactButton(
text: String
) = add(RequestContactKeyboardButton(text))
@@ -95,7 +97,7 @@ inline fun ReplyKeyboardRowBuilder.requestContactButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestLocationButton(
fun ReplyKeyboardRowBuilder.requestLocationButton(
text: String
) = add(RequestLocationKeyboardButton(text))
@@ -105,7 +107,7 @@ inline fun ReplyKeyboardRowBuilder.requestLocationButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestPollButton(
fun ReplyKeyboardRowBuilder.requestPollButton(
text: String,
pollType: KeyboardButtonPollType
) = add(RequestPollKeyboardButton(text, pollType))
@@ -116,7 +118,7 @@ inline fun ReplyKeyboardRowBuilder.requestPollButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.webAppButton(
fun ReplyKeyboardRowBuilder.webAppButton(
text: String,
webApp: WebAppInfo
) = add(WebAppKeyboardButton(text, webApp))
@@ -127,7 +129,7 @@ inline fun ReplyKeyboardRowBuilder.webAppButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.webAppButton(
fun ReplyKeyboardRowBuilder.webAppButton(
text: String,
url: String
) = webAppButton(text, WebAppInfo(url))
@@ -139,7 +141,7 @@ inline fun ReplyKeyboardRowBuilder.webAppButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestUsersButton(
fun ReplyKeyboardRowBuilder.requestUsersButton(
text: String,
requestUser: KeyboardButtonRequestUsers
) = add(
@@ -155,7 +157,7 @@ inline fun ReplyKeyboardRowBuilder.requestUsersButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestBotsButton(
fun ReplyKeyboardRowBuilder.requestBotsButton(
text: String,
requestId: RequestId,
maxCount: Int = keyboardButtonRequestUserLimit.first,
@@ -179,7 +181,7 @@ inline fun ReplyKeyboardRowBuilder.requestBotsButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestBotButton(
fun ReplyKeyboardRowBuilder.requestBotButton(
text: String,
requestId: RequestId,
requestName: Boolean? = null,
@@ -200,7 +202,7 @@ inline fun ReplyKeyboardRowBuilder.requestBotButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestUsersButton(
fun ReplyKeyboardRowBuilder.requestUsersButton(
text: String,
requestId: RequestId,
premiumUser: Boolean? = null,
@@ -226,7 +228,7 @@ inline fun ReplyKeyboardRowBuilder.requestUsersButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestUserButton(
fun ReplyKeyboardRowBuilder.requestUserButton(
text: String,
requestId: RequestId,
premiumUser: Boolean? = null,
@@ -249,7 +251,7 @@ inline fun ReplyKeyboardRowBuilder.requestUserButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestUsersOrBotsButton(
fun ReplyKeyboardRowBuilder.requestUsersOrBotsButton(
text: String,
requestId: RequestId,
premiumUser: Boolean? = null,
@@ -275,7 +277,7 @@ inline fun ReplyKeyboardRowBuilder.requestUsersOrBotsButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestUserOrBotButton(
fun ReplyKeyboardRowBuilder.requestUserOrBotButton(
text: String,
requestId: RequestId,
requestName: Boolean? = null,
@@ -297,7 +299,7 @@ inline fun ReplyKeyboardRowBuilder.requestUserOrBotButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestChatButton(
fun ReplyKeyboardRowBuilder.requestChatButton(
text: String,
requestChat: KeyboardButtonRequestChat
) = add(
@@ -313,7 +315,7 @@ inline fun ReplyKeyboardRowBuilder.requestChatButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestChatButton(
fun ReplyKeyboardRowBuilder.requestChatButton(
text: String,
requestId: RequestId,
isChannel: Boolean? = null,
@@ -349,7 +351,7 @@ inline fun ReplyKeyboardRowBuilder.requestChatButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestChannelButton(
fun ReplyKeyboardRowBuilder.requestChannelButton(
text: String,
requestId: RequestId,
isPublic: Boolean? = null,
@@ -381,7 +383,7 @@ inline fun ReplyKeyboardRowBuilder.requestChannelButton(
* @see replyKeyboard
* @see ReplyKeyboardBuilder.row
*/
inline fun ReplyKeyboardRowBuilder.requestGroupButton(
fun ReplyKeyboardRowBuilder.requestGroupButton(
text: String,
requestId: RequestId,
isForum: Boolean? = null,

View File

@@ -15,6 +15,7 @@ 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.subscribeWithBotLogger
import io.ktor.client.plugins.HttpRequestTimeoutException
import io.ktor.utils.io.CancellationException
import kotlinx.coroutines.*
@@ -155,15 +156,14 @@ fun TelegramBot.startGettingOfUpdatesByLongPolling(
updatesReceiver: UpdateReceiver<Update>
): Job = longPollingFlow(
timeoutSeconds = timeoutSeconds,
exceptionsHandler = exceptionsHandler,
exceptionsHandler = exceptionsHandler ?: defaultSafelyExceptionHandler,
allowedUpdates = allowedUpdates,
autoDisableWebhooks = autoDisableWebhooks,
autoSkipTimeoutExceptions = autoSkipTimeoutExceptions,
mediaGroupsDebounceTimeMillis = mediaGroupsDebounceTimeMillis
).subscribeSafely(
scope,
exceptionsHandler ?: defaultSafelyExceptionHandler,
updatesReceiver
).subscribeWithBotLogger(
scope = scope,
block = updatesReceiver
)
/**
@@ -219,8 +219,8 @@ fun TelegramBot.retrieveAccumulatedUpdates(
allowedUpdates,
autoDisableWebhooks,
mediaGroupsDebounceTimeMillis
).subscribeSafelyWithoutExceptions(
scope.LinkedSupervisorScope()
).subscribeWithBotLogger(
scope.LinkedSupervisorScope(),
) {
updatesReceiver(it)
}

View File

@@ -2,7 +2,6 @@ package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
import dev.inmo.kslog.common.KSLog
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.utils.updates.convertWithMediaGroupUpdates
import dev.inmo.tgbotapi.types.message.abstracts.PossiblyMediaGroupMessage
import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate

View File

@@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
import dev.inmo.kslog.common.KSLog
import dev.inmo.micro_utils.coroutines.ExceptionHandler
import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.micro_utils.coroutines.runCatchingLogging
import dev.inmo.tgbotapi.bot.RequestsExecutor
import dev.inmo.tgbotapi.extensions.utils.nonstrictJsonFormat
import dev.inmo.tgbotapi.extensions.utils.updates.flowsUpdatesFilter
@@ -48,7 +48,7 @@ fun Route.includeWebhookHandlingInRoute(
val transformer = scope.updateHandlerWithMediaGroupsAdaptation(block, mediaGroupsDebounceTimeMillis, logger = logger)
post {
try {
runCatchingSafely {
runCatchingLogging(logger = logger) {
val update = nonstrictJsonFormat.decodeFromString(
UpdateDeserializationStrategy,
call.receiveText()