1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-09-04 07:39:39 +00:00

Merge pull request #981 from InsanusMokrassar/27.0.0

27.0.0
This commit is contained in:
2025-07-22 20:32:37 +06:00
committed by GitHub
308 changed files with 4396 additions and 5076 deletions

1
.gitignore vendored
View File

@@ -9,6 +9,7 @@ settings.xml
.gradle/ .gradle/
build/ build/
out/ out/
bin/
local.properties local.properties
kotlin-js-store/ kotlin-js-store/

View File

@@ -1,5 +1,20 @@
# TelegramBotAPI changelog # TelegramBotAPI changelog
## 27.0.0
**THIS UPDATE MAY CONTAIN BREAKING CHANGES. IN CASE OF ANY MIGRATION PROBLEMS FEEL FREE TO ASK IN [OUR CHAT](https://t.me/ktgbotapi_chat)**
* `Version`:
* `Kotlin`: `2.1.20` -> `2.2.0`
* `Serialization`: `1.8.1` -> `1.9.0`
* `Ktor`: `3.1.3` -> `3.2.2`
* `MicroUtils`: `0.25.7` -> `0.26.1`
* `KSLog`: `1.4.1` -> `1.5.0`
* `Common`:
* In most `data` classes with non-public constructors has been added `ConsistentCopyVisibility` annotation, preventing
public nature in difference with constructor
* Absence of several API methods for requests has been fixed
## 26.1.0 ## 26.1.0
**THIS UPDATE CONTAINS ADDING SUPPORT OF [Telegram Bots API 9.1](https://core.telegram.org/bots/api-changelog#july-3-2025)** **THIS UPDATE CONTAINS ADDING SUPPORT OF [Telegram Bots API 9.1](https://core.telegram.org/bots/api-changelog#july-3-2025)**

View File

@@ -27,7 +27,7 @@ if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != n
centralPortal { centralPortal {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER') username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD') password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
verificationTimeout = Duration.ofSeconds(0) validationTimeout = Duration.ofSeconds(0)
publishingType = "USER_MANAGED" publishingType = "USER_MANAGED"
} }

View File

@@ -5,5 +5,8 @@ kotlin.js.generate.externals=true
kotlin.incremental=true kotlin.incremental=true
kotlin.incremental.js=true kotlin.incremental.js=true
# https://github.com/google/ksp/issues/2491
ksp.useKSP2=false
library_group=dev.inmo library_group=dev.inmo
library_version=26.1.0 library_version=27.0.0

View File

@@ -1,28 +1,28 @@
[versions] [versions]
kotlin = "2.1.20" kotlin = "2.2.0"
kotlin-serialization = "1.8.1" kotlin-serialization = "1.9.0"
kotlin-coroutines = "1.10.2" kotlin-coroutines = "1.10.2"
javax-activation = "1.1.1" javax-activation = "1.1.1"
korlibs = "5.4.0" korlibs = "5.4.0"
uuid = "0.8.4" uuid = "0.8.4"
ktor = "3.1.3" ktor = "3.2.2"
ksp = "2.1.20-1.0.31" ksp = "2.2.0-2.0.2"
kotlin-poet = "1.18.1" kotlin-poet = "2.0.0"
microutils = "0.25.7" microutils = "0.26.1"
kslog = "1.4.1" kslog = "1.5.0"
versions = "0.51.0" versions = "0.52.0"
github-release-plugin = "2.5.2" github-release-plugin = "2.5.2"
dokka = "2.0.0" dokka = "2.0.0"
validator = "0.17.0" validator = "0.17.0"
nmcp = "0.1.5" nmcp = "1.0.1"
[libraries] [libraries]

View File

@@ -4,6 +4,9 @@ project.group = "$group"
apply from: "$mpp_publish" apply from: "$mpp_publish"
kotlin { kotlin {
compilerOptions {
freeCompilerArgs.add("-Xcontext-parameters")
}
js (IR) { js (IR) {
browser() browser()
nodejs() nodejs()

View File

@@ -2,6 +2,9 @@ project.version = "$library_version"
project.group = "$library_group" project.group = "$library_group"
kotlin { kotlin {
compilerOptions {
freeCompilerArgs.add("-Xcontext-parameters")
}
jvm { jvm {
compilations.main { compilations.main {
kotlinOptions { kotlinOptions {

View File

@@ -3,8 +3,6 @@ public final class dev/inmo/tgbotapi/extensions/api/BotBuilder {
public final fun component1 ()Ljava/net/Proxy; public final fun component1 ()Ljava/net/Proxy;
public final fun component2 ()Lio/ktor/client/engine/HttpClientEngineFactory; public final fun component2 ()Lio/ktor/client/engine/HttpClientEngineFactory;
public final fun component3 ()Lkotlin/jvm/functions/Function1; public final fun component3 ()Lkotlin/jvm/functions/Function1;
public final fun copy (Ljava/net/Proxy;Lio/ktor/client/engine/HttpClientEngineFactory;Lkotlin/jvm/functions/Function1;)Ldev/inmo/tgbotapi/extensions/api/BotBuilder;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/extensions/api/BotBuilder;Ljava/net/Proxy;Lio/ktor/client/engine/HttpClientEngineFactory;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/inmo/tgbotapi/extensions/api/BotBuilder;
public fun equals (Ljava/lang/Object;)Z public fun equals (Ljava/lang/Object;)Z
public final fun getKtorClientConfig ()Lkotlin/jvm/functions/Function1; public final fun getKtorClientConfig ()Lkotlin/jvm/functions/Function1;
public final fun getKtorClientEngineFactory ()Lio/ktor/client/engine/HttpClientEngineFactory; public final fun getKtorClientEngineFactory ()Lio/ktor/client/engine/HttpClientEngineFactory;
@@ -40,7 +38,7 @@ public final class dev/inmo/tgbotapi/extensions/api/BotExtensionsKt {
} }
public final class dev/inmo/tgbotapi/extensions/api/CloseKt { public final class dev/inmo/tgbotapi/extensions/api/CloseKt {
public static final fun close (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun executeClose (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
} }
public final class dev/inmo/tgbotapi/extensions/api/DeleteMessageKt { public final class dev/inmo/tgbotapi/extensions/api/DeleteMessageKt {
@@ -88,7 +86,7 @@ public final class dev/inmo/tgbotapi/extensions/api/EditLiveLocationInfo : dev/i
public fun toString ()Ljava/lang/String; public fun toString ()Ljava/lang/String;
} }
public synthetic class dev/inmo/tgbotapi/extensions/api/EditLiveLocationInfo$$serializer : kotlinx/serialization/internal/GeneratedSerializer { public final synthetic class dev/inmo/tgbotapi/extensions/api/EditLiveLocationInfo$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Ldev/inmo/tgbotapi/extensions/api/EditLiveLocationInfo$$serializer; public static final field INSTANCE Ldev/inmo/tgbotapi/extensions/api/EditLiveLocationInfo$$serializer;
public final fun childSerializers ()[Lkotlinx/serialization/KSerializer; public final fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ldev/inmo/tgbotapi/extensions/api/EditLiveLocationInfo; public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ldev/inmo/tgbotapi/extensions/api/EditLiveLocationInfo;
@@ -96,6 +94,7 @@ public synthetic class dev/inmo/tgbotapi/extensions/api/EditLiveLocationInfo$$se
public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Ldev/inmo/tgbotapi/extensions/api/EditLiveLocationInfo;)V public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Ldev/inmo/tgbotapi/extensions/api/EditLiveLocationInfo;)V
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
} }
public final class dev/inmo/tgbotapi/extensions/api/EditLiveLocationInfo$Companion { public final class dev/inmo/tgbotapi/extensions/api/EditLiveLocationInfo$Companion {
@@ -2479,8 +2478,16 @@ public final class dev/inmo/tgbotapi/extensions/api/thumbs/SetStickerSetThumbnai
} }
public final class dev/inmo/tgbotapi/extensions/api/utils/UpdatesHandlingKt { public final class dev/inmo/tgbotapi/extensions/api/utils/UpdatesHandlingKt {
public static final fun updateHandlerWithMediaGroupsAdaptation (Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;J)Lkotlin/jvm/functions/Function2; public static final fun updateHandlerWithMediaGroupsAdaptation (Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;JLdev/inmo/kslog/common/KSLog;)Lkotlin/jvm/functions/Function2;
public static synthetic fun updateHandlerWithMediaGroupsAdaptation$default (Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;JILjava/lang/Object;)Lkotlin/jvm/functions/Function2; public static synthetic fun updateHandlerWithMediaGroupsAdaptation$default (Lkotlinx/coroutines/CoroutineScope;Lkotlin/jvm/functions/Function2;JLdev/inmo/kslog/common/KSLog;ILjava/lang/Object;)Lkotlin/jvm/functions/Function2;
}
public final class dev/inmo/tgbotapi/extensions/api/verifications/RemoveChatVerificationKt {
public static final fun removeChatVerification (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Ldev/inmo/tgbotapi/types/ChatIdentifier;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}
public final class dev/inmo/tgbotapi/extensions/api/verifications/RemoveUserVerificationKt {
public static final fun removeUserVerification-dEpx-Zg (Ldev/inmo/tgbotapi/bot/RequestsExecutor;JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
} }
public final class dev/inmo/tgbotapi/extensions/api/verifications/VerifyChatKt { public final class dev/inmo/tgbotapi/extensions/api/verifications/VerifyChatKt {

View File

@@ -12,6 +12,7 @@ import io.ktor.client.engine.*
* @param ktorClientEngine Engine like [io.ktor.client.engine.cio.CIO] * @param ktorClientEngine Engine like [io.ktor.client.engine.cio.CIO]
* @param ktorClientConfig Config block for preconfiguring of bot [HttpClient] * @param ktorClientConfig Config block for preconfiguring of bot [HttpClient]
*/ */
@ConsistentCopyVisibility
public data class BotBuilder internal constructor( public data class BotBuilder internal constructor(
var proxy: ProxyConfig? = null, var proxy: ProxyConfig? = null,
var ktorClientEngineFactory: HttpClientEngineFactory<HttpClientEngineConfig>? = null, var ktorClientEngineFactory: HttpClientEngineFactory<HttpClientEngineConfig>? = null,

View File

@@ -3,5 +3,4 @@ package dev.inmo.tgbotapi.extensions.api
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.local.Close import dev.inmo.tgbotapi.requests.local.Close
@Suppress("unused") public suspend inline fun TelegramBot.executeClose(): Boolean = execute(Close)
public suspend inline fun TelegramBot.close(): Boolean = execute(Close)

View File

@@ -17,6 +17,7 @@ internal fun List<Update>.convertWithMediaGroupUpdates(): List<Update> {
for (update in this) { for (update in this) {
val message = (update.data as? PossiblySentViaBotCommonMessage<*>) ?.let { val message = (update.data as? PossiblySentViaBotCommonMessage<*>) ?.let {
if (it.content is MediaGroupPartContent) { if (it.content is MediaGroupPartContent) {
@Suppress("UNCHECKED_CAST")
it as PossiblySentViaBotCommonMessage<MediaGroupPartContent> it as PossiblySentViaBotCommonMessage<MediaGroupPartContent>
} else { } else {
null null
@@ -48,10 +49,4 @@ internal fun List<Update>.convertWithMediaGroupUpdates(): List<Update> {
return resultUpdates return resultUpdates
} }
/** internal fun BaseEditMessageUpdate.toEditMediaGroupUpdate(): BaseEditMessageUpdate = this
* @return [EditMessageMediaGroupUpdate] in case if [this] is [EditMessageUpdate]. When [this] object is
* [EditChannelPostUpdate] instance - will return [EditChannelPostMediaGroupUpdate]
*
* @throws IllegalStateException
*/
internal fun BaseEditMessageUpdate.toEditMediaGroupUpdate() = this

View File

@@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.extensions.api package dev.inmo.tgbotapi.extensions.api
import dev.inmo.micro_utils.coroutines.LinkedSupervisorScope import dev.inmo.micro_utils.coroutines.LinkedSupervisorScope
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.tgbotapi.abstracts.Headed import dev.inmo.tgbotapi.abstracts.Headed
import dev.inmo.tgbotapi.abstracts.HorizontallyAccured import dev.inmo.tgbotapi.abstracts.HorizontallyAccured
import dev.inmo.tgbotapi.abstracts.Locationed import dev.inmo.tgbotapi.abstracts.Locationed
@@ -19,6 +18,7 @@ import dev.inmo.tgbotapi.types.location.Location
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.LiveLocationContent import dev.inmo.tgbotapi.types.message.content.LiveLocationContent
import dev.inmo.tgbotapi.types.message.content.LocationContent import dev.inmo.tgbotapi.types.message.content.LocationContent
import dev.inmo.tgbotapi.utils.launchWithBotLogger
import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.currentCoroutineContext import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@@ -63,7 +63,7 @@ public suspend fun TelegramBot.handleLiveLocation(
null null
} else { } else {
val scope = currentCoroutineContext().LinkedSupervisorScope() val scope = currentCoroutineContext().LinkedSupervisorScope()
scope.launchSafelyWithoutExceptions(start = CoroutineStart.LAZY) { scope.launchWithBotLogger(start = CoroutineStart.LAZY) {
while (scope.isActive) { while (scope.isActive) {
delay(liveTimeMillis) delay(liveTimeMillis)
// Remove previous location message info to resend live location message // Remove previous location message info to resend live location message

View File

@@ -1,3 +1,5 @@
@file:Suppress("KDocUnresolvedReference")
package dev.inmo.tgbotapi.extensions.api.edit.media package dev.inmo.tgbotapi.extensions.api.edit.media
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
@@ -45,7 +47,7 @@ public suspend fun TelegramBot.editMessageMedia(
* as a builder for that * as a builder for that
*/ */
public suspend fun TelegramBot.editMessageMedia( public suspend fun TelegramBot.editMessageMedia(
message: ContentMessage<out MediaContent>, message: ContentMessage<MediaContent>,
media: TelegramFreeMedia, media: TelegramFreeMedia,
businessConnectionId: BusinessConnectionId? = message.chat.id.businessConnectionId, businessConnectionId: BusinessConnectionId? = message.chat.id.businessConnectionId,
replyMarkup: InlineKeyboardMarkup? = null replyMarkup: InlineKeyboardMarkup? = null

View File

@@ -10,6 +10,7 @@ import dev.inmo.tgbotapi.types.message.content.MessageContent
/** /**
* This method will send [content] to the [chatId] as is * This method will send [content] to the [chatId] as is
*/ */
@Suppress("UNCHECKED_CAST")
public suspend inline fun <T : MessageContent> TelegramBot.resend( public suspend inline fun <T : MessageContent> TelegramBot.resend(
chatId: ChatIdentifier, chatId: ChatIdentifier,
content: T, content: T,

View File

@@ -1,9 +1,7 @@
package dev.inmo.tgbotapi.extensions.api.send package dev.inmo.tgbotapi.extensions.api.send
import dev.inmo.micro_utils.coroutines.LinkedSupervisorScope import dev.inmo.micro_utils.coroutines.LinkedSupervisorScope
import dev.inmo.micro_utils.coroutines.runCatchingSafely import dev.inmo.micro_utils.coroutines.runCatchingLogging
import dev.inmo.micro_utils.coroutines.safelyWithResult
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.send.SendAction import dev.inmo.tgbotapi.requests.send.SendAction
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
@@ -21,6 +19,7 @@ public suspend fun <T> TelegramBot.withAction(
actionRequest: SendAction, actionRequest: SendAction,
block: TelegramBotActionCallback<T> block: TelegramBotActionCallback<T>
): T { ): T {
@Suppress("WRONG_INVOCATION_KIND")
contract { contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
@@ -33,7 +32,7 @@ public suspend fun <T> TelegramBot.withAction(
delay(refreshTime) delay(refreshTime)
} }
} }
val result = runCatchingSafely { block() } val result = runCatchingLogging(logger = Log) { block() }
actionScope.coroutineContext.job.cancel() actionScope.coroutineContext.job.cancel()
return result.getOrThrow() return result.getOrThrow()
} }

View File

@@ -9,6 +9,8 @@ import dev.inmo.tgbotapi.types.ReplyParameters
import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.checklists.Checklist import dev.inmo.tgbotapi.types.checklists.Checklist
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.ChecklistContent
public suspend fun TelegramBot.sendChecklist( public suspend fun TelegramBot.sendChecklist(
chatId: ChatIdentifier, chatId: ChatIdentifier,
@@ -19,7 +21,7 @@ public suspend fun TelegramBot.sendChecklist(
effectId: EffectId? = null, effectId: EffectId? = null,
replyParameters: ReplyParameters? = null, replyParameters: ReplyParameters? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
) = execute( ): ContentMessage<ChecklistContent> = execute(
SendChecklist( SendChecklist(
chatId = chatId, chatId = chatId,
checklist = checklist, checklist = checklist,
@@ -40,7 +42,7 @@ public suspend fun TelegramBot.sendChecklist(
effectId: EffectId? = null, effectId: EffectId? = null,
replyParameters: ReplyParameters? = null, replyParameters: ReplyParameters? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
) = execute( ): ContentMessage<ChecklistContent> = execute(
SendChecklist( SendChecklist(
chatId = chatId, chatId = chatId,
checklist = checklist, checklist = checklist,

View File

@@ -546,7 +546,7 @@ public suspend fun TelegramBot.send(
effectId: EffectId? = null, effectId: EffectId? = null,
replyParameters: ReplyParameters? = null, replyParameters: ReplyParameters? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
) = execute( ): ContentMessage<ChecklistContent> = execute(
SendChecklist( SendChecklist(
chatId = chatId, chatId = chatId,
checklist = checklist, checklist = checklist,
@@ -567,7 +567,7 @@ public suspend fun TelegramBot.send(
effectId: EffectId? = null, effectId: EffectId? = null,
replyParameters: ReplyParameters? = null, replyParameters: ReplyParameters? = null,
replyMarkup: KeyboardMarkup? = null replyMarkup: KeyboardMarkup? = null
) = execute( ): ContentMessage<ChecklistContent> = execute(
SendChecklist( SendChecklist(
chatId = chatId, chatId = chatId,
checklist = checklist, checklist = checklist,

View File

@@ -1,11 +1,13 @@
package dev.inmo.tgbotapi.extensions.api.utils package dev.inmo.tgbotapi.extensions.api.utils
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions import dev.inmo.kslog.common.KSLog
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
import dev.inmo.tgbotapi.extensions.api.InternalUtils.convertWithMediaGroupUpdates import dev.inmo.tgbotapi.extensions.api.InternalUtils.convertWithMediaGroupUpdates
import dev.inmo.tgbotapi.types.message.abstracts.PossiblyMediaGroupMessage import dev.inmo.tgbotapi.types.message.abstracts.PossiblyMediaGroupMessage
import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate import dev.inmo.tgbotapi.types.update.abstracts.BaseMessageUpdate
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.updateshandlers.UpdateReceiver import dev.inmo.tgbotapi.updateshandlers.UpdateReceiver
import dev.inmo.tgbotapi.utils.DefaultKTgBotAPIKSLog
import dev.inmo.tgbotapi.utils.extensions.accumulateByKey import dev.inmo.tgbotapi.utils.extensions.accumulateByKey
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
@@ -19,7 +21,8 @@ import kotlinx.coroutines.launch
*/ */
public fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation( public fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation(
output: UpdateReceiver<Update>, output: UpdateReceiver<Update>,
mediaGroupsDebounceMillis: Long = 1000L mediaGroupsDebounceMillis: Long = 1000L,
logger: KSLog = DefaultKTgBotAPIKSLog
): UpdateReceiver<Update> { ): UpdateReceiver<Update> {
val updatesChannel = Channel<Update>(Channel.UNLIMITED) val updatesChannel = Channel<Update>(Channel.UNLIMITED)
val mediaGroupChannel = Channel<Pair<String, BaseMessageUpdate>>(Channel.UNLIMITED) val mediaGroupChannel = Channel<Pair<String, BaseMessageUpdate>>(Channel.UNLIMITED)
@@ -29,7 +32,7 @@ public fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation(
) )
launch { launch {
launchSafelyWithoutExceptions { launchLoggingDropExceptions(logger = logger) {
for (update in updatesChannel) { for (update in updatesChannel) {
val data = update.data val data = update.data
when { when {
@@ -40,7 +43,7 @@ public fun CoroutineScope.updateHandlerWithMediaGroupsAdaptation(
} }
} }
} }
launchSafelyWithoutExceptions { launchLoggingDropExceptions(logger = logger) {
for ((_, mediaGroup) in mediaGroupAccumulatedChannel) { for ((_, mediaGroup) in mediaGroupAccumulatedChannel) {
mediaGroup.convertWithMediaGroupUpdates().forEach { mediaGroup.convertWithMediaGroupUpdates().forEach {
output(it) output(it)

View File

@@ -0,0 +1,11 @@
package dev.inmo.tgbotapi.extensions.api.verifications
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.verifications.RemoveChatVerification
import dev.inmo.tgbotapi.types.ChatIdentifier
public suspend fun TelegramBot.removeChatVerification(
chatId: ChatIdentifier
): Boolean = execute(
RemoveChatVerification(chatId)
)

View File

@@ -0,0 +1,11 @@
package dev.inmo.tgbotapi.extensions.api.verifications
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.verifications.RemoveUserVerification
import dev.inmo.tgbotapi.types.UserId
public suspend fun TelegramBot.removeUserVerification(
userId: UserId
): Boolean = execute(
RemoveUserVerification(userId)
)

View File

@@ -1,11 +1,13 @@
public abstract interface class dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM : dev/inmo/micro_utils/fsm/common/StatesMachine, dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext { public abstract interface class dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM : dev/inmo/micro_utils/fsm/common/StatesMachine, dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext {
public static final field Companion Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM$Companion; public static final field Companion Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM$Companion;
public abstract fun add (Lkotlin/reflect/KClass;ZLdev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandler;)V public abstract fun add (Lkotlin/reflect/KClass;ZLdev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandler;)V
public abstract fun addStrict (Lkotlin/reflect/KClass;Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandler;)V public static synthetic fun add$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM;Lkotlin/reflect/KClass;ZLdev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandler;ILjava/lang/Object;)V
public fun addStrict (Lkotlin/reflect/KClass;Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandler;)V
public abstract fun copy (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Lkotlinx/coroutines/CoroutineScope;ILkotlinx/coroutines/channels/BufferOverflow;Lkotlinx/coroutines/flow/Flow;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/handlers_registrar/TriggersHolder;Lkotlin/jvm/functions/Function3;)Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM; public abstract fun copy (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Lkotlinx/coroutines/CoroutineScope;ILkotlinx/coroutines/channels/BufferOverflow;Lkotlinx/coroutines/flow/Flow;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/handlers_registrar/TriggersHolder;Lkotlin/jvm/functions/Function3;)Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM;
public abstract fun copy (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Lkotlinx/coroutines/CoroutineScope;ILkotlinx/coroutines/channels/BufferOverflow;Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/handlers_registrar/TriggersHolder;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;)Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM; public abstract fun copy (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Lkotlinx/coroutines/CoroutineScope;ILkotlinx/coroutines/channels/BufferOverflow;Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/handlers_registrar/TriggersHolder;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;)Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM;Ldev/inmo/tgbotapi/bot/RequestsExecutor;Lkotlinx/coroutines/CoroutineScope;ILkotlinx/coroutines/channels/BufferOverflow;Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/handlers_registrar/TriggersHolder;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM;
public abstract fun getStateInitialAction ()Lkotlin/jvm/functions/Function3; public abstract fun getStateInitialAction ()Lkotlin/jvm/functions/Function3;
public abstract fun start (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun start (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
} }
public final class dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM$Companion { public final class dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM$Companion {
@@ -49,7 +51,7 @@ public final class dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourConte
} }
public abstract interface class dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandler : dev/inmo/micro_utils/fsm/common/StatesHandler { public abstract interface class dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourWithFSMStateHandler : dev/inmo/micro_utils/fsm/common/StatesHandler {
public abstract fun handleState (Ldev/inmo/micro_utils/fsm/common/StatesMachine;Ldev/inmo/micro_utils/fsm/common/State;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun handleState (Ldev/inmo/micro_utils/fsm/common/StatesMachine;Ldev/inmo/micro_utils/fsm/common/State;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public abstract fun handleState (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM;Ldev/inmo/micro_utils/fsm/common/State;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun handleState (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextWithFSM;Ldev/inmo/micro_utils/fsm/common/State;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
} }

View File

@@ -1,3 +1,5 @@
@file:Suppress("unused")
package dev.inmo.tgbotapi.extensions.behaviour_builder package dev.inmo.tgbotapi.extensions.behaviour_builder
import dev.inmo.micro_utils.coroutines.* import dev.inmo.micro_utils.coroutines.*
@@ -8,6 +10,8 @@ import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextWithFSM.Companion.DATA_FSM_KEY import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextWithFSM.Companion.DATA_FSM_KEY
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.handlers_registrar.TriggersHolder import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.handlers_registrar.TriggersHolder
import dev.inmo.tgbotapi.utils.launchWithBotLogger
import dev.inmo.tgbotapi.utils.subscribeWithBotLogger
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
@@ -72,6 +76,7 @@ interface BehaviourContextWithFSM<T : State> : BehaviourContext, StatesMachine<T
): BehaviourContextWithFSM<T> ): BehaviourContextWithFSM<T>
companion object { companion object {
@Suppress("RemoveExplicitTypeArguments")
operator fun <T : State> invoke( operator fun <T : State> invoke(
behaviourContext: BehaviourContext, behaviourContext: BehaviourContext,
handlers: List<BehaviourWithFSMStateHandlerHolder<*, T>>, handlers: List<BehaviourWithFSMStateHandlerHolder<*, T>>,
@@ -88,7 +93,7 @@ interface BehaviourContextWithFSM<T : State> : BehaviourContext, StatesMachine<T
/** /**
* Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that * Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that
* for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement * for input [State] will be used [KClass.isInstance] and any inheritor of I::class will pass this requirement
* *
* @see BehaviourWithFSMStateHandlerHolder * @see BehaviourWithFSMStateHandlerHolder
* @see BehaviourContextWithFSM.add * @see BehaviourContextWithFSM.add
@@ -98,7 +103,7 @@ inline fun <reified I : O, O: State> BehaviourContextWithFSM<O>.onStateOrSubstat
/** /**
* Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that * Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that
* for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass * for input [State] will be used [State]::class == I::class and any [State] with exactly the same type will pass
* requirements * requirements
* *
* @see BehaviourWithFSMStateHandlerHolder * @see BehaviourWithFSMStateHandlerHolder
@@ -157,7 +162,7 @@ class DefaultBehaviourContextWithFSM<T : State>(
actualHandlersList = additionalHandlers + handlers actualHandlersList = additionalHandlers + handlers
} }
override fun start(scope: CoroutineScope): Job = scope.launchSafelyWithoutExceptions { override fun start(scope: CoroutineScope): Job = scope.launchWithBotLogger {
val statePerformer: suspend (T) -> Unit = { state: T -> val statePerformer: suspend (T) -> Unit = { state: T ->
val newState = getSubContext(state.context).launchStateHandling(state, actualHandlersList) val newState = getSubContext(state.context).launchStateHandling(state, actualHandlersList)
if (newState != null) { if (newState != null) {
@@ -169,7 +174,7 @@ class DefaultBehaviourContextWithFSM<T : State>(
fun Job.enableRemoveOnCompletion(state: T) { fun Job.enableRemoveOnCompletion(state: T) {
invokeOnCompletion { invokeOnCompletion {
launchSafelyWithoutExceptions { launchWithBotLogger {
statesJobsMutex.withLock { statesJobsMutex.withLock {
if (this@enableRemoveOnCompletion === statesJobs[state]) { if (this@enableRemoveOnCompletion === statesJobs[state]) {
statesJobs.remove(state) statesJobs.remove(state)
@@ -179,23 +184,23 @@ class DefaultBehaviourContextWithFSM<T : State>(
} }
} }
statesManager.onStartChain.subscribeSafelyWithoutExceptions(this) { statesManager.onStartChain.subscribeWithBotLogger(this) {
statesJobsMutex.withLock { statesJobsMutex.withLock {
runCatchingSafely { statesJobs.remove(it) ?.cancel() } runCatching { statesJobs.remove(it) ?.cancel() }
statesJobs[it] = launch { statePerformer(it) }.apply { enableRemoveOnCompletion(it) } statesJobs[it] = launch { statePerformer(it) }.apply { enableRemoveOnCompletion(it) }
} }
} }
statesManager.onEndChain.subscribeSafelyWithoutExceptions(this) { statesManager.onEndChain.subscribeWithBotLogger(this) {
statesJobsMutex.withLock { statesJobsMutex.withLock {
runCatchingSafely { statesJobs.remove(it) ?.cancel() } runCatching { statesJobs.remove(it) ?.cancel() }
} }
updatesFlows.remove(it.context) ?.cancel() updatesFlows.remove(it.context) ?.cancel()
} }
statesManager.onChainStateUpdated.subscribeSafelyWithoutExceptions(this) { (old, new) -> statesManager.onChainStateUpdated.subscribeWithBotLogger(this) { (old, new) ->
statesJobsMutex.withLock { statesJobsMutex.withLock {
runCatchingSafely { statesJobs.remove(old) ?.cancel() } runCatching { statesJobs.remove(old) ?.cancel() }
runCatchingSafely { statesJobs.remove(new) ?.cancel() } runCatching { statesJobs.remove(new) ?.cancel() }
statesJobs[new] = launch { statePerformer(new) }.apply { enableRemoveOnCompletion(new) } statesJobs[new] = launch { statePerformer(new) }.apply { enableRemoveOnCompletion(new) }
} }
if (old.context != new.context) { if (old.context != new.context) {
@@ -205,7 +210,7 @@ class DefaultBehaviourContextWithFSM<T : State>(
statesManager.getActiveStates().forEach { statesManager.getActiveStates().forEach {
statesJobsMutex.withLock { statesJobsMutex.withLock {
runCatchingSafely { statesJobs.remove(it) ?.cancel() } runCatching { statesJobs.remove(it) ?.cancel() }
statesJobs[it] = launch { statePerformer(it) }.apply { enableRemoveOnCompletion(it) } statesJobs[it] = launch { statePerformer(it) }.apply { enableRemoveOnCompletion(it) }
} }
@@ -213,7 +218,7 @@ class DefaultBehaviourContextWithFSM<T : State>(
} }
/** /**
* Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that * Add NON STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Non strict means that
* for input [State] will be used [KClass.isInstance] and any inheritor of [kClass] will pass this requirement * for input [State] will be used [KClass.isInstance] and any inheritor of I::class will pass this requirement
* *
* @see BehaviourWithFSMStateHandlerHolder * @see BehaviourWithFSMStateHandlerHolder
* @see BehaviourContextWithFSM.add * @see BehaviourContextWithFSM.add
@@ -223,7 +228,7 @@ class DefaultBehaviourContextWithFSM<T : State>(
/** /**
* Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that * Add STRICT [handler] to list of available in future [BehaviourContextWithFSM]. Strict means that
* for input [State] will be used [State]::class == [kClass] and any [State] with exactly the same type will pass * for input [State] will be used [State]::class == I::class and any [State] with exactly the same type will pass
* requirements * requirements
* *
* @see BehaviourWithFSMStateHandlerHolder * @see BehaviourWithFSMStateHandlerHolder
@@ -295,6 +300,7 @@ class DefaultBehaviourContextWithFSM<T : State>(
* Extracting from [BehaviourContext.data] exists [StatesMachine] by key [DATA_FSM_KEY], which usually some [BehaviourContextWithFSM]. * Extracting from [BehaviourContext.data] exists [StatesMachine] by key [DATA_FSM_KEY], which usually some [BehaviourContextWithFSM].
* In case if value absent in [BehaviourContext.data] will return null * In case if value absent in [BehaviourContext.data] will return null
*/ */
@Suppress("UNCHECKED_CAST")
fun <T : State> BehaviourContext.fsmOrNull(): StatesMachine<T>? = data[DATA_FSM_KEY] as? StatesMachine<T> fun <T : State> BehaviourContext.fsmOrNull(): StatesMachine<T>? = data[DATA_FSM_KEY] as? StatesMachine<T>
/** /**
@@ -303,4 +309,5 @@ fun <T : State> BehaviourContext.fsmOrNull(): StatesMachine<T>? = data[DATA_FSM_
* *
* @throws NullPointerException * @throws NullPointerException
*/ */
@Suppress("RemoveExplicitTypeArguments")
fun <T : State> BehaviourContext.fsmOrThrow(): StatesMachine<T> = fsmOrNull<T>()!! fun <T : State> BehaviourContext.fsmOrThrow(): StatesMachine<T> = fsmOrNull<T>()!!

View File

@@ -7,10 +7,11 @@ public final class dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourBuild
public abstract interface class dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext : dev/inmo/tgbotapi/bot/RequestsExecutor, dev/inmo/tgbotapi/updateshandlers/FlowsUpdatesFilter, kotlinx/coroutines/CoroutineScope { public abstract interface class dev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext : dev/inmo/tgbotapi/bot/RequestsExecutor, dev/inmo/tgbotapi/updateshandlers/FlowsUpdatesFilter, kotlinx/coroutines/CoroutineScope {
public abstract fun copy (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Lkotlinx/coroutines/CoroutineScope;ILkotlinx/coroutines/channels/BufferOverflow;Lkotlinx/coroutines/flow/Flow;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/handlers_registrar/TriggersHolder;Lkotlin/jvm/functions/Function3;)Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext; public abstract fun copy (Ldev/inmo/tgbotapi/bot/RequestsExecutor;Lkotlinx/coroutines/CoroutineScope;ILkotlinx/coroutines/channels/BufferOverflow;Lkotlinx/coroutines/flow/Flow;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/handlers_registrar/TriggersHolder;Lkotlin/jvm/functions/Function3;)Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;
public abstract fun getBot ()Ldev/inmo/tgbotapi/bot/RequestsExecutor; public static synthetic fun copy$default (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ldev/inmo/tgbotapi/bot/RequestsExecutor;Lkotlinx/coroutines/CoroutineScope;ILkotlinx/coroutines/channels/BufferOverflow;Lkotlinx/coroutines/flow/Flow;Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/handlers_registrar/TriggersHolder;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;
public fun getBot ()Ldev/inmo/tgbotapi/bot/RequestsExecutor;
public abstract fun getData ()Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextData; public abstract fun getData ()Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContextData;
public abstract fun getFlowsUpdatesFilter ()Ldev/inmo/tgbotapi/updateshandlers/FlowsUpdatesFilter; public fun getFlowsUpdatesFilter ()Ldev/inmo/tgbotapi/updateshandlers/FlowsUpdatesFilter;
public abstract fun getScope ()Lkotlinx/coroutines/CoroutineScope; public fun getScope ()Lkotlinx/coroutines/CoroutineScope;
public abstract fun getSubcontextInitialAction ()Lkotlin/jvm/functions/Function3; public abstract fun getSubcontextInitialAction ()Lkotlin/jvm/functions/Function3;
public abstract fun getTriggersHolder ()Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/handlers_registrar/TriggersHolder; public abstract fun getTriggersHolder ()Ldev/inmo/tgbotapi/extensions/behaviour_builder/utils/handlers_registrar/TriggersHolder;
} }
@@ -145,7 +146,7 @@ public final class dev/inmo/tgbotapi/extensions/behaviour_builder/VariantsKt {
public static final fun oneOf (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;[Lkotlinx/coroutines/Deferred;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun oneOf (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;[Lkotlinx/coroutines/Deferred;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final fun oneOfActions (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ljava/lang/Iterable;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun oneOfActions (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Ljava/lang/Iterable;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final fun oneOfActions (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;[Ldev/inmo/micro_utils/coroutines/DeferredAction;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun oneOfActions (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;[Ldev/inmo/micro_utils/coroutines/DeferredAction;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final fun parallel (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final fun parallel (Ldev/inmo/tgbotapi/extensions/behaviour_builder/BehaviourContext;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/Deferred;
public static final fun withAction (Lkotlinx/coroutines/Deferred;Lkotlin/jvm/functions/Function2;)Ldev/inmo/micro_utils/coroutines/DeferredAction; public static final fun withAction (Lkotlinx/coroutines/Deferred;Lkotlin/jvm/functions/Function2;)Ldev/inmo/micro_utils/coroutines/DeferredAction;
} }

View File

@@ -9,6 +9,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.handlers_registrar.T
import dev.inmo.tgbotapi.types.UpdateId import dev.inmo.tgbotapi.types.UpdateId
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.launchWithBotLogger
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
@@ -150,6 +151,7 @@ inline fun <T> BehaviourContext(
* *
* @param updatesFilter This param will not be used anymore * @param updatesFilter This param will not be used anymore
*/ */
@Suppress("UNCHECKED_CAST")
fun <BC : BehaviourContext> BC.createSubContext( fun <BC : BehaviourContext> BC.createSubContext(
scope: CoroutineScope = LinkedSupervisorScope(), scope: CoroutineScope = LinkedSupervisorScope(),
triggersHolder: TriggersHolder = this.triggersHolder, triggersHolder: TriggersHolder = this.triggersHolder,
@@ -217,7 +219,7 @@ fun <T, BC : BehaviourContext> BC.launchInNewSubContext(
updatesUpstreamFlow = updatesUpstreamFlow, updatesUpstreamFlow = updatesUpstreamFlow,
subcontextInitialAction = subcontextInitialAction subcontextInitialAction = subcontextInitialAction
).apply { ).apply {
this@apply.launchLoggingDropExceptions(logger = Log) { this@apply.launchWithBotLogger {
behaviourContextReceiver() behaviourContextReceiver()
} }
}.coroutineContext.job }.coroutineContext.job

View File

@@ -1,3 +1,5 @@
@file:Suppress("unused")
package dev.inmo.tgbotapi.extensions.behaviour_builder package dev.inmo.tgbotapi.extensions.behaviour_builder
import dev.inmo.micro_utils.coroutines.DeferredAction import dev.inmo.micro_utils.coroutines.DeferredAction
@@ -5,15 +7,15 @@ import dev.inmo.micro_utils.coroutines.invokeFirstOf
import kotlinx.coroutines.Deferred import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async import kotlinx.coroutines.async
suspend fun <T> BehaviourContext.parallel( fun <T> BehaviourContext.parallel(
action: BehaviourContextReceiver<T> action: BehaviourContextReceiver<T>
) = async { ) = async {
action() action()
} }
inline infix fun <T, O> Deferred<T>.withAction(noinline callback: suspend (T) -> O) = DeferredAction(this, callback) infix fun <T, O> Deferred<T>.withAction(callback: suspend (T) -> O) = DeferredAction(this, callback)
inline fun <T> Deferred<T>.asAction() = DeferredAction(this) { it } fun <T> Deferred<T>.asAction() = DeferredAction(this) { it }
suspend fun <O> BehaviourContext.oneOfActions( suspend fun <O> BehaviourContext.oneOfActions(
deferredActions: Iterable<DeferredAction<*, O>> deferredActions: Iterable<DeferredAction<*, O>>

View File

@@ -44,7 +44,7 @@ fun <T> FlowsUpdatesFilter.expectFlow(
if (result.isFailure || result.getOrThrow().isEmpty()) { if (result.isFailure || result.getOrThrow().isEmpty()) {
if (cancelTrigger(it)) { if (cancelTrigger(it)) {
cancelRequestFactory(it) ?.also { cancelRequestFactory(it) ?.also {
safelyWithResult { bot.execute(it) } runCatching { bot.execute(it) }
throw cancelledByFilterException throw cancelledByFilterException
} }
} }

View File

@@ -1,3 +1,5 @@
@file:Suppress("unused")
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
@@ -10,9 +12,9 @@ import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage import dev.inmo.tgbotapi.utils.lowLevelRiskFeatureMessage
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
inline fun BehaviourContext.waitChatMessageReactionsCountUpdated( fun BehaviourContext.waitChatMessageReactionsCountUpdated(
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null } errorFactory: NullableRequestBuilder<*> = { null }
): Flow<ChatMessageReactionsCountUpdated> = expectFlow( ): Flow<ChatMessageReactionsCountUpdated> = expectFlow(
initRequest, initRequest,
errorFactory errorFactory

View File

@@ -1,3 +1,5 @@
@file:Suppress("OPT_IN_USAGE")
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext

View File

@@ -1,3 +1,5 @@
@file:Suppress("unused")
package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
@@ -17,7 +19,8 @@ inline fun <reified T : MediaGroupPartContent> BehaviourContext.buildMediaGroupW
noinline errorFactory: NullableRequestBuilder<*> = { null } noinline errorFactory: NullableRequestBuilder<*> = { null }
): Flow<MediaGroupContent<T>> = flowsUpdatesFilter.expectFlow(bot, initRequest, errorFactory) { update -> ): Flow<MediaGroupContent<T>> = flowsUpdatesFilter.expectFlow(bot, initRequest, errorFactory) { update ->
update.baseSentMessageUpdateOrNull() ?.data ?.commonMessageOrNull() ?.withContentOrNull<MediaGroupContent<*>>() ?.let { message -> update.baseSentMessageUpdateOrNull() ?.data ?.commonMessageOrNull() ?.withContentOrNull<MediaGroupContent<*>>() ?.let { message ->
if (message.content.group.all { it is T }) { if (message.content.group.all { it.content is T }) {
@Suppress("UNCHECKED_CAST")
listOf(message.content as MediaGroupContent<T>) listOf(message.content as MediaGroupContent<T>)
} else { } else {
null null

View File

@@ -17,7 +17,8 @@ inline fun <reified T : MediaGroupPartContent> BehaviourContext.buildMediaGroupM
noinline errorFactory: NullableRequestBuilder<*> = { null } noinline errorFactory: NullableRequestBuilder<*> = { null }
): Flow<MediaGroupMessage<T>> = flowsUpdatesFilter.expectFlow(bot, initRequest, errorFactory) { update -> ): Flow<MediaGroupMessage<T>> = flowsUpdatesFilter.expectFlow(bot, initRequest, errorFactory) { update ->
update.baseSentMessageUpdateOrNull() ?.data ?.commonMessageOrNull() ?.withContentOrNull<MediaGroupContent<*>>() ?.let { message -> update.baseSentMessageUpdateOrNull() ?.data ?.commonMessageOrNull() ?.withContentOrNull<MediaGroupContent<*>>() ?.let { message ->
if (message.content.group.all { it is T }) { if (message.content.group.all { it.content is T }) {
@Suppress("UNCHECKED_CAST")
listOf(message as MediaGroupMessage<T>) listOf(message as MediaGroupMessage<T>)
} else { } else {
null null

View File

@@ -2,8 +2,6 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CallbackQueryFilterByUser import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CallbackQueryFilterByUser
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
@@ -13,6 +11,7 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times
import dev.inmo.tgbotapi.extensions.utils.callbackQueryUpdateOrNull import dev.inmo.tgbotapi.extensions.utils.callbackQueryUpdateOrNull
import dev.inmo.tgbotapi.types.queries.callback.* import dev.inmo.tgbotapi.types.queries.callback.*
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.utils.launchWithBotLogger
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
internal inline fun <BC : BehaviourContext, reified T : CallbackQuery> BC.onCallbackQuery( internal inline fun <BC : BehaviourContext, reified T : CallbackQuery> BC.onCallbackQuery(
@@ -63,7 +62,7 @@ internal inline fun <BC : BehaviourContext, reified T : DataCallbackQuery> BC.on
this@launchInNewSubContext.triggersHolder.handleableCallbackQueriesDataHolder.registerHandleable(newInitialFilterInvoke) this@launchInNewSubContext.triggersHolder.handleableCallbackQueriesDataHolder.registerHandleable(newInitialFilterInvoke)
it.invokeOnCompletion { it.invokeOnCompletion {
runCatching { runCatching {
launchSafelyWithoutExceptions { launchWithBotLogger {
this@launchInNewSubContext.triggersHolder.handleableCallbackQueriesDataHolder.unregisterHandleable(newInitialFilterInvoke) this@launchInNewSubContext.triggersHolder.handleableCallbackQueriesDataHolder.unregisterHandleable(newInitialFilterInvoke)
} }
} }

View File

@@ -2,10 +2,6 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.kslog.common.KSLog
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CommonMessageFilterExcludeMediaGroups import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CommonMessageFilterExcludeMediaGroups
import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessageFilterByChat import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessageFilterByChat
@@ -20,6 +16,7 @@ import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.types.message.content.TextContent 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.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.utils.launchWithBotLogger
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.job import kotlinx.coroutines.job
@@ -77,7 +74,7 @@ fun <BC : BehaviourContext> BC.command(
triggersHolder.handleableCommandsHolder.registerHandleable(commandRegex) triggersHolder.handleableCommandsHolder.registerHandleable(commandRegex)
it.invokeOnCompletion { it.invokeOnCompletion {
runCatching { runCatching {
launchSafelyWithoutExceptions { launchWithBotLogger {
triggersHolder.handleableCommandsHolder.unregisterHandleable(commandRegex) triggersHolder.handleableCommandsHolder.unregisterHandleable(commandRegex)
} }
} }

View File

@@ -15,6 +15,7 @@ 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 dev.inmo.tgbotapi.utils.launchWithBotLogger
import io.ktor.http.decodeURLQueryComponent import io.ktor.http.decodeURLQueryComponent
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@@ -43,7 +44,7 @@ fun <BC : BehaviourContext> BC.onDeepLink(
}.also { }.also {
triggersHolder.handleableCommandsHolder.registerHandleable(startRegex) triggersHolder.handleableCommandsHolder.registerHandleable(startRegex)
it.invokeOnCompletion { it.invokeOnCompletion {
this@onDeepLink.launchSafelyWithoutExceptions { triggersHolder.handleableCommandsHolder.unregisterHandleable(startRegex) } this@onDeepLink.launchWithBotLogger { triggersHolder.handleableCommandsHolder.unregisterHandleable(startRegex) }
} }
} }
} }

View File

@@ -1,17 +1,19 @@
@file:OptIn(ExperimentalCoroutinesApi::class)
package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling package dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
import dev.inmo.micro_utils.coroutines.launchLoggingDropExceptions import dev.inmo.micro_utils.coroutines.runCatchingLogging
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions import dev.inmo.micro_utils.coroutines.subscribeAsync
import dev.inmo.micro_utils.coroutines.subscribeLoggingDropExceptions import dev.inmo.micro_utils.coroutines.subscribeLoggingDropExceptions
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptionsAsync import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptionsAsync
import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.expectFlow
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter
import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory
import dev.inmo.tgbotapi.extensions.utils.flatMap
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.utils.launchWithBotLogger
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flatMapLatest
@@ -69,13 +71,17 @@ internal fun <BC : BehaviourContext, T> BC.on(
createSubContextAndDoSynchronouslyWithUpdatesFilter(behaviourContextReceiver = { scenarioReceiver(triggerData) }) createSubContextAndDoSynchronouslyWithUpdatesFilter(behaviourContextReceiver = { scenarioReceiver(triggerData) })
} }
markerFactory ?.let { markerFactory ?.let {
subscribeSafelyWithoutExceptionsAsync( subscribeAsync(
scope, scope,
{ markerFactory(it.second) }, { markerFactory(it.second) },
block = handler logger = Log
) ) {
} ?: subscribeLoggingDropExceptions(scope) { runCatchingLogging(logger = Log) {
scope.launchLoggingDropExceptions { handler(it)
}
}
} ?: subscribeLoggingDropExceptions(scope, logger = Log) {
scope.launchWithBotLogger {
handler(it) handler(it)
} }
} }

View File

@@ -24,6 +24,7 @@ internal inline fun <BC : BehaviourContext, reified T : MediaGroupPartContent> B
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, additionalSubcontextInitialAction, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, additionalSubcontextInitialAction, scenarioReceiver) {
it.baseSentMessageUpdateOrNull() ?.data ?.commonMessageOrNull() ?.withContentOrNull<MediaGroupContent<*>>() ?.let { it.baseSentMessageUpdateOrNull() ?.data ?.commonMessageOrNull() ?.withContentOrNull<MediaGroupContent<*>>() ?.let {
if (it.content.group.all { it.content is T }) { if (it.content.group.all { it.content is T }) {
@Suppress("UNCHECKED_CAST")
listOf(it as MediaGroupMessage<T>) listOf(it as MediaGroupMessage<T>)
} else { } else {
null null

View File

@@ -24,6 +24,7 @@ internal inline fun <BC : BehaviourContext, reified T : MediaGroupPartContent> B
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, additionalSubcontextInitialAction, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, additionalSubcontextInitialAction, scenarioReceiver) {
it.baseSentMessageUpdateOrNull() ?.data ?.commonMessageOrNull() ?.withContentOrNull<MediaGroupContent<*>>() ?.let { it.baseSentMessageUpdateOrNull() ?.data ?.commonMessageOrNull() ?.withContentOrNull<MediaGroupContent<*>>() ?.let {
if (it.content.group.all { it.content is T }) { if (it.content.group.all { it.content is T }) {
@Suppress("UNCHECKED_CAST")
listOf(it.content as MediaGroupContent<T>) listOf(it.content as MediaGroupContent<T>)
} else { } else {
null null

View File

@@ -10,12 +10,12 @@ import dev.inmo.tgbotapi.extensions.utils.pollAnswerUpdateOrNull
import dev.inmo.tgbotapi.types.polls.PollAnswer import dev.inmo.tgbotapi.types.polls.PollAnswer
import dev.inmo.tgbotapi.types.update.abstracts.Update import dev.inmo.tgbotapi.types.update.abstracts.Update
internal inline fun <BC : BehaviourContext> BC.onPollAnswered( internal fun <BC : BehaviourContext> BC.onPollAnswered(
initialFilter: SimpleFilter<PollAnswer>? = null, initialFilter: SimpleFilter<PollAnswer>? = null,
noinline subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PollAnswer, Update>? = null, subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PollAnswer, Update>? = null,
markerFactory: MarkerFactory<in PollAnswer, Any>? = ByIdPollAnswerMarkerFactory, markerFactory: MarkerFactory<in PollAnswer, Any>? = ByIdPollAnswerMarkerFactory,
noinline additionalSubcontextInitialAction: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, Update, PollAnswer>? = null, additionalSubcontextInitialAction: CustomBehaviourContextAndTwoTypesReceiver<BC, Unit, Update, PollAnswer>? = null,
noinline scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PollAnswer> scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PollAnswer>
) = on(markerFactory, initialFilter, subcontextUpdatesFilter, additionalSubcontextInitialAction, scenarioReceiver) { ) = on(markerFactory, initialFilter, subcontextUpdatesFilter, additionalSubcontextInitialAction, scenarioReceiver) {
(it.pollAnswerUpdateOrNull() ?.data) ?.let(::listOfNotNull) (it.pollAnswerUpdateOrNull() ?.data) ?.let(::listOfNotNull)
} }

View File

@@ -1,6 +1,5 @@
package dev.inmo.tgbotapi.extensions.behaviour_builder.utils.handlers_registrar package dev.inmo.tgbotapi.extensions.behaviour_builder.utils.handlers_registrar
import dev.inmo.micro_utils.coroutines.runCatchingSafely
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
@@ -40,7 +39,7 @@ suspend fun <T, R> HandleableTriggersHolder<T>.doWithRegistration(
block: suspend () -> R block: suspend () -> R
): R { ): R {
registerHandleable(data) registerHandleable(data)
val result = runCatchingSafely { val result = runCatching {
block() block()
} }
unregisterHandleable(data) unregisterHandleable(data)

View File

@@ -1,3 +1,5 @@
@file:Suppress("UNCHECKED_CAST")
package dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories package dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories
private val commonAnyMarker = MarkerFactory<Any, Any> { it } private val commonAnyMarker = MarkerFactory<Any, Any> { it }

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,13 @@
@file:OptIn(ExperimentalCoroutinesApi::class)
package dev.inmo.tgbotapi.bot.exceptions package dev.inmo.tgbotapi.bot.exceptions
import korlibs.time.DateTime import korlibs.time.DateTime
import dev.inmo.tgbotapi.types.Response import dev.inmo.tgbotapi.types.Response
import dev.inmo.tgbotapi.types.RetryAfterError import dev.inmo.tgbotapi.types.RetryAfterError
import io.ktor.utils.io.errors.IOException
import kotlinx.coroutines.CopyableThrowable import kotlinx.coroutines.CopyableThrowable
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.io.IOException
fun newRequestException( fun newRequestException(
response: Response, response: Response,
@@ -42,7 +45,7 @@ class CommonBotException(message: String = "Something went wrong", cause: Throwa
override fun createCopy(): BotException = CommonBotException(message!!, cause) override fun createCopy(): BotException = CommonBotException(message!!, cause)
} }
sealed class RequestException constructor( sealed class RequestException (
val response: Response, val response: Response,
val plainAnswer: String, val plainAnswer: String,
message: String? = null, message: String? = null,

View File

@@ -18,6 +18,7 @@ import kotlinx.serialization.json.Json
* * On JS, JVM and MingwX64 platforms it is [dev.inmo.tgbotapi.bot.ktor.base.DefaultKtorRequestsExecutor] * * On JS, JVM and MingwX64 platforms it is [dev.inmo.tgbotapi.bot.ktor.base.DefaultKtorRequestsExecutor]
* * On LinuxX64 it is [dev.inmo.tgbotapi.bot.ktor.base.MultipleClientKtorRequestsExecutor] * * On LinuxX64 it is [dev.inmo.tgbotapi.bot.ktor.base.MultipleClientKtorRequestsExecutor]
*/ */
@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
expect class KtorRequestsExecutor internal constructor( expect class KtorRequestsExecutor internal constructor(
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper, telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
client: HttpClient, client: HttpClient,
@@ -52,5 +53,5 @@ fun KtorRequestsExecutor(
jsonFormatter = jsonFormatter, jsonFormatter = jsonFormatter,
pipelineStepsHolder = pipelineStepsHolder, pipelineStepsHolder = pipelineStepsHolder,
logger = logger, logger = logger,
diff = kotlin.Unit, diff = Unit,
) )

View File

@@ -3,7 +3,6 @@ package dev.inmo.tgbotapi.bot.ktor.base
import dev.inmo.kslog.common.KSLog import dev.inmo.kslog.common.KSLog
import dev.inmo.kslog.common.v import dev.inmo.kslog.common.v
import dev.inmo.kslog.common.w import dev.inmo.kslog.common.w
import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
import dev.inmo.tgbotapi.bot.exceptions.newRequestException import dev.inmo.tgbotapi.bot.exceptions.newRequestException
import dev.inmo.tgbotapi.requests.GetUpdatesRequest import dev.inmo.tgbotapi.requests.GetUpdatesRequest
@@ -73,7 +72,7 @@ abstract class AbstractRequestCallFactory(
val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content) val responseObject = jsonFormatter.decodeFromString(Response.serializer(), content)
logger.v { "Answer as json for $request: $responseObject" } logger.v { "Answer as json for $request: $responseObject" }
return runCatchingSafely { return runCatching {
(responseObject.result?.let { (responseObject.result?.let {
jsonFormatter.decodeFromJsonElement(request.resultDeserializer, it) jsonFormatter.decodeFromJsonElement(request.resultDeserializer, it)
} ?: response.let { } ?: response.let {

View File

@@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.bot.ktor.base package dev.inmo.tgbotapi.bot.ktor.base
import dev.inmo.kslog.common.* import dev.inmo.kslog.common.*
import dev.inmo.micro_utils.coroutines.runCatchingSafely import dev.inmo.micro_utils.coroutines.runCatchingLogging
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
import dev.inmo.tgbotapi.bot.exceptions.BotException import dev.inmo.tgbotapi.bot.exceptions.BotException
import dev.inmo.tgbotapi.bot.exceptions.CommonBotException import dev.inmo.tgbotapi.bot.exceptions.CommonBotException
@@ -17,6 +17,7 @@ import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import io.ktor.client.* import io.ktor.client.*
import io.ktor.client.plugins.* import io.ktor.client.plugins.*
import io.ktor.client.statement.* import io.ktor.client.statement.*
import kotlinx.coroutines.CancellationException
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
class DefaultKtorRequestsExecutor internal constructor( class DefaultKtorRequestsExecutor internal constructor(
@@ -48,7 +49,7 @@ class DefaultKtorRequestsExecutor internal constructor(
} }
override suspend fun <T : Any> execute(request: Request<T>): T { override suspend fun <T : Any> execute(request: Request<T>): T {
return runCatching { return runCatchingLogging(logger = logger) {
logger.v { "Start request $request" } logger.v { "Start request $request" }
pipelineStepsHolder.onBeforeSearchCallFactory(request, callsFactories) pipelineStepsHolder.onBeforeSearchCallFactory(request, callsFactories)
requestsLimiter.limit(request) { requestsLimiter.limit(request) {
@@ -83,7 +84,7 @@ class DefaultKtorRequestsExecutor internal constructor(
when (e) { when (e) {
is ClientRequestException -> { is ClientRequestException -> {
val exceptionResult = runCatchingSafely { val exceptionResult = runCatching {
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(
@@ -96,6 +97,7 @@ class DefaultKtorRequestsExecutor internal constructor(
CommonBotException(cause = e) CommonBotException(cause = e)
} ?: exceptionResult.getOrThrow() } ?: exceptionResult.getOrThrow()
} }
is CancellationException,
is BotException -> e is BotException -> e
else -> CommonBotException(cause = e) else -> CommonBotException(cause = e)
}.also { newException -> }.also { newException ->

View File

@@ -24,11 +24,12 @@ object DownloadFileChannelRequestCallFactory : KtorCallFactory {
): T? = (request as? DownloadFileStream) ?.let { ): T? = (request as? DownloadFileStream) ?.let {
val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath) val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath)
@Suppress("UNCHECKED_CAST")
ByteReadChannelAllocator { ByteReadChannelAllocator {
val scope = CoroutineScope(currentCoroutineContext() + SupervisorJob()) val scope = CoroutineScope(currentCoroutineContext() + SupervisorJob())
val outChannel = ByteChannel() val outChannel = ByteChannel()
scope.launch { scope.launch {
runCatchingSafely { runCatching {
val response = client.get(fullUrl) val response = client.get(fullUrl)
val channel: ByteReadChannel = response.bodyAsChannel() val channel: ByteReadChannel = response.bodyAsChannel()
channel.copyAndClose(outChannel) channel.copyAndClose(outChannel)

View File

@@ -21,9 +21,7 @@ object DownloadFileRequestCallFactory : KtorCallFactory {
): T? = (request as? DownloadFile)?.let { ): T? = (request as? DownloadFile)?.let {
val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath) val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath)
safely { @Suppress("UNCHECKED_CAST")
@Suppress("UNCHECKED_CAST") client.get(fullUrl).readRawBytes() as T // always ByteArray
client.get(fullUrl).readRawBytes() as T // always ByteArray
}
} }
} }

View File

@@ -1,7 +1,6 @@
package dev.inmo.tgbotapi.bot.ktor.base package dev.inmo.tgbotapi.bot.ktor.base
import dev.inmo.kslog.common.KSLog import dev.inmo.kslog.common.KSLog
import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory import dev.inmo.tgbotapi.bot.ktor.KtorCallFactory
import dev.inmo.tgbotapi.bot.ktor.TelegramBotPipelinesHandler import dev.inmo.tgbotapi.bot.ktor.TelegramBotPipelinesHandler
@@ -107,7 +106,7 @@ class MultipleClientKtorRequestsExecutor(
private suspend fun <T> withRequestExecutor(block: suspend (DefaultKtorRequestsExecutor) -> T): T { private suspend fun <T> withRequestExecutor(block: suspend (DefaultKtorRequestsExecutor) -> T): T {
val requestsExecutor = prepareRequestsExecutor() val requestsExecutor = prepareRequestsExecutor()
val result = runCatchingSafely { val result = runCatching {
block(requestsExecutor) block(requestsExecutor)
} }
freeRequestsExecutor(requestsExecutor) freeRequestsExecutor(requestsExecutor)

View File

@@ -35,6 +35,7 @@ open class TelegramBotMiddleware(
) : TelegramBotPipelinesHandler { ) : TelegramBotPipelinesHandler {
object ResultAbsence : Throwable() object ResultAbsence : Throwable()
override suspend fun <T : Any> onRequestException(request: Request<T>, t: Throwable): T? { override suspend fun <T : Any> onRequestException(request: Request<T>, t: Throwable): T? {
@Suppress("UNCHECKED_CAST")
return onRequestException ?.invoke(request, t) as? T return onRequestException ?.invoke(request, t) as? T
} }
@@ -51,6 +52,7 @@ open class TelegramBotMiddleware(
request: Request<T>, request: Request<T>,
potentialFactory: KtorCallFactory potentialFactory: KtorCallFactory
): T? { ): T? {
@Suppress("UNCHECKED_CAST")
return onAfterCallFactoryMakeCall ?.invoke(result, request, potentialFactory) as? T return onAfterCallFactoryMakeCall ?.invoke(result, request, potentialFactory) as? T
} }
@@ -60,6 +62,7 @@ open class TelegramBotMiddleware(
resultCallFactory: KtorCallFactory, resultCallFactory: KtorCallFactory,
callsFactories: List<KtorCallFactory> callsFactories: List<KtorCallFactory>
): T? { ): T? {
@Suppress("UNCHECKED_CAST")
return onRequestResultPresented ?.invoke(result, request, resultCallFactory, callsFactories) as? T return onRequestResultPresented ?.invoke(result, request, resultCallFactory, callsFactories) as? T
} }
@@ -67,6 +70,7 @@ open class TelegramBotMiddleware(
request: Request<T>, request: Request<T>,
callsFactories: List<KtorCallFactory> callsFactories: List<KtorCallFactory>
): T? { ): T? {
@Suppress("UNCHECKED_CAST")
return onRequestResultAbsent ?.invoke(request, callsFactories) as? T return onRequestResultAbsent ?.invoke(request, callsFactories) as? T
} }
@@ -75,6 +79,7 @@ open class TelegramBotMiddleware(
request: Request<T>, request: Request<T>,
callsFactories: List<KtorCallFactory> callsFactories: List<KtorCallFactory>
): Result<T> { ): Result<T> {
@Suppress("UNCHECKED_CAST")
return onRequestReturnResult ?.invoke(result, request, callsFactories) as? Result<T> ?: Result.failure(ResultAbsence) return onRequestReturnResult ?.invoke(result, request, callsFactories) as? Result<T> ?: Result.failure(ResultAbsence)
} }

View File

@@ -1,6 +1,5 @@
package dev.inmo.tgbotapi.bot.settings.limiters package dev.inmo.tgbotapi.bot.settings.limiters
import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.tgbotapi.bot.exceptions.TooMuchRequestsException import dev.inmo.tgbotapi.bot.exceptions.TooMuchRequestsException
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@@ -11,7 +10,7 @@ object ExceptionsOnlyLimiter : RequestLimiter {
override suspend fun <T> limit(block: suspend () -> T): T { override suspend fun <T> limit(block: suspend () -> T): T {
var result: Result<T>? = null var result: Result<T>? = null
while (result == null || result.isFailure) { while (result == null || result.isFailure) {
result = runCatchingSafely { result = runCatching {
block() block()
}.onFailure { }.onFailure {
if (it is TooMuchRequestsException) { if (it is TooMuchRequestsException) {

View File

@@ -1,7 +1,8 @@
@file:Suppress("unused", "RemoveExplicitTypeArguments")
package dev.inmo.tgbotapi.bot.settings.limiters package dev.inmo.tgbotapi.bot.settings.limiters
import dev.inmo.micro_utils.coroutines.actor import dev.inmo.micro_utils.coroutines.actor
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.types.MilliSeconds import dev.inmo.tgbotapi.types.MilliSeconds
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@@ -56,7 +57,7 @@ data class PowLimiter(
} }
delay(delayMillis) delay(delayMillis)
return try { return try {
safely { block() } block()
} finally { } finally {
eventsChannel.send(CompleteRequest) eventsChannel.send(CompleteRequest)
} }

View File

@@ -8,6 +8,7 @@ import kotlinx.serialization.builtins.serializer
@Serializable @Serializable
data class SetPassportDataErrors( data class SetPassportDataErrors(
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
val user: UserId, val user: UserId,
@SerialName(errorsField) @SerialName(errorsField)

View File

@@ -1,3 +1,6 @@
@file:OptIn(ExperimentalSerializationApi::class)
@file:Suppress("DEPRECATION") // for io.ktor.utils.io.core.ByteReadPacket
package dev.inmo.tgbotapi.requests.abstracts package dev.inmo.tgbotapi.requests.abstracts
import com.benasher44.uuid.uuid4 import com.benasher44.uuid.uuid4
@@ -70,6 +73,7 @@ internal inline val InputFile.fileIdToSend
/** /**
* Contains file id or file url * Contains file id or file url
*/ */
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@Serializable(InputFileSerializer::class) @Serializable(InputFileSerializer::class)
data class FileId( data class FileId(
override val fileId: String override val fileId: String
@@ -92,6 +96,7 @@ object InputFileSerializer : KSerializer<InputFile> {
* *
* @see asMultipartFile * @see asMultipartFile
*/ */
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@Serializable(InputFileSerializer::class) @Serializable(InputFileSerializer::class)
data class MultipartFile ( data class MultipartFile (
val filename: String, val filename: String,
@@ -126,5 +131,5 @@ suspend inline fun ByteReadChannelAllocator.asMultipartFile(
) = this.invoke().asMultipartFile(fileName) ) = this.invoke().asMultipartFile(fileName)
expect fun MPPFile.asMultipartFile(): MultipartFile expect fun MPPFile.asMultipartFile(): MultipartFile
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE", "unused")
inline fun MPPFile.multipartFile() = asMultipartFile() inline fun MPPFile.multipartFile() = asMultipartFile()

View File

@@ -1,7 +1,5 @@
package dev.inmo.tgbotapi.requests.answers package dev.inmo.tgbotapi.requests.answers
import dev.inmo.micro_utils.common.Warning
import dev.inmo.tgbotapi.types.StartParameter
import dev.inmo.tgbotapi.types.startParameterField import dev.inmo.tgbotapi.types.startParameterField
import dev.inmo.tgbotapi.types.textField import dev.inmo.tgbotapi.types.textField
import dev.inmo.tgbotapi.types.webAppField import dev.inmo.tgbotapi.types.webAppField
@@ -29,6 +27,7 @@ sealed interface InlineQueryResultsButton {
val deepLinkParameter: String? = null val deepLinkParameter: String? = null
) )
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@Serializable(InlineQueryResultsButtonSerializer::class) @Serializable(InlineQueryResultsButtonSerializer::class)
data class WebApp( data class WebApp(
@SerialName(textField) @SerialName(textField)
@@ -37,6 +36,7 @@ sealed interface InlineQueryResultsButton {
val webAppInfo: WebAppInfo val webAppInfo: WebAppInfo
) : InlineQueryResultsButton ) : InlineQueryResultsButton
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@Serializable(InlineQueryResultsButtonSerializer::class) @Serializable(InlineQueryResultsButtonSerializer::class)
data class Start( data class Start(
@SerialName(textField) @SerialName(textField)
@@ -45,6 +45,8 @@ sealed interface InlineQueryResultsButton {
val deepLinkParameter: String val deepLinkParameter: String
) : InlineQueryResultsButton ) : InlineQueryResultsButton
@ConsistentCopyVisibility
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@Serializable(InlineQueryResultsButtonSerializer::class) @Serializable(InlineQueryResultsButtonSerializer::class)
data class Unknown internal constructor ( data class Unknown internal constructor (
@SerialName(textField) @SerialName(textField)

View File

@@ -1,14 +1,14 @@
@file:OptIn(ExperimentalSerializationApi::class)
package dev.inmo.tgbotapi.requests.business_connection package dev.inmo.tgbotapi.requests.business_connection
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
import dev.inmo.tgbotapi.types.DoubleSeconds import dev.inmo.tgbotapi.types.DoubleSeconds
import dev.inmo.tgbotapi.types.Seconds
import dev.inmo.tgbotapi.types.StickerFormat
import dev.inmo.tgbotapi.types.animationField import dev.inmo.tgbotapi.types.animationField
import dev.inmo.tgbotapi.types.mainFrameTimestampField import dev.inmo.tgbotapi.types.mainFrameTimestampField
import dev.inmo.tgbotapi.types.photoField import dev.inmo.tgbotapi.types.photoField
import dev.inmo.tgbotapi.utils.deserializeWithRaw
import kotlinx.serialization.EncodeDefault import kotlinx.serialization.EncodeDefault
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@@ -23,6 +23,7 @@ sealed interface InputProfilePhoto {
val mediaPair: Pair<String, MultipartFile> val mediaPair: Pair<String, MultipartFile>
@Serializable @Serializable
data class Static( data class Static(
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(photoField) @SerialName(photoField)
val photo: MultipartFile val photo: MultipartFile
) : InputProfilePhoto { ) : InputProfilePhoto {
@@ -33,6 +34,7 @@ sealed interface InputProfilePhoto {
} }
@Serializable @Serializable
data class Animated( data class Animated(
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(animationField) @SerialName(animationField)
val animation: MultipartFile, val animation: MultipartFile,
@SerialName(mainFrameTimestampField) @SerialName(mainFrameTimestampField)

View File

@@ -19,6 +19,7 @@ import kotlinx.serialization.builtins.serializer
data class ReadBusinessMessage( data class ReadBusinessMessage(
@SerialName(businessConnectionIdField) @SerialName(businessConnectionIdField)
override val businessConnectionId: BusinessConnectionId, override val businessConnectionId: BusinessConnectionId,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(chatIdField) @SerialName(chatIdField)
val chatId: ChatId, val chatId: ChatId,
@SerialName(messageIdField) @SerialName(messageIdField)

View File

@@ -2,21 +2,10 @@ package dev.inmo.tgbotapi.requests.business_connection
import dev.inmo.tgbotapi.requests.abstracts.BusinessRequest import dev.inmo.tgbotapi.requests.abstracts.BusinessRequest
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.Username
import dev.inmo.tgbotapi.types.businessConnectionIdField import dev.inmo.tgbotapi.types.businessConnectionIdField
import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId
import dev.inmo.tgbotapi.types.chatIdField
import dev.inmo.tgbotapi.types.firstNameField
import dev.inmo.tgbotapi.types.isPublicField import dev.inmo.tgbotapi.types.isPublicField
import dev.inmo.tgbotapi.types.lastNameField
import dev.inmo.tgbotapi.types.message.RawMessage
import dev.inmo.tgbotapi.types.messageIdField
import dev.inmo.tgbotapi.types.messageIdsField
import dev.inmo.tgbotapi.types.photoField import dev.inmo.tgbotapi.types.photoField
import dev.inmo.tgbotapi.types.usernameField
import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@@ -39,6 +28,7 @@ data class SetBusinessAccountProfilePhoto(
override val requestSerializer: SerializationStrategy<*> override val requestSerializer: SerializationStrategy<*>
get() = serializer() get() = serializer()
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
override val mediaMap: Map<String, MultipartFile> = mapOf( override val mediaMap: Map<String, MultipartFile> = mapOf(
photo.mediaPair photo.mediaPair
) )

View File

@@ -20,6 +20,7 @@ data class TransferGift(
override val businessConnectionId: BusinessConnectionId, override val businessConnectionId: BusinessConnectionId,
@SerialName(ownedGiftIdField) @SerialName(ownedGiftIdField)
val ownedGiftId: GiftId, val ownedGiftId: GiftId,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(newOwnerChatIdField) @SerialName(newOwnerChatIdField)
val newOwnerChatId: ChatId, val newOwnerChatId: ChatId,
@SerialName(starCountField) @SerialName(starCountField)

View File

@@ -18,12 +18,13 @@ sealed interface ChatJoinRequestAnswer : SimpleRequest<Boolean> {
/** /**
* Represent [approve](https://core.telegram.org/bots/api#approvechatjoinrequest) [ChatJoinRequestAnswer]. You may approve * Represent [approve](https://core.telegram.org/bots/api#approvechatjoinrequest) [ChatJoinRequestAnswer]. You may approve
* the requests retrieved in with [ChatJoinRequest] (in [dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate]) * the requests retrieved in with [dev.inmo.tgbotapi.types.chat.ChatJoinRequest] (in [dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate])
*/ */
@Serializable @Serializable
data class ApproveChatJoinRequest( data class ApproveChatJoinRequest(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
override val userId: UserId override val userId: UserId
) : ChatJoinRequestAnswer { ) : ChatJoinRequestAnswer {
@@ -35,12 +36,13 @@ data class ApproveChatJoinRequest(
/** /**
* Represent [decline](https://core.telegram.org/bots/api#declinechatjoinrequest) [ChatJoinRequestAnswer]. You may approve * Represent [decline](https://core.telegram.org/bots/api#declinechatjoinrequest) [ChatJoinRequestAnswer]. You may approve
* the requests retrieved in with [ChatJoinRequest] (in [dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate]) * the requests retrieved in with [dev.inmo.tgbotapi.types.chat.ChatJoinRequest] (in [dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate])
*/ */
@Serializable @Serializable
data class DeclineChatJoinRequest( data class DeclineChatJoinRequest(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
override val userId: UserId override val userId: UserId
) : ChatJoinRequestAnswer { ) : ChatJoinRequestAnswer {

View File

@@ -1,7 +1,9 @@
@file:OptIn(ExperimentalSerializationApi::class)
@file:Suppress("unused")
package dev.inmo.tgbotapi.requests.chat.invite_links package dev.inmo.tgbotapi.requests.chat.invite_links
import dev.inmo.tgbotapi.abstracts.types.SubscriptionInfo import dev.inmo.tgbotapi.abstracts.types.SubscriptionInfo
import dev.inmo.tgbotapi.abstracts.types.SubscriptionPeriodInfo
import korlibs.time.DateTime import korlibs.time.DateTime
import dev.inmo.tgbotapi.requests.chat.abstracts.* import dev.inmo.tgbotapi.requests.chat.abstracts.*
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*

View File

@@ -1,7 +1,9 @@
@file:OptIn(ExperimentalSerializationApi::class)
@file:Suppress("unused")
package dev.inmo.tgbotapi.requests.chat.invite_links package dev.inmo.tgbotapi.requests.chat.invite_links
import korlibs.time.DateTime import korlibs.time.DateTime
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.requests.chat.abstracts.* import dev.inmo.tgbotapi.requests.chat.abstracts.*
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import kotlinx.serialization.* import kotlinx.serialization.*

View File

@@ -10,6 +10,7 @@ import kotlinx.serialization.builtins.serializer
data class BanChatMember( data class BanChatMember(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
override val userId: UserId, override val userId: UserId,
@SerialName(untilDateField) @SerialName(untilDateField)

View File

@@ -12,6 +12,7 @@ import kotlinx.serialization.builtins.serializer
data class BanChatSenderChat( data class BanChatSenderChat(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(senderChatIdField) @SerialName(senderChatIdField)
override val senderChatId: IdChatIdentifier override val senderChatId: IdChatIdentifier
) : ChatSenderRequest { ) : ChatSenderRequest {

View File

@@ -10,6 +10,7 @@ import kotlinx.serialization.*
data class GetChatMember( data class GetChatMember(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
override val userId: UserId override val userId: UserId
) : ChatMemberRequest<ChatMember> { ) : ChatMemberRequest<ChatMember> {

View File

@@ -12,6 +12,7 @@ import kotlinx.serialization.builtins.serializer
data class PromoteChatMember( data class PromoteChatMember(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
override val userId: UserId, override val userId: UserId,
@SerialName(untilDateField) @SerialName(untilDateField)

View File

@@ -11,6 +11,7 @@ import kotlinx.serialization.builtins.serializer
data class RestrictChatMember( data class RestrictChatMember(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
override val userId: UserId, override val userId: UserId,
@SerialName(untilDateField) @SerialName(untilDateField)

View File

@@ -9,6 +9,7 @@ import kotlinx.serialization.builtins.serializer
data class SetChatAdministratorCustomTitle( data class SetChatAdministratorCustomTitle(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
override val userId: UserId, override val userId: UserId,
@SerialName(customTitleField) @SerialName(customTitleField)

View File

@@ -9,6 +9,7 @@ import kotlinx.serialization.builtins.serializer
data class UnbanChatMember( data class UnbanChatMember(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
override val userId: UserId, override val userId: UserId,
@SerialName(onlyIfBannedField) @SerialName(onlyIfBannedField)

View File

@@ -12,6 +12,7 @@ import kotlinx.serialization.builtins.serializer
data class UnbanChatSenderChat( data class UnbanChatSenderChat(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(senderChatIdField) @SerialName(senderChatIdField)
override val senderChatId: IdChatIdentifier override val senderChatId: IdChatIdentifier
) : ChatSenderRequest { ) : ChatSenderRequest {

View File

@@ -56,6 +56,7 @@ fun EditChatMessageCaption(
replyMarkup = replyMarkup replyMarkup = replyMarkup
) )
@ConsistentCopyVisibility
@Serializable @Serializable
data class EditChatMessageCaption internal constructor( data class EditChatMessageCaption internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)

View File

@@ -37,6 +37,7 @@ fun EditInlineMessageCaption(
replyMarkup replyMarkup
) )
@ConsistentCopyVisibility
@Serializable @Serializable
data class EditInlineMessageCaption internal constructor( data class EditInlineMessageCaption internal constructor(
@SerialName(inlineMessageIdField) @SerialName(inlineMessageIdField)

View File

@@ -23,6 +23,7 @@ data class EditChatMessageMedia(
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@SerialName(messageIdField) @SerialName(messageIdField)
override val messageId: MessageId, override val messageId: MessageId,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(mediaField) @SerialName(mediaField)
override val media: TelegramFreeMedia, override val media: TelegramFreeMedia,
@SerialName(businessConnectionIdField) @SerialName(businessConnectionIdField)

View File

@@ -11,6 +11,7 @@ import kotlinx.serialization.*
data class EditInlineMessageMedia( data class EditInlineMessageMedia(
@SerialName(inlineMessageIdField) @SerialName(inlineMessageIdField)
override val inlineMessageId: InlineMessageId, override val inlineMessageId: InlineMessageId,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(mediaField) @SerialName(mediaField)
override val media: TelegramFreeMedia, override val media: TelegramFreeMedia,
@SerialName(replyMarkupField) @SerialName(replyMarkupField)

View File

@@ -14,6 +14,7 @@ import kotlinx.serialization.builtins.serializer
@Serializable @Serializable
data class EditUserStarSubscription( data class EditUserStarSubscription(
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
val userId: UserId, val userId: UserId,
@SerialName(telegramPaymentChargeIdField) @SerialName(telegramPaymentChargeIdField)

View File

@@ -55,6 +55,7 @@ fun EditChatMessageText(
replyMarkup replyMarkup
) )
@ConsistentCopyVisibility
@Serializable @Serializable
data class EditChatMessageText internal constructor( data class EditChatMessageText internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)

View File

@@ -46,6 +46,7 @@ fun EditInlineMessageText(
replyMarkup = replyMarkup replyMarkup = replyMarkup
) )
@ConsistentCopyVisibility
@Serializable @Serializable
data class EditInlineMessageText internal constructor( data class EditInlineMessageText internal constructor(
@SerialName(inlineMessageIdField) @SerialName(inlineMessageIdField)

View File

@@ -7,8 +7,10 @@ import kotlinx.serialization.*
@Serializable @Serializable
data class GetGameHighScoresByChat ( data class GetGameHighScoresByChat (
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
override val userId: UserId, override val userId: UserId,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: IdChatIdentifier, override val chatId: IdChatIdentifier,
@SerialName(messageIdField) @SerialName(messageIdField)

View File

@@ -7,6 +7,7 @@ import kotlinx.serialization.*
@Serializable @Serializable
data class GetGameHighScoresByInlineMessageId ( data class GetGameHighScoresByInlineMessageId (
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
override val userId: UserId, override val userId: UserId,
@SerialName(inlineMessageIdField) @SerialName(inlineMessageIdField)

View File

@@ -7,10 +7,12 @@ import kotlinx.serialization.*
@Serializable @Serializable
data class SetGameScoreByChatId ( data class SetGameScoreByChatId (
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
override val userId: UserId, override val userId: UserId,
@SerialName(scoreField) @SerialName(scoreField)
override val score: Long, override val score: Long,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: IdChatIdentifier, override val chatId: IdChatIdentifier,
@SerialName(messageIdField) @SerialName(messageIdField)

View File

@@ -7,6 +7,7 @@ import kotlinx.serialization.*
@Serializable @Serializable
data class SetGameScoreByInlineMessageId ( data class SetGameScoreByInlineMessageId (
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
override val userId: UserId, override val userId: UserId,
@SerialName(scoreField) @SerialName(scoreField)

View File

@@ -7,6 +7,7 @@ import dev.inmo.tgbotapi.types.files.StickerSerializer
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.builtins.ListSerializer
@Suppress("UNCHECKED_CAST")
internal val getCustomEmojiStickersResultSerializer = ListSerializer(StickerSerializer) as DeserializationStrategy<List<CustomEmojiSticker>> internal val getCustomEmojiStickersResultSerializer = ListSerializer(StickerSerializer) as DeserializationStrategy<List<CustomEmojiSticker>>
@Serializable @Serializable

View File

@@ -8,6 +8,7 @@ import kotlinx.serialization.*
@Serializable @Serializable
data class GetFile( data class GetFile(
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(fileIdField) @SerialName(fileIdField)
val fileId: FileId val fileId: FileId
): SimpleRequest<PathedFile> { ): SimpleRequest<PathedFile> {

View File

@@ -13,6 +13,7 @@ import kotlinx.serialization.SerializationStrategy
data class GetUserChatBoosts( data class GetUserChatBoosts(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
val userId: UserId val userId: UserId
) : SimpleRequest<UserChatBoosts>, ChatRequest { ) : SimpleRequest<UserChatBoosts>, ChatRequest {

View File

@@ -6,6 +6,7 @@ import kotlinx.serialization.*
@Serializable @Serializable
data class GetUserProfilePhotos( data class GetUserProfilePhotos(
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
val userId: UserId, val userId: UserId,
@SerialName(offsetField) @SerialName(offsetField)

View File

@@ -21,8 +21,10 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer
@ConsistentCopyVisibility
@Serializable @Serializable
data class GiftPremiumSubscription internal constructor( data class GiftPremiumSubscription internal constructor(
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
val userId: UserId, val userId: UserId,
@SerialName(monthCountField) @SerialName(monthCountField)

View File

@@ -6,7 +6,6 @@ import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.message.ParseMode import dev.inmo.tgbotapi.types.message.ParseMode
import dev.inmo.tgbotapi.types.message.RawMessageEntity import dev.inmo.tgbotapi.types.message.RawMessageEntity
import dev.inmo.tgbotapi.types.message.asTextSources import dev.inmo.tgbotapi.types.message.asTextSources
import dev.inmo.tgbotapi.types.message.textsources.TextSource
import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList
import dev.inmo.tgbotapi.types.message.toRawMessageEntities import dev.inmo.tgbotapi.types.message.toRawMessageEntities
import dev.inmo.tgbotapi.utils.extensions.makeSourceString import dev.inmo.tgbotapi.utils.extensions.makeSourceString
@@ -16,8 +15,10 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer
@ConsistentCopyVisibility
@Serializable @Serializable
data class SendGift internal constructor( data class SendGift internal constructor(
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
val userId: UserId? = null, val userId: UserId? = null,
@SerialName(chatIdField) @SerialName(chatIdField)

View File

@@ -12,6 +12,7 @@ import kotlinx.serialization.SerializationStrategy
@Serializable @Serializable
data class SavePreparedInlineMessage( data class SavePreparedInlineMessage(
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
val userId: UserId, val userId: UserId,
@Serializable(InlineQueryResultSerializer::class) @Serializable(InlineQueryResultSerializer::class)

View File

@@ -1,8 +1,9 @@
@file:Suppress("unused")
package dev.inmo.tgbotapi.requests.send package dev.inmo.tgbotapi.requests.send
import dev.inmo.tgbotapi.abstracts.TextedOutput import dev.inmo.tgbotapi.abstracts.TextedOutput
import dev.inmo.tgbotapi.abstracts.WithCustomStartMediaData import dev.inmo.tgbotapi.abstracts.WithCustomStartMediaData
import dev.inmo.tgbotapi.abstracts.WithCustomizableCaption
import dev.inmo.tgbotapi.abstracts.types.MessageAction import dev.inmo.tgbotapi.abstracts.types.MessageAction
import dev.inmo.tgbotapi.abstracts.types.ProtectContent import dev.inmo.tgbotapi.abstracts.types.ProtectContent
import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
@@ -10,7 +11,6 @@ import dev.inmo.tgbotapi.requests.send.abstracts.OptionallyMessageThreadRequest
import dev.inmo.tgbotapi.requests.send.abstracts.ReplyingMarkupSendMessageRequest import dev.inmo.tgbotapi.requests.send.abstracts.ReplyingMarkupSendMessageRequest
import dev.inmo.tgbotapi.requests.send.abstracts.WithCustomizableCaptionRequest import dev.inmo.tgbotapi.requests.send.abstracts.WithCustomizableCaptionRequest
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId
import dev.inmo.tgbotapi.types.message.textsources.TextSource import dev.inmo.tgbotapi.types.message.textsources.TextSource
import dev.inmo.tgbotapi.types.message.ParseMode import dev.inmo.tgbotapi.types.message.ParseMode
import dev.inmo.tgbotapi.types.message.parseModeField import dev.inmo.tgbotapi.types.message.parseModeField
@@ -143,6 +143,7 @@ fun CopyMessage(
replyMarkup = replyMarkup replyMarkup = replyMarkup
) )
@ConsistentCopyVisibility
@Serializable @Serializable
data class CopyMessage internal constructor( data class CopyMessage internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)

View File

@@ -78,6 +78,7 @@ fun SendTextMessage(
replyMarkup = replyMarkup replyMarkup = replyMarkup
) )
@ConsistentCopyVisibility
@Serializable @Serializable
data class SendTextMessage internal constructor( data class SendTextMessage internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)

View File

@@ -1,3 +1,5 @@
@file:Suppress("FunctionName")
package dev.inmo.tgbotapi.requests.send.media package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.requests.abstracts.* import dev.inmo.tgbotapi.requests.abstracts.*
@@ -133,6 +135,7 @@ fun SendAnimation(
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<AnimationContent>> private val commonResultDeserializer: DeserializationStrategy<ContentMessage<AnimationContent>>
= TelegramBotAPIMessageDeserializationStrategyClass() = TelegramBotAPIMessageDeserializationStrategyClass()
@ConsistentCopyVisibility
@Serializable @Serializable
data class SendAnimationData internal constructor( data class SendAnimationData internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)
@@ -202,6 +205,8 @@ data class SendAnimationData internal constructor(
get() = serializer() get() = serializer()
} }
@Suppress("unused")
@ConsistentCopyVisibility
data class SendAnimationFiles internal constructor( data class SendAnimationFiles internal constructor(
val animation: MultipartFile? = null, val animation: MultipartFile? = null,
val thumbnail: MultipartFile? = null val thumbnail: MultipartFile? = null

View File

@@ -1,3 +1,5 @@
@file:Suppress("FunctionName")
package dev.inmo.tgbotapi.requests.send.media package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.abstracts.Performerable import dev.inmo.tgbotapi.abstracts.Performerable
@@ -126,6 +128,7 @@ fun SendAudio(
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<AudioContent>> private val commonResultDeserializer: DeserializationStrategy<ContentMessage<AudioContent>>
= TelegramBotAPIMessageDeserializationStrategyClass() = TelegramBotAPIMessageDeserializationStrategyClass()
@ConsistentCopyVisibility
@Serializable @Serializable
data class SendAudioData internal constructor( data class SendAudioData internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)
@@ -190,6 +193,8 @@ data class SendAudioData internal constructor(
get() = serializer() get() = serializer()
} }
@Suppress("unused")
@ConsistentCopyVisibility
data class SendAudioFiles internal constructor( data class SendAudioFiles internal constructor(
val audio: MultipartFile? = null, val audio: MultipartFile? = null,
val thumbnail: MultipartFile? = null val thumbnail: MultipartFile? = null

View File

@@ -1,3 +1,5 @@
@file:Suppress("unused", "FunctionName")
package dev.inmo.tgbotapi.requests.send.media package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.requests.abstracts.* import dev.inmo.tgbotapi.requests.abstracts.*
@@ -144,6 +146,7 @@ private val commonResultDeserializer: DeserializationStrategy<ContentMessage<Doc
* @see ContentMessage * @see ContentMessage
* @see DocumentContent * @see DocumentContent
*/ */
@ConsistentCopyVisibility
@Serializable @Serializable
data class SendDocumentData internal constructor( data class SendDocumentData internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)
@@ -201,6 +204,7 @@ data class SendDocumentData internal constructor(
get() = serializer() get() = serializer()
} }
@ConsistentCopyVisibility
data class SendDocumentFiles internal constructor( data class SendDocumentFiles internal constructor(
val document: MultipartFile? = null, val document: MultipartFile? = null,
val thumbnail: MultipartFile? = null val thumbnail: MultipartFile? = null

View File

@@ -1,3 +1,5 @@
@file:Suppress("FunctionName", "DuplicatedCode")
package dev.inmo.tgbotapi.requests.send.media package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
@@ -72,6 +74,7 @@ fun <T : MediaGroupPartContent> SendMediaGroup(
replyParameters = replyParameters replyParameters = replyParameters
) )
@Suppress("UNCHECKED_CAST")
return (if (files.isEmpty()) { return (if (files.isEmpty()) {
data data
} else { } else {
@@ -182,6 +185,7 @@ private object MessagesListSerializer: KSerializer<PossiblySentViaBotCommonMessa
} }
@ConsistentCopyVisibility
@Serializable @Serializable
data class SendMediaGroupData internal constructor( data class SendMediaGroupData internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)
@@ -203,6 +207,7 @@ data class SendMediaGroupData internal constructor(
override val replyParameters: ReplyParameters? = null, override val replyParameters: ReplyParameters? = null,
) : DataRequest<PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>>>, ) : DataRequest<PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>>>,
SendContentMessageRequest<PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>>> { SendContentMessageRequest<PossiblySentViaBotCommonMessage<MediaGroupContent<MediaGroupPartContent>>> {
@Suppress("unused")
@SerialName(mediaField) @SerialName(mediaField)
private val convertedMedia: String private val convertedMedia: String
get() = buildJsonArray { get() = buildJsonArray {
@@ -219,6 +224,8 @@ data class SendMediaGroupData internal constructor(
get() = MessagesListSerializer get() = MessagesListSerializer
} }
@Suppress("unused")
@ConsistentCopyVisibility
data class SendMediaGroupFiles internal constructor( data class SendMediaGroupFiles internal constructor(
val files: List<MultipartFile> val files: List<MultipartFile>
) : Files by (files.map { it.fileId to it }.toMap()) ) : Files by (files.associateBy { it.fileId })

View File

@@ -1,3 +1,5 @@
@file:Suppress("FunctionName")
package dev.inmo.tgbotapi.requests.send.media package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.types.media.TelegramPaidMedia import dev.inmo.tgbotapi.types.media.TelegramPaidMedia
@@ -145,12 +147,14 @@ fun SendPaidMedia(
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<PaidMediaInfoContent>> private val commonResultDeserializer: DeserializationStrategy<ContentMessage<PaidMediaInfoContent>>
= TelegramBotAPIMessageDeserializationStrategyClass() = TelegramBotAPIMessageDeserializationStrategyClass()
@ConsistentCopyVisibility
@Serializable @Serializable
data class SendPaidMediaData internal constructor( data class SendPaidMediaData internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: ChatIdentifier, override val chatId: ChatIdentifier,
@SerialName(starCountField) @SerialName(starCountField)
val starCount: Int, val starCount: Int,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(mediaField) @SerialName(mediaField)
val media: List<TelegramPaidMedia>, val media: List<TelegramPaidMedia>,
@SerialName(captionField) @SerialName(captionField)
@@ -204,6 +208,8 @@ data class SendPaidMediaData internal constructor(
get() = serializer() get() = serializer()
} }
@Suppress("unused")
@ConsistentCopyVisibility
data class SendPaidMediaFiles internal constructor( data class SendPaidMediaFiles internal constructor(
val photo: MultipartFile val photo: MultipartFile
) : Files by mapOf( ) : Files by mapOf(

View File

@@ -1,3 +1,5 @@
@file:Suppress("FunctionName")
package dev.inmo.tgbotapi.requests.send.media package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.requests.abstracts.* import dev.inmo.tgbotapi.requests.abstracts.*
@@ -109,6 +111,7 @@ fun SendPhoto(
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<PhotoContent>> private val commonResultDeserializer: DeserializationStrategy<ContentMessage<PhotoContent>>
= TelegramBotAPIMessageDeserializationStrategyClass() = TelegramBotAPIMessageDeserializationStrategyClass()
@ConsistentCopyVisibility
@Serializable @Serializable
data class SendPhotoData internal constructor( data class SendPhotoData internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)
@@ -167,6 +170,8 @@ data class SendPhotoData internal constructor(
get() = serializer() get() = serializer()
} }
@Suppress("unused")
@ConsistentCopyVisibility
data class SendPhotoFiles internal constructor( data class SendPhotoFiles internal constructor(
val photo: MultipartFile val photo: MultipartFile
) : Files by mapOf( ) : Files by mapOf(

View File

@@ -13,6 +13,7 @@ import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializ
import dev.inmo.tgbotapi.types.message.content.StickerContent import dev.inmo.tgbotapi.types.message.content.StickerContent
import kotlinx.serialization.* import kotlinx.serialization.*
@Suppress("FunctionName")
fun SendSticker( fun SendSticker(
chatId: ChatIdentifier, chatId: ChatIdentifier,
sticker: InputFile, sticker: InputFile,
@@ -50,6 +51,7 @@ fun SendSticker(
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<StickerContent>> private val commonResultDeserializer: DeserializationStrategy<ContentMessage<StickerContent>>
= TelegramBotAPIMessageDeserializationStrategyClass() = TelegramBotAPIMessageDeserializationStrategyClass()
@ConsistentCopyVisibility
@Serializable @Serializable
data class SendStickerByFileId internal constructor( data class SendStickerByFileId internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)

View File

@@ -1,3 +1,5 @@
@file:Suppress("FunctionName")
package dev.inmo.tgbotapi.requests.send.media package dev.inmo.tgbotapi.requests.send.media
import dev.inmo.tgbotapi.abstracts.WithCustomStartMediaData import dev.inmo.tgbotapi.abstracts.WithCustomStartMediaData
@@ -148,6 +150,7 @@ fun SendVideo(
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<VideoContent>> private val commonResultDeserializer: DeserializationStrategy<ContentMessage<VideoContent>>
= TelegramBotAPIMessageDeserializationStrategyClass() = TelegramBotAPIMessageDeserializationStrategyClass()
@ConsistentCopyVisibility
@Serializable @Serializable
data class SendVideoData internal constructor( data class SendVideoData internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)
@@ -225,6 +228,8 @@ data class SendVideoData internal constructor(
get() = serializer() get() = serializer()
} }
@Suppress("unused")
@ConsistentCopyVisibility
data class SendVideoFiles internal constructor( data class SendVideoFiles internal constructor(
val video: MultipartFile? = null, val video: MultipartFile? = null,
val thumbnail: MultipartFile? = null val thumbnail: MultipartFile? = null

View File

@@ -13,6 +13,7 @@ import dev.inmo.tgbotapi.types.message.content.VideoNoteContent
import dev.inmo.tgbotapi.utils.mapOfNotNull import dev.inmo.tgbotapi.utils.mapOfNotNull
import kotlinx.serialization.* import kotlinx.serialization.*
@Suppress("FunctionName")
fun SendVideoNote( fun SendVideoNote(
chatId: ChatIdentifier, chatId: ChatIdentifier,
videoNote: InputFile, videoNote: InputFile,
@@ -60,6 +61,7 @@ fun SendVideoNote(
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<VideoNoteContent>> private val commonResultDeserializer: DeserializationStrategy<ContentMessage<VideoNoteContent>>
= TelegramBotAPIMessageDeserializationStrategyClass() = TelegramBotAPIMessageDeserializationStrategyClass()
@ConsistentCopyVisibility
@Serializable @Serializable
data class SendVideoNoteData internal constructor( data class SendVideoNoteData internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)
@@ -105,6 +107,8 @@ data class SendVideoNoteData internal constructor(
get() = serializer() get() = serializer()
} }
@Suppress("unused")
@ConsistentCopyVisibility
data class SendVideoNoteFiles internal constructor( data class SendVideoNoteFiles internal constructor(
val videoNote: MultipartFile? = null, val videoNote: MultipartFile? = null,
val thumbnail: MultipartFile? = null val thumbnail: MultipartFile? = null

View File

@@ -111,6 +111,7 @@ fun SendVoice(
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<VoiceContent>> private val commonResultDeserializer: DeserializationStrategy<ContentMessage<VoiceContent>>
= TelegramBotAPIMessageDeserializationStrategyClass() = TelegramBotAPIMessageDeserializationStrategyClass()
@ConsistentCopyVisibility
@Serializable @Serializable
data class SendVoiceData internal constructor( data class SendVoiceData internal constructor(
@SerialName(chatIdField) @SerialName(chatIdField)
@@ -166,6 +167,8 @@ data class SendVoiceData internal constructor(
get() = serializer() get() = serializer()
} }
@Suppress("unused")
@ConsistentCopyVisibility
data class SendVoiceFiles internal constructor( data class SendVoiceFiles internal constructor(
val voice: MultipartFile? = null, val voice: MultipartFile? = null,
val thumbnail: MultipartFile? = null val thumbnail: MultipartFile? = null

View File

@@ -8,6 +8,7 @@ import kotlinx.serialization.builtins.serializer
@Serializable @Serializable
data class RefundStarPayment( data class RefundStarPayment(
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(userIdField) @SerialName(userIdField)
val userId: UserId, val userId: UserId,
@SerialName(telegramPaymentChargeIdField) @SerialName(telegramPaymentChargeIdField)

View File

@@ -5,7 +5,6 @@ import dev.inmo.tgbotapi.abstracts.types.*
import dev.inmo.tgbotapi.requests.send.abstracts.OptionallyWithEffectRequest import dev.inmo.tgbotapi.requests.send.abstracts.OptionallyWithEffectRequest
import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest import dev.inmo.tgbotapi.requests.send.abstracts.SendMessageRequest
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.business_connection.BusinessConnectionId
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass import dev.inmo.tgbotapi.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
@@ -24,6 +23,7 @@ private val invoiceMessageSerializer: DeserializationStrategy<ContentMessage<Inv
*/ */
@Serializable @Serializable
data class SendInvoice( data class SendInvoice(
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
@SerialName(chatIdField) @SerialName(chatIdField)
override val chatId: IdChatIdentifier, override val chatId: IdChatIdentifier,
@SerialName(titleField) @SerialName(titleField)

Some files were not shown because too many files have changed in this diff Show More