mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-11-22 08:13:47 +00:00
commit
103dd949ce
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,5 +1,18 @@
|
|||||||
# TelegramBotAPI changelog
|
# TelegramBotAPI changelog
|
||||||
|
|
||||||
|
## 5.1.0
|
||||||
|
|
||||||
|
[Bot API 6.5](https://core.telegram.org/bots/api-changelog#february-3-2023) support
|
||||||
|
|
||||||
|
* `Core`:
|
||||||
|
* `ChatPermissions` now is interface and have two main realizations: `ChatPermissions.Granular` and
|
||||||
|
`ChatPermissions.Common`
|
||||||
|
* `RestrictedChatMember` now implements `ChatPermissions` too
|
||||||
|
* `API`:
|
||||||
|
* Now it is possible to pass all long polling parameters in all places used it
|
||||||
|
* `Issues`:
|
||||||
|
* Fix of [#697](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/697)
|
||||||
|
|
||||||
## 5.0.2
|
## 5.0.2
|
||||||
|
|
||||||
* `Versions`:
|
* `Versions`:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# TelegramBotAPI [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [![Supported version](https://img.shields.io/badge/Telegram%20Bot%20API-6.4-blue)](https://core.telegram.org/bots/api-changelog#december-30-2022)
|
# TelegramBotAPI [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi) [![Supported version](https://img.shields.io/badge/Telegram%20Bot%20API-6.5-blue)](https://core.telegram.org/bots/api-changelog#february-3-2023)
|
||||||
|
|
||||||
| Docs | [![KDocs](https://img.shields.io/static/v1?label=Dokka&message=KDocs&color=blue&logo=kotlin)](https://tgbotapi.inmo.dev/index.html) [![Mini tutorial](https://img.shields.io/static/v1?label=Bookstack&message=Tutorial&color=blue&logo=bookstack)](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
|
| Docs | [![KDocs](https://img.shields.io/static/v1?label=Dokka&message=KDocs&color=blue&logo=kotlin)](https://tgbotapi.inmo.dev/index.html) [![Mini tutorial](https://img.shields.io/static/v1?label=Bookstack&message=Tutorial&color=blue&logo=bookstack)](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
|
||||||
|:---:|:---:|
|
|:---:|:---:|
|
||||||
|
@ -6,4 +6,4 @@ kotlin.incremental=true
|
|||||||
kotlin.incremental.js=true
|
kotlin.incremental.js=true
|
||||||
|
|
||||||
library_group=dev.inmo
|
library_group=dev.inmo
|
||||||
library_version=5.0.2
|
library_version=5.1.0
|
||||||
|
@ -14,27 +14,31 @@ suspend fun TelegramBot.restrictChatMember(
|
|||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
userId: UserId,
|
userId: UserId,
|
||||||
untilDate: TelegramDate? = null,
|
untilDate: TelegramDate? = null,
|
||||||
permissions: ChatPermissions = ChatPermissions()
|
permissions: ChatPermissions = ChatPermissions(),
|
||||||
) = execute(RestrictChatMember(chatId, userId, untilDate, permissions))
|
useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||||
|
) = execute(RestrictChatMember(chatId, userId, untilDate, permissions, useIndependentChatPermissions))
|
||||||
|
|
||||||
suspend fun TelegramBot.restrictChatMember(
|
suspend fun TelegramBot.restrictChatMember(
|
||||||
chat: PublicChat,
|
chat: PublicChat,
|
||||||
userId: UserId,
|
userId: UserId,
|
||||||
untilDate: TelegramDate? = null,
|
untilDate: TelegramDate? = null,
|
||||||
permissions: ChatPermissions = ChatPermissions()
|
permissions: ChatPermissions = ChatPermissions(),
|
||||||
) = restrictChatMember(chat.id, userId, untilDate, permissions)
|
useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||||
|
) = restrictChatMember(chat.id, userId, untilDate, permissions, useIndependentChatPermissions)
|
||||||
|
|
||||||
suspend fun TelegramBot.restrictChatMember(
|
suspend fun TelegramBot.restrictChatMember(
|
||||||
chatId: IdChatIdentifier,
|
chatId: IdChatIdentifier,
|
||||||
user: User,
|
user: User,
|
||||||
untilDate: TelegramDate? = null,
|
untilDate: TelegramDate? = null,
|
||||||
permissions: ChatPermissions = ChatPermissions()
|
permissions: ChatPermissions = ChatPermissions(),
|
||||||
) = restrictChatMember(chatId, user.id, untilDate, permissions)
|
useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||||
|
) = restrictChatMember(chatId, user.id, untilDate, permissions, useIndependentChatPermissions)
|
||||||
|
|
||||||
suspend fun TelegramBot.restrictChatMember(
|
suspend fun TelegramBot.restrictChatMember(
|
||||||
chat: PublicChat,
|
chat: PublicChat,
|
||||||
user: User,
|
user: User,
|
||||||
untilDate: TelegramDate? = null,
|
untilDate: TelegramDate? = null,
|
||||||
permissions: ChatPermissions = ChatPermissions()
|
permissions: ChatPermissions = ChatPermissions(),
|
||||||
) = restrictChatMember(chat.id, user.id, untilDate, permissions)
|
useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||||
|
) = restrictChatMember(chat.id, user.id, untilDate, permissions, useIndependentChatPermissions)
|
||||||
|
|
||||||
|
@ -8,10 +8,12 @@ import dev.inmo.tgbotapi.types.chat.PublicChat
|
|||||||
|
|
||||||
suspend fun TelegramBot.setDefaultChatMembersPermissions(
|
suspend fun TelegramBot.setDefaultChatMembersPermissions(
|
||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
permissions: ChatPermissions
|
permissions: ChatPermissions,
|
||||||
) = execute(SetChatPermissions(chatId, permissions))
|
useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||||
|
) = execute(SetChatPermissions(chatId, permissions, useIndependentChatPermissions))
|
||||||
|
|
||||||
suspend fun TelegramBot.setDefaultChatMembersPermissions(
|
suspend fun TelegramBot.setDefaultChatMembersPermissions(
|
||||||
chat: PublicChat,
|
chat: PublicChat,
|
||||||
permissions: ChatPermissions
|
permissions: ChatPermissions,
|
||||||
) = setDefaultChatMembersPermissions(chat.id, permissions)
|
useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||||
|
) = setDefaultChatMembersPermissions(chat.id, permissions, useIndependentChatPermissions)
|
||||||
|
@ -8,6 +8,7 @@ import dev.inmo.micro_utils.fsm.common.utils.StateHandlingErrorHandler
|
|||||||
import dev.inmo.micro_utils.fsm.common.utils.defaultStateHandlingErrorHandler
|
import dev.inmo.micro_utils.fsm.common.utils.defaultStateHandlingErrorHandler
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.longPolling
|
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.longPolling
|
||||||
|
import dev.inmo.tgbotapi.types.Seconds
|
||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
@ -54,6 +55,9 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
|
|||||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
||||||
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
|
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
|
||||||
|
timeoutSeconds: Seconds = 30,
|
||||||
|
autoDisableWebhooks: Boolean = true,
|
||||||
|
autoSkipTimeoutExceptions: Boolean = true,
|
||||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
||||||
): Pair<DefaultBehaviourContextWithFSM<T>, Job> = buildBehaviourWithFSM(
|
): Pair<DefaultBehaviourContextWithFSM<T>, Job> = buildBehaviourWithFSM(
|
||||||
upstreamUpdatesFlow,
|
upstreamUpdatesFlow,
|
||||||
@ -66,7 +70,7 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
|
|||||||
).run {
|
).run {
|
||||||
this to scope.launch {
|
this to scope.launch {
|
||||||
start()
|
start()
|
||||||
longPolling(flowsUpdatesFilter, scope = scope)
|
longPolling(flowsUpdatesFilter, timeoutSeconds, scope, autoDisableWebhooks, autoSkipTimeoutExceptions, defaultExceptionsHandler)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,6 +128,9 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
|
|||||||
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
statesManager: StatesManager<T> = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
|
||||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
||||||
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
|
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
|
||||||
|
timeoutSeconds: Seconds = 30,
|
||||||
|
autoDisableWebhooks: Boolean = true,
|
||||||
|
autoSkipTimeoutExceptions: Boolean = true,
|
||||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
||||||
) = FlowsUpdatesFilter().let {
|
) = FlowsUpdatesFilter().let {
|
||||||
buildBehaviourWithFSM(
|
buildBehaviourWithFSM(
|
||||||
@ -138,7 +145,11 @@ suspend fun <T : State> TelegramBot.buildBehaviourWithFSMAndStartLongPolling(
|
|||||||
start()
|
start()
|
||||||
longPolling(
|
longPolling(
|
||||||
flowsUpdatesFilter,
|
flowsUpdatesFilter,
|
||||||
scope = scope
|
timeoutSeconds,
|
||||||
|
scope,
|
||||||
|
autoDisableWebhooks,
|
||||||
|
autoSkipTimeoutExceptions,
|
||||||
|
defaultExceptionsHandler
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutorBuilder
|
|||||||
import dev.inmo.tgbotapi.bot.ktor.telegramBot
|
import dev.inmo.tgbotapi.bot.ktor.telegramBot
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
|
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
|
||||||
|
import dev.inmo.tgbotapi.types.Seconds
|
||||||
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
||||||
import dev.inmo.tgbotapi.utils.telegramBotAPIDefaultUrl
|
import dev.inmo.tgbotapi.utils.telegramBotAPIDefaultUrl
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -42,6 +43,9 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSM(
|
|||||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
||||||
testServer: Boolean = false,
|
testServer: Boolean = false,
|
||||||
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
|
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
|
||||||
|
timeoutSeconds: Seconds = 30,
|
||||||
|
autoDisableWebhooks: Boolean = true,
|
||||||
|
autoSkipTimeoutExceptions: Boolean = true,
|
||||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
||||||
): TelegramBot = telegramBot(
|
): TelegramBot = telegramBot(
|
||||||
token,
|
token,
|
||||||
@ -56,6 +60,9 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSM(
|
|||||||
statesManager,
|
statesManager,
|
||||||
presetHandlers,
|
presetHandlers,
|
||||||
onStateHandlingErrorHandler,
|
onStateHandlingErrorHandler,
|
||||||
|
timeoutSeconds,
|
||||||
|
autoDisableWebhooks,
|
||||||
|
autoSkipTimeoutExceptions,
|
||||||
block
|
block
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -81,6 +88,9 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSMAndStartLongPolling(
|
|||||||
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
presetHandlers: List<BehaviourWithFSMStateHandlerHolder<*, T>> = listOf(),
|
||||||
testServer: Boolean = false,
|
testServer: Boolean = false,
|
||||||
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
|
onStateHandlingErrorHandler: StateHandlingErrorHandler<T> = defaultStateHandlingErrorHandler(),
|
||||||
|
timeoutSeconds: Seconds = 30,
|
||||||
|
autoDisableWebhooks: Boolean = true,
|
||||||
|
autoSkipTimeoutExceptions: Boolean = true,
|
||||||
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
block: CustomBehaviourContextReceiver<DefaultBehaviourContextWithFSM<T>, Unit>
|
||||||
): Pair<TelegramBot, Job> {
|
): Pair<TelegramBot, Job> {
|
||||||
return telegramBot(
|
return telegramBot(
|
||||||
@ -95,6 +105,9 @@ suspend fun <T : State> telegramBotWithBehaviourAndFSMAndStartLongPolling(
|
|||||||
statesManager,
|
statesManager,
|
||||||
presetHandlers,
|
presetHandlers,
|
||||||
onStateHandlingErrorHandler,
|
onStateHandlingErrorHandler,
|
||||||
|
timeoutSeconds,
|
||||||
|
autoDisableWebhooks,
|
||||||
|
autoSkipTimeoutExceptions,
|
||||||
block
|
block
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import dev.inmo.micro_utils.coroutines.ExceptionHandler
|
|||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.longPolling
|
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.longPolling
|
||||||
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
|
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
|
||||||
|
import dev.inmo.tgbotapi.types.Seconds
|
||||||
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
|
||||||
@ -53,6 +54,9 @@ suspend fun TelegramBot.buildBehaviour(
|
|||||||
suspend fun TelegramBot.buildBehaviourWithLongPolling(
|
suspend fun TelegramBot.buildBehaviourWithLongPolling(
|
||||||
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
scope: CoroutineScope = defaultCoroutineScopeProvider(),
|
||||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
|
timeoutSeconds: Seconds = 30,
|
||||||
|
autoDisableWebhooks: Boolean = true,
|
||||||
|
autoSkipTimeoutExceptions: Boolean = true,
|
||||||
block: BehaviourContextReceiver<Unit>
|
block: BehaviourContextReceiver<Unit>
|
||||||
): Job {
|
): Job {
|
||||||
val behaviourContext = buildBehaviour(
|
val behaviourContext = buildBehaviour(
|
||||||
@ -62,6 +66,9 @@ suspend fun TelegramBot.buildBehaviourWithLongPolling(
|
|||||||
)
|
)
|
||||||
return longPolling(
|
return longPolling(
|
||||||
behaviourContext,
|
behaviourContext,
|
||||||
scope = behaviourContext
|
scope = behaviourContext,
|
||||||
|
timeoutSeconds = timeoutSeconds,
|
||||||
|
autoDisableWebhooks = autoDisableWebhooks,
|
||||||
|
autoSkipTimeoutExceptions = autoSkipTimeoutExceptions
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import dev.inmo.tgbotapi.bot.TelegramBot
|
|||||||
import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutorBuilder
|
import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutorBuilder
|
||||||
import dev.inmo.tgbotapi.bot.ktor.telegramBot
|
import dev.inmo.tgbotapi.bot.ktor.telegramBot
|
||||||
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
|
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
|
||||||
|
import dev.inmo.tgbotapi.types.Seconds
|
||||||
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
|
||||||
import dev.inmo.tgbotapi.utils.telegramBotAPIDefaultUrl
|
import dev.inmo.tgbotapi.utils.telegramBotAPIDefaultUrl
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
@ -66,6 +67,9 @@ suspend fun telegramBotWithBehaviourAndLongPolling(
|
|||||||
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
builder: KtorRequestsExecutorBuilder.() -> Unit = {},
|
||||||
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
defaultExceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
testServer: Boolean = false,
|
testServer: Boolean = false,
|
||||||
|
timeoutSeconds: Seconds = 30,
|
||||||
|
autoDisableWebhooks: Boolean = true,
|
||||||
|
autoSkipTimeoutExceptions: Boolean = true,
|
||||||
block: BehaviourContextReceiver<Unit>
|
block: BehaviourContextReceiver<Unit>
|
||||||
): Pair<TelegramBot, Job> {
|
): Pair<TelegramBot, Job> {
|
||||||
return telegramBot(
|
return telegramBot(
|
||||||
@ -77,6 +81,9 @@ suspend fun telegramBotWithBehaviourAndLongPolling(
|
|||||||
it to it.buildBehaviourWithLongPolling(
|
it to it.buildBehaviourWithLongPolling(
|
||||||
scope ?: CoroutineScope(coroutineContext),
|
scope ?: CoroutineScope(coroutineContext),
|
||||||
defaultExceptionsHandler,
|
defaultExceptionsHandler,
|
||||||
|
timeoutSeconds,
|
||||||
|
autoDisableWebhooks,
|
||||||
|
autoSkipTimeoutExceptions,
|
||||||
block
|
block
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,9 @@ import dev.inmo.tgbotapi.types.message.ChatEvents.forum.WriteAccessAllowed
|
|||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.*
|
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.*
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
||||||
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
|
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
|
||||||
|
import dev.inmo.tgbotapi.types.request.ChatShared
|
||||||
|
import dev.inmo.tgbotapi.types.request.ChatSharedRequest
|
||||||
|
import dev.inmo.tgbotapi.types.request.UserShared
|
||||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
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
|
||||||
@ -171,3 +174,18 @@ suspend fun BehaviourContext.waitWriteAccessAllowed(
|
|||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitEvents<WriteAccessAllowed>(initRequest, errorFactory)
|
) = waitEvents<WriteAccessAllowed>(initRequest, errorFactory)
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.waitChatSharedRequest(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitEvents<ChatSharedRequest>(initRequest, errorFactory)
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.waitUserShared(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitEvents<UserShared>(initRequest, errorFactory)
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.waitChatShared(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitEvents<ChatShared>(initRequest, errorFactory)
|
||||||
|
@ -9,10 +9,17 @@ import dev.inmo.tgbotapi.types.message.ChatEvents.*
|
|||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
|
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.*
|
||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicClosed
|
import dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicClosed
|
||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicCreated
|
import dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicCreated
|
||||||
|
import dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicEdited
|
||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicReopened
|
import dev.inmo.tgbotapi.types.message.ChatEvents.forum.ForumTopicReopened
|
||||||
|
import dev.inmo.tgbotapi.types.message.ChatEvents.forum.GeneralForumTopicHidden
|
||||||
|
import dev.inmo.tgbotapi.types.message.ChatEvents.forum.GeneralForumTopicUnhidden
|
||||||
|
import dev.inmo.tgbotapi.types.message.ChatEvents.forum.WriteAccessAllowed
|
||||||
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.*
|
import dev.inmo.tgbotapi.types.message.ChatEvents.voice.*
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
||||||
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
|
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
|
||||||
|
import dev.inmo.tgbotapi.types.request.ChatShared
|
||||||
|
import dev.inmo.tgbotapi.types.request.ChatSharedRequest
|
||||||
|
import dev.inmo.tgbotapi.types.request.UserShared
|
||||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
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
|
||||||
@ -148,3 +155,34 @@ suspend fun BehaviourContext.waitForumTopicReopenedEventsMessages(
|
|||||||
initRequest: Request<*>? = null,
|
initRequest: Request<*>? = null,
|
||||||
errorFactory: NullableRequestBuilder<*> = { null }
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
) = waitEventsMessages<ForumTopicReopened>(initRequest, errorFactory)
|
) = waitEventsMessages<ForumTopicReopened>(initRequest, errorFactory)
|
||||||
|
suspend fun BehaviourContext.waitForumTopicEditedEventsMessages(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitEventsMessages<ForumTopicEdited>(initRequest, errorFactory)
|
||||||
|
suspend fun BehaviourContext.waitGeneralForumTopicHiddenEventsMessages(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitEventsMessages<GeneralForumTopicHidden>(initRequest, errorFactory)
|
||||||
|
suspend fun BehaviourContext.waitGeneralForumTopicUnhiddenEventsMessages(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitEventsMessages<GeneralForumTopicUnhidden>(initRequest, errorFactory)
|
||||||
|
suspend fun BehaviourContext.waitWriteAccessAllowedEventsMessages(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitEventsMessages<WriteAccessAllowed>(initRequest, errorFactory)
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.waitChatSharedRequestEventsMessages(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitEventsMessages<ChatSharedRequest>(initRequest, errorFactory)
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.waitUserSharedEventsMessages(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitEventsMessages<UserShared>(initRequest, errorFactory)
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.waitChatSharedEventsMessages(
|
||||||
|
initRequest: Request<*>? = null,
|
||||||
|
errorFactory: NullableRequestBuilder<*> = { null }
|
||||||
|
) = waitEventsMessages<ChatShared>(initRequest, errorFactory)
|
||||||
|
@ -23,6 +23,9 @@ import dev.inmo.tgbotapi.types.message.PrivateEventMessage
|
|||||||
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.SupergroupEventMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.SupergroupEventMessage
|
||||||
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
|
import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent
|
||||||
|
import dev.inmo.tgbotapi.types.request.ChatShared
|
||||||
|
import dev.inmo.tgbotapi.types.request.ChatSharedRequest
|
||||||
|
import dev.inmo.tgbotapi.types.request.UserShared
|
||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
|
|
||||||
internal suspend inline fun <BC : BehaviourContext, reified T : ChatEvent> BC.onEvent(
|
internal suspend inline fun <BC : BehaviourContext, reified T : ChatEvent> BC.onEvent(
|
||||||
@ -657,3 +660,65 @@ suspend fun <BC : BehaviourContext> BC.onWriteAccessAllowed(
|
|||||||
markerFactory: MarkerFactory<in ChatEventMessage<WriteAccessAllowed>, Any> = ByChatMessageMarkerFactory,
|
markerFactory: MarkerFactory<in ChatEventMessage<WriteAccessAllowed>, Any> = ByChatMessageMarkerFactory,
|
||||||
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, SupergroupEventMessage<WriteAccessAllowed>>
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, SupergroupEventMessage<WriteAccessAllowed>>
|
||||||
) = onEventWithCustomChatEventMessage(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
) = onEventWithCustomChatEventMessage(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||||
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
|
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
|
||||||
|
* to combinate several filters
|
||||||
|
* @param markerFactory Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
|
||||||
|
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
|
||||||
|
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||||
|
* data
|
||||||
|
*/
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onChatSharedRequest(
|
||||||
|
initialFilter: SimpleFilter<PrivateEventMessage<ChatSharedRequest>>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PrivateEventMessage<ChatSharedRequest>, Update>? = MessageFilterByChat,
|
||||||
|
markerFactory: MarkerFactory<in ChatEventMessage<ChatSharedRequest>, Any> = ByChatMessageMarkerFactory,
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PrivateEventMessage<ChatSharedRequest>>
|
||||||
|
) = onEventWithCustomChatEventMessage(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||||
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
|
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
|
||||||
|
* to combinate several filters
|
||||||
|
* @param markerFactory Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
|
||||||
|
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
|
||||||
|
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||||
|
* data
|
||||||
|
*/
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onUserShared(
|
||||||
|
initialFilter: SimpleFilter<PrivateEventMessage<UserShared>>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PrivateEventMessage<UserShared>, Update>? = MessageFilterByChat,
|
||||||
|
markerFactory: MarkerFactory<in ChatEventMessage<UserShared>, Any> = ByChatMessageMarkerFactory,
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PrivateEventMessage<UserShared>>
|
||||||
|
) = onEventWithCustomChatEventMessage(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param initialFilter This filter will be called to remove unnecessary data BEFORE [scenarioReceiver] call
|
||||||
|
* @param subcontextUpdatesFilter This filter will be applied to each update inside of [scenarioReceiver]. For example,
|
||||||
|
* this filter will be used if you will call [dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitContentMessage].
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextAndTwoTypesReceiver] function to create your own.
|
||||||
|
* Use [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.plus] or [dev.inmo.tgbotapi.extensions.behaviour_builder.utils.times]
|
||||||
|
* to combinate several filters
|
||||||
|
* @param markerFactory Will be used to identify different "stream". [scenarioReceiver] will be called synchronously
|
||||||
|
* in one "stream". Output of [markerFactory] will be used as a key for "stream"
|
||||||
|
* @param scenarioReceiver Main callback which will be used to handle incoming data if [initialFilter] will pass that
|
||||||
|
* data
|
||||||
|
*/
|
||||||
|
suspend fun <BC : BehaviourContext> BC.onChatShared(
|
||||||
|
initialFilter: SimpleFilter<PrivateEventMessage<ChatShared>>? = null,
|
||||||
|
subcontextUpdatesFilter: CustomBehaviourContextAndTwoTypesReceiver<BC, Boolean, PrivateEventMessage<ChatShared>, Update>? = MessageFilterByChat,
|
||||||
|
markerFactory: MarkerFactory<in ChatEventMessage<ChatShared>, Any> = ByChatMessageMarkerFactory,
|
||||||
|
scenarioReceiver: CustomBehaviourContextAndTypeReceiver<BC, Unit, PrivateEventMessage<ChatShared>>
|
||||||
|
) = onEventWithCustomChatEventMessage(initialFilter, subcontextUpdatesFilter, markerFactory, scenarioReceiver)
|
||||||
|
@ -16,7 +16,9 @@ data class RestrictChatMember(
|
|||||||
@SerialName(untilDateField)
|
@SerialName(untilDateField)
|
||||||
override val untilDate: TelegramDate? = null,
|
override val untilDate: TelegramDate? = null,
|
||||||
@SerialName(permissionsField)
|
@SerialName(permissionsField)
|
||||||
val permissions: ChatPermissions = ChatPermissions()
|
val permissions: ChatPermissions = ChatPermissions(),
|
||||||
|
@SerialName(useIndependentChatPermissionsField)
|
||||||
|
val useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||||
) : ChatMemberRequest<Boolean>, UntilDate {
|
) : ChatMemberRequest<Boolean>, UntilDate {
|
||||||
override fun method(): String = "restrictChatMember"
|
override fun method(): String = "restrictChatMember"
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
|
@ -12,7 +12,9 @@ data class SetChatPermissions (
|
|||||||
@SerialName(chatIdField)
|
@SerialName(chatIdField)
|
||||||
override val chatId: ChatIdentifier,
|
override val chatId: ChatIdentifier,
|
||||||
@SerialName(permissionsField)
|
@SerialName(permissionsField)
|
||||||
val permissions: ChatPermissions
|
val permissions: ChatPermissions,
|
||||||
|
@SerialName(useIndependentChatPermissionsField)
|
||||||
|
val useIndependentChatPermissions: Boolean? = permissions.isGranular.takeIf { it }
|
||||||
): ChatRequest, SimpleRequest<Boolean> {
|
): ChatRequest, SimpleRequest<Boolean> {
|
||||||
override fun method(): String = "setChatPermissions"
|
override fun method(): String = "setChatPermissions"
|
||||||
override val resultDeserializer: DeserializationStrategy<Boolean>
|
override val resultDeserializer: DeserializationStrategy<Boolean>
|
||||||
|
@ -261,6 +261,19 @@ const val iconColorField = "icon_color"
|
|||||||
const val requestContactField = "request_contact"
|
const val requestContactField = "request_contact"
|
||||||
const val requestLocationField = "request_location"
|
const val requestLocationField = "request_location"
|
||||||
const val requestPollField = "request_poll"
|
const val requestPollField = "request_poll"
|
||||||
|
const val requestUserField = "request_user"
|
||||||
|
const val requestChatField = "request_chat"
|
||||||
|
const val requestIdField = "request_id"
|
||||||
|
|
||||||
|
const val userIsBotField = "user_is_bot"
|
||||||
|
const val userIsPremiumField = "user_is_premium"
|
||||||
|
const val chatIsChannelField = "chat_is_channel"
|
||||||
|
const val chatIsForumField = "chat_is_forum"
|
||||||
|
const val chatHasUsernameField = "chat_has_username"
|
||||||
|
const val chatIsCreatedField = "chat_is_created"
|
||||||
|
const val userAdministratorRightsField = "user_administrator_rights"
|
||||||
|
const val botAdministratorRightsField = "bot_administrator_rights"
|
||||||
|
const val botIsMemberField = "bot_is_member"
|
||||||
|
|
||||||
const val fileNameField = "file_name"
|
const val fileNameField = "file_name"
|
||||||
const val mimeTypeField = "mime_type"
|
const val mimeTypeField = "mime_type"
|
||||||
@ -327,7 +340,12 @@ const val scopeField = "scope"
|
|||||||
const val isMemberField = "is_member"
|
const val isMemberField = "is_member"
|
||||||
const val isForumField = "is_forum"
|
const val isForumField = "is_forum"
|
||||||
const val canSendMessagesField = "can_send_messages"
|
const val canSendMessagesField = "can_send_messages"
|
||||||
const val canSendMediaMessagesField = "can_send_media_messages"
|
const val canSendAudiosField = "can_send_audios"
|
||||||
|
const val canSendDocumentsField = "can_send_documents"
|
||||||
|
const val canSendPhotosField = "can_send_photos"
|
||||||
|
const val canSendVideosField = "can_send_videos"
|
||||||
|
const val canSendVideoNotesField = "can_send_video_notes"
|
||||||
|
const val canSendVoiceNotesField = "can_send_voice_notes"
|
||||||
const val canSendOtherMessagesField = "can_send_other_messages"
|
const val canSendOtherMessagesField = "can_send_other_messages"
|
||||||
const val canSendPollsField = "can_send_polls"
|
const val canSendPollsField = "can_send_polls"
|
||||||
const val canAddWebPagePreviewsField = "can_add_web_page_previews"
|
const val canAddWebPagePreviewsField = "can_add_web_page_previews"
|
||||||
@ -345,6 +363,7 @@ const val canPinMessagesField = "can_pin_messages"
|
|||||||
const val canPromoteMembersField = "can_promote_members"
|
const val canPromoteMembersField = "can_promote_members"
|
||||||
const val canManageVoiceChatsField = "can_manage_voice_chats"
|
const val canManageVoiceChatsField = "can_manage_voice_chats"
|
||||||
const val canManageVideoChatsField = "can_manage_video_chats"
|
const val canManageVideoChatsField = "can_manage_video_chats"
|
||||||
|
const val useIndependentChatPermissionsField = "use_independent_chat_permissions"
|
||||||
const val rightsField = "rights"
|
const val rightsField = "rights"
|
||||||
const val forChannelsField = "for_channels"
|
const val forChannelsField = "for_channels"
|
||||||
const val canManageChatField = "can_manage_chat"
|
const val canManageChatField = "can_manage_chat"
|
||||||
@ -375,6 +394,7 @@ const val latitudeField = "latitude"
|
|||||||
const val longitudeField = "longitude"
|
const val longitudeField = "longitude"
|
||||||
const val headingField = "heading"
|
const val headingField = "heading"
|
||||||
const val fromField = "from"
|
const val fromField = "from"
|
||||||
|
const val userChatIdField = "user_chat_id"
|
||||||
const val userField = "user"
|
const val userField = "user"
|
||||||
const val dateField = "date"
|
const val dateField = "date"
|
||||||
const val chatField = "chat"
|
const val chatField = "chat"
|
||||||
|
@ -94,6 +94,42 @@ data class RequestPollKeyboardButton(
|
|||||||
val requestPoll: KeyboardButtonPollType
|
val requestPoll: KeyboardButtonPollType
|
||||||
) : KeyboardButton
|
) : KeyboardButton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private chats only. When user will tap on this button, he will be asked for the chat with [requestChat] options. You
|
||||||
|
* will be able to catch this [ChatId] in updates and data using
|
||||||
|
* [dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onUserShared] in case you are using Behaviour
|
||||||
|
* Builder OR with [dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter.messagesFlow]
|
||||||
|
* and [kotlinx.coroutines.flow.filterIsInstance].
|
||||||
|
*
|
||||||
|
* In case you will use [dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onUserShared] it is
|
||||||
|
* recommended to use [kotlinx.coroutines.flow.Flow] [kotlinx.coroutines.flow.filter] with checking of incoming
|
||||||
|
* [dev.inmo.tgbotapi.types.request.UserShared.requestId]
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
|
data class RequestUserKeyboardButton(
|
||||||
|
override val text: String,
|
||||||
|
@SerialName(requestUserField)
|
||||||
|
val requestUser: KeyboardButtonRequestUser
|
||||||
|
) : KeyboardButton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private chats only. When user will tap on this button, he will be asked for the chat with [requestChat] options. You
|
||||||
|
* will be able to catch this [ChatId] in updates and data using
|
||||||
|
* [dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onChatShared] in case you are using Behaviour
|
||||||
|
* Builder OR with [dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter.messagesFlow]
|
||||||
|
* and [kotlinx.coroutines.flow.filterIsInstance].
|
||||||
|
*
|
||||||
|
* In case you will use [dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onChatShared] it is
|
||||||
|
* recommended to use [kotlinx.coroutines.flow.Flow] [kotlinx.coroutines.flow.filter] with checking of incoming
|
||||||
|
* [dev.inmo.tgbotapi.types.request.ChatShared.requestId]
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
|
data class RequestChatKeyboardButton(
|
||||||
|
override val text: String,
|
||||||
|
@SerialName(requestChatField)
|
||||||
|
val requestChat: KeyboardButtonRequestChat
|
||||||
|
) : KeyboardButton
|
||||||
|
|
||||||
@RiskFeature
|
@RiskFeature
|
||||||
object KeyboardButtonSerializer : KSerializer<KeyboardButton> {
|
object KeyboardButtonSerializer : KSerializer<KeyboardButton> {
|
||||||
private val internalSerializer = JsonElement.serializer()
|
private val internalSerializer = JsonElement.serializer()
|
||||||
@ -124,6 +160,20 @@ object KeyboardButtonSerializer : KSerializer<KeyboardButton> {
|
|||||||
asJson[requestPollField] ?.jsonObject ?: buildJsonObject { }
|
asJson[requestPollField] ?.jsonObject ?: buildJsonObject { }
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
asJson is JsonObject && asJson[requestUserField] != null -> RequestUserKeyboardButton(
|
||||||
|
asJson[textField]!!.jsonPrimitive.content,
|
||||||
|
nonstrictJsonFormat.decodeFromJsonElement(
|
||||||
|
KeyboardButtonRequestUser.serializer(),
|
||||||
|
asJson[requestUserField] ?.jsonObject ?: buildJsonObject { }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
asJson is JsonObject && asJson[requestChatField] != null -> RequestChatKeyboardButton(
|
||||||
|
asJson[textField]!!.jsonPrimitive.content,
|
||||||
|
nonstrictJsonFormat.decodeFromJsonElement(
|
||||||
|
KeyboardButtonRequestChat.serializer(),
|
||||||
|
asJson[requestChatField] ?.jsonObject ?: buildJsonObject { }
|
||||||
|
)
|
||||||
|
)
|
||||||
else -> UnknownKeyboardButton(
|
else -> UnknownKeyboardButton(
|
||||||
when (asJson) {
|
when (asJson) {
|
||||||
is JsonObject -> asJson[textField]!!.jsonPrimitive.content
|
is JsonObject -> asJson[textField]!!.jsonPrimitive.content
|
||||||
@ -142,6 +192,8 @@ object KeyboardButtonSerializer : KSerializer<KeyboardButton> {
|
|||||||
is WebAppKeyboardButton -> WebAppKeyboardButton.serializer().serialize(encoder, value)
|
is WebAppKeyboardButton -> WebAppKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is RequestPollKeyboardButton -> RequestPollKeyboardButton.serializer().serialize(encoder, value)
|
is RequestPollKeyboardButton -> RequestPollKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is SimpleKeyboardButton -> encoder.encodeString(value.text)
|
is SimpleKeyboardButton -> encoder.encodeString(value.text)
|
||||||
|
is RequestUserKeyboardButton -> RequestUserKeyboardButton.serializer().serialize(encoder, value)
|
||||||
|
is RequestChatKeyboardButton -> RequestChatKeyboardButton.serializer().serialize(encoder, value)
|
||||||
is UnknownKeyboardButton -> JsonElement.serializer().serialize(encoder, nonstrictJsonFormat.parseToJsonElement(value.raw))
|
is UnknownKeyboardButton -> JsonElement.serializer().serialize(encoder, nonstrictJsonFormat.parseToJsonElement(value.raw))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.buttons
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.botAdministratorRightsField
|
||||||
|
import dev.inmo.tgbotapi.types.botIsMemberField
|
||||||
|
import dev.inmo.tgbotapi.types.chat.member.ChatAdministratorRights
|
||||||
|
import dev.inmo.tgbotapi.types.chatHasUsernameField
|
||||||
|
import dev.inmo.tgbotapi.types.chatIsChannelField
|
||||||
|
import dev.inmo.tgbotapi.types.chatIsCreatedField
|
||||||
|
import dev.inmo.tgbotapi.types.chatIsForumField
|
||||||
|
import dev.inmo.tgbotapi.types.request.RequestId
|
||||||
|
import dev.inmo.tgbotapi.types.requestIdField
|
||||||
|
import dev.inmo.tgbotapi.types.userAdministratorRightsField
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Channel
|
||||||
|
* @see Group
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
|
data class KeyboardButtonRequestChat(
|
||||||
|
@SerialName(requestIdField)
|
||||||
|
val requestId: RequestId,
|
||||||
|
@SerialName(chatIsChannelField)
|
||||||
|
val isChannel: Boolean? = null,
|
||||||
|
@SerialName(chatIsForumField)
|
||||||
|
val isForum: Boolean? = null,
|
||||||
|
@SerialName(chatHasUsernameField)
|
||||||
|
val isPublic: Boolean? = null,
|
||||||
|
@SerialName(chatIsCreatedField)
|
||||||
|
val isOwnedBy: Boolean? = null,
|
||||||
|
@SerialName(userAdministratorRightsField)
|
||||||
|
val userRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
@SerialName(botAdministratorRightsField)
|
||||||
|
val botRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
@SerialName(botIsMemberField)
|
||||||
|
val botIsMember: Boolean? = null
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun Channel(
|
||||||
|
requestId: RequestId,
|
||||||
|
isPublic: Boolean? = null,
|
||||||
|
isOwnedBy: Boolean? = null,
|
||||||
|
userRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botIsMember: Boolean? = null
|
||||||
|
) = KeyboardButtonRequestChat(
|
||||||
|
requestId = requestId,
|
||||||
|
isChannel = true,
|
||||||
|
isForum = null,
|
||||||
|
isPublic = isPublic,
|
||||||
|
isOwnedBy = isOwnedBy,
|
||||||
|
userRightsInChat = userRightsInChat,
|
||||||
|
botRightsInChat = botRightsInChat,
|
||||||
|
botIsMember = botIsMember
|
||||||
|
)
|
||||||
|
|
||||||
|
fun Group(
|
||||||
|
requestId: RequestId,
|
||||||
|
isForum: Boolean? = null,
|
||||||
|
isPublic: Boolean? = null,
|
||||||
|
isOwnedBy: Boolean? = null,
|
||||||
|
userRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botIsMember: Boolean? = null
|
||||||
|
) = KeyboardButtonRequestChat(
|
||||||
|
requestId = requestId,
|
||||||
|
isChannel = false,
|
||||||
|
isForum = isForum,
|
||||||
|
isPublic = isPublic,
|
||||||
|
isOwnedBy = isOwnedBy,
|
||||||
|
userRightsInChat = userRightsInChat,
|
||||||
|
botRightsInChat = botRightsInChat,
|
||||||
|
botIsMember = botIsMember
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,91 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.buttons
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.request.RequestId
|
||||||
|
import dev.inmo.tgbotapi.types.requestIdField
|
||||||
|
import dev.inmo.tgbotapi.types.userIsBotField
|
||||||
|
import dev.inmo.tgbotapi.types.userIsPremiumField
|
||||||
|
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
|
||||||
|
import kotlinx.serialization.EncodeDefault
|
||||||
|
import kotlinx.serialization.KSerializer
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.Serializer
|
||||||
|
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||||
|
import kotlinx.serialization.encoding.Decoder
|
||||||
|
import kotlinx.serialization.encoding.Encoder
|
||||||
|
|
||||||
|
@Serializable(KeyboardButtonRequestUser.Companion::class)
|
||||||
|
@ClassCastsIncluded
|
||||||
|
sealed interface KeyboardButtonRequestUser {
|
||||||
|
val requestId: RequestId
|
||||||
|
val isBot: Boolean?
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Any(
|
||||||
|
@SerialName(requestIdField)
|
||||||
|
override val requestId: RequestId
|
||||||
|
) : KeyboardButtonRequestUser {
|
||||||
|
@SerialName(userIsBotField)
|
||||||
|
@EncodeDefault
|
||||||
|
override val isBot: Boolean? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Common(
|
||||||
|
@SerialName(requestIdField)
|
||||||
|
override val requestId: RequestId,
|
||||||
|
@SerialName(userIsPremiumField)
|
||||||
|
val isPremium: Boolean? = null
|
||||||
|
) : KeyboardButtonRequestUser {
|
||||||
|
@SerialName(userIsBotField)
|
||||||
|
@EncodeDefault
|
||||||
|
override val isBot: Boolean = false
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Bot(
|
||||||
|
@SerialName(requestIdField)
|
||||||
|
override val requestId: RequestId
|
||||||
|
) : KeyboardButtonRequestUser {
|
||||||
|
@SerialName(userIsBotField)
|
||||||
|
@EncodeDefault
|
||||||
|
override val isBot: Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializer(KeyboardButtonRequestUser::class)
|
||||||
|
companion object : KSerializer<KeyboardButtonRequestUser> {
|
||||||
|
@Serializable
|
||||||
|
private data class Surrogate(
|
||||||
|
@SerialName(requestIdField)
|
||||||
|
val requestId: RequestId,
|
||||||
|
@SerialName(userIsBotField)
|
||||||
|
val userIsBot: Boolean? = null,
|
||||||
|
@SerialName(userIsPremiumField)
|
||||||
|
val userIsPremium: Boolean? = null
|
||||||
|
)
|
||||||
|
private val realSerializer = Surrogate.serializer()
|
||||||
|
|
||||||
|
override val descriptor: SerialDescriptor = realSerializer.descriptor
|
||||||
|
|
||||||
|
override fun deserialize(decoder: Decoder): KeyboardButtonRequestUser {
|
||||||
|
val surrogate = realSerializer.deserialize(decoder)
|
||||||
|
|
||||||
|
return when (surrogate.userIsBot) {
|
||||||
|
true -> Bot(surrogate.requestId)
|
||||||
|
false -> Common(surrogate.requestId, surrogate.userIsPremium)
|
||||||
|
null -> Any(surrogate.requestId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(encoder: Encoder, value: KeyboardButtonRequestUser) {
|
||||||
|
realSerializer.serialize(
|
||||||
|
encoder,
|
||||||
|
Surrogate(
|
||||||
|
value.requestId,
|
||||||
|
value.isBot,
|
||||||
|
(value as? Common) ?.isPremium
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,8 @@ package dev.inmo.tgbotapi.types.buttons.reply
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.types.buttons.*
|
import dev.inmo.tgbotapi.types.buttons.*
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.*
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.*
|
||||||
|
import dev.inmo.tgbotapi.types.chat.member.ChatAdministratorRights
|
||||||
|
import dev.inmo.tgbotapi.types.request.RequestId
|
||||||
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
|
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
|
||||||
|
|
||||||
|
|
||||||
@ -67,3 +69,161 @@ inline fun webAppReplyButton(
|
|||||||
text: String,
|
text: String,
|
||||||
url: String
|
url: String
|
||||||
) = webAppReplyButton(text, WebAppInfo(url))
|
) = webAppReplyButton(text, WebAppInfo(url))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestUserKeyboardButton]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun requestUserReplyButton(
|
||||||
|
text: String,
|
||||||
|
requestUser: KeyboardButtonRequestUser
|
||||||
|
) = RequestUserKeyboardButton(
|
||||||
|
text,
|
||||||
|
requestUser
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Bot]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun requestBotReplyButton(
|
||||||
|
text: String,
|
||||||
|
requestId: RequestId
|
||||||
|
) = requestUserReplyButton(
|
||||||
|
text,
|
||||||
|
KeyboardButtonRequestUser.Bot(requestId)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Common]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun requestUserReplyButton(
|
||||||
|
text: String,
|
||||||
|
requestId: RequestId,
|
||||||
|
premiumUser: Boolean? = null
|
||||||
|
) = requestUserReplyButton(
|
||||||
|
text,
|
||||||
|
KeyboardButtonRequestUser.Common(requestId, premiumUser)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Any]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun requestUserOrBotReplyButton(
|
||||||
|
text: String,
|
||||||
|
requestId: RequestId
|
||||||
|
) = requestUserReplyButton(
|
||||||
|
text,
|
||||||
|
KeyboardButtonRequestUser.Any(requestId)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestChatKeyboardButton]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun requestChatReplyButton(
|
||||||
|
text: String,
|
||||||
|
requestChat: KeyboardButtonRequestChat
|
||||||
|
) = RequestChatKeyboardButton(
|
||||||
|
text,
|
||||||
|
requestChat
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestChatKeyboardButton] with [KeyboardButtonRequestChat]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun requestChatReplyButton(
|
||||||
|
text: String,
|
||||||
|
requestId: RequestId,
|
||||||
|
isChannel: Boolean? = null,
|
||||||
|
isForum: Boolean? = null,
|
||||||
|
isPublic: Boolean? = null,
|
||||||
|
isOwnedBy: Boolean? = null,
|
||||||
|
userRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botIsMember: Boolean = false
|
||||||
|
) = requestChatReplyButton(
|
||||||
|
text,
|
||||||
|
KeyboardButtonRequestChat(
|
||||||
|
requestId = requestId,
|
||||||
|
isChannel = isChannel,
|
||||||
|
isForum = isForum,
|
||||||
|
isPublic = isPublic,
|
||||||
|
isOwnedBy = isOwnedBy,
|
||||||
|
userRightsInChat = userRightsInChat,
|
||||||
|
botRightsInChat = botRightsInChat,
|
||||||
|
botIsMember = botIsMember
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestChatKeyboardButton] with [KeyboardButtonRequestChat.Channel]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun requestChannelReplyButton(
|
||||||
|
text: String,
|
||||||
|
requestId: RequestId,
|
||||||
|
isPublic: Boolean? = null,
|
||||||
|
isOwnedBy: Boolean? = null,
|
||||||
|
userRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botIsMember: Boolean = false
|
||||||
|
) = requestChatReplyButton(
|
||||||
|
text,
|
||||||
|
KeyboardButtonRequestChat.Channel(
|
||||||
|
requestId = requestId,
|
||||||
|
isPublic = isPublic,
|
||||||
|
isOwnedBy = isOwnedBy,
|
||||||
|
userRightsInChat = userRightsInChat,
|
||||||
|
botRightsInChat = botRightsInChat,
|
||||||
|
botIsMember = botIsMember
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestChatKeyboardButton] with [KeyboardButtonRequestChat.Group]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun requestChannelReplyButton(
|
||||||
|
text: String,
|
||||||
|
requestId: RequestId,
|
||||||
|
isForum: Boolean? = null,
|
||||||
|
isPublic: Boolean? = null,
|
||||||
|
isOwnedBy: Boolean? = null,
|
||||||
|
userRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botIsMember: Boolean? = null
|
||||||
|
) = requestChatReplyButton(
|
||||||
|
text,
|
||||||
|
KeyboardButtonRequestChat.Group(
|
||||||
|
requestId = requestId,
|
||||||
|
isForum = isForum,
|
||||||
|
isPublic = isPublic,
|
||||||
|
isOwnedBy = isOwnedBy,
|
||||||
|
userRightsInChat = userRightsInChat,
|
||||||
|
botRightsInChat = botRightsInChat,
|
||||||
|
botIsMember = botIsMember
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@ -15,6 +15,8 @@ data class ChatJoinRequest(
|
|||||||
val chat: PublicChat,
|
val chat: PublicChat,
|
||||||
@SerialName(fromField)
|
@SerialName(fromField)
|
||||||
override val from: User,
|
override val from: User,
|
||||||
|
@SerialName(userChatIdField)
|
||||||
|
val userChatId: UserId,
|
||||||
@SerialName(dateField)
|
@SerialName(dateField)
|
||||||
val date: TelegramDate,
|
val date: TelegramDate,
|
||||||
@SerialName(inviteLinkField)
|
@SerialName(inviteLinkField)
|
||||||
|
@ -1,32 +1,259 @@
|
|||||||
package dev.inmo.tgbotapi.types.chat
|
package dev.inmo.tgbotapi.types.chat
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.Transient
|
||||||
|
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||||
|
import kotlinx.serialization.encoding.Decoder
|
||||||
|
import kotlinx.serialization.encoding.Encoder
|
||||||
|
|
||||||
@Serializable
|
/**
|
||||||
data class ChatPermissions(
|
* Represents any type with common permissions list
|
||||||
@SerialName(canSendMessagesField)
|
*
|
||||||
val canSendMessages: Boolean = false,
|
* !!WARNING!! Default serializer of this interface is using [Granular] as surrogate and in fact serialized
|
||||||
@SerialName(canSendMediaMessagesField)
|
* and deserialized as [Granular]. In case you wish some custom behaviour you must implement your own
|
||||||
val canSendMediaMessages: Boolean = false,
|
* [KSerializer] or pass another serializer
|
||||||
@SerialName(canSendPollsField)
|
*/
|
||||||
val canSendPolls: Boolean = false,
|
@Serializable(ChatPermissions.Companion::class)
|
||||||
@SerialName(canSendOtherMessagesField)
|
interface ChatPermissions {
|
||||||
val canSendOtherMessages: Boolean = false,
|
val canSendMessages: Boolean?
|
||||||
@SerialName(canAddWebPagePreviewsField)
|
val canSendAudios: Boolean?
|
||||||
val canAddWebPagePreviews: Boolean = false,
|
val canSendDocuments: Boolean?
|
||||||
@SerialName(canChangeInfoField)
|
val canSendPhotos: Boolean?
|
||||||
val canChangeInfo: Boolean = false,
|
val canSendVideos: Boolean?
|
||||||
@SerialName(canInviteUsersField)
|
val canSendVideoNotes: Boolean?
|
||||||
val canInviteUsers: Boolean = false,
|
val canSendVoiceNotes: Boolean?
|
||||||
@SerialName(canPinMessagesField)
|
val canSendPolls: Boolean?
|
||||||
val canPinMessages: Boolean = false
|
val canSendOtherMessages: Boolean?
|
||||||
)
|
val canAddWebPagePreviews: Boolean?
|
||||||
|
val canChangeInfo: Boolean?
|
||||||
|
val canInviteUsers: Boolean?
|
||||||
|
val canPinMessages: Boolean?
|
||||||
|
@Transient
|
||||||
|
val isGranular
|
||||||
|
get() = canSendAudios != null ||
|
||||||
|
canSendDocuments != null ||
|
||||||
|
canSendVideoNotes != null ||
|
||||||
|
canSendPhotos != null ||
|
||||||
|
canSendVideos != null ||
|
||||||
|
canSendVoiceNotes != null
|
||||||
|
val canSendStickers: Boolean?
|
||||||
|
get() = canSendOtherMessages
|
||||||
|
val canSendGifs: Boolean?
|
||||||
|
get() = canSendStickers
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Granular(
|
||||||
|
@SerialName(canSendMessagesField)
|
||||||
|
override val canSendMessages: Boolean? = null,
|
||||||
|
@SerialName(canSendAudiosField)
|
||||||
|
override val canSendAudios: Boolean? = null,
|
||||||
|
@SerialName(canSendDocumentsField)
|
||||||
|
override val canSendDocuments: Boolean? = null,
|
||||||
|
@SerialName(canSendPhotosField)
|
||||||
|
override val canSendPhotos: Boolean? = null,
|
||||||
|
@SerialName(canSendVideosField)
|
||||||
|
override val canSendVideos: Boolean? = null,
|
||||||
|
@SerialName(canSendVideoNotesField)
|
||||||
|
override val canSendVideoNotes: Boolean? = null,
|
||||||
|
@SerialName(canSendVoiceNotesField)
|
||||||
|
override val canSendVoiceNotes: Boolean? = null,
|
||||||
|
@SerialName(canSendPollsField)
|
||||||
|
override val canSendPolls: Boolean? = null,
|
||||||
|
@SerialName(canSendOtherMessagesField)
|
||||||
|
override val canSendOtherMessages: Boolean? = null,
|
||||||
|
@SerialName(canAddWebPagePreviewsField)
|
||||||
|
override val canAddWebPagePreviews: Boolean? = null,
|
||||||
|
@SerialName(canChangeInfoField)
|
||||||
|
override val canChangeInfo: Boolean? = null,
|
||||||
|
@SerialName(canInviteUsersField)
|
||||||
|
override val canInviteUsers: Boolean? = null,
|
||||||
|
@SerialName(canPinMessagesField)
|
||||||
|
override val canPinMessages: Boolean? = null
|
||||||
|
) : ChatPermissions {
|
||||||
|
@Transient
|
||||||
|
override val isGranular: Boolean
|
||||||
|
get() = true
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Common(
|
||||||
|
@SerialName(canSendPollsField)
|
||||||
|
override val canSendPolls: Boolean? = null,
|
||||||
|
@SerialName(canSendOtherMessagesField)
|
||||||
|
override val canSendOtherMessages: Boolean? = null,
|
||||||
|
@SerialName(canAddWebPagePreviewsField)
|
||||||
|
override val canAddWebPagePreviews: Boolean? = null,
|
||||||
|
@SerialName(canChangeInfoField)
|
||||||
|
override val canChangeInfo: Boolean? = null,
|
||||||
|
@SerialName(canInviteUsersField)
|
||||||
|
override val canInviteUsers: Boolean? = null,
|
||||||
|
@SerialName(canPinMessagesField)
|
||||||
|
override val canPinMessages: Boolean? = null
|
||||||
|
) : ChatPermissions {
|
||||||
|
@Transient
|
||||||
|
override val isGranular: Boolean
|
||||||
|
get() = false
|
||||||
|
@Transient
|
||||||
|
override val canSendMessages: Boolean? = canSendOtherMessages ?.let {
|
||||||
|
it && (canAddWebPagePreviews ?: return@let null)
|
||||||
|
}
|
||||||
|
@Transient
|
||||||
|
override val canSendAudios: Boolean?
|
||||||
|
get() = canSendMessages
|
||||||
|
@Transient
|
||||||
|
override val canSendDocuments: Boolean?
|
||||||
|
get() = canSendMessages
|
||||||
|
@Transient
|
||||||
|
override val canSendPhotos: Boolean?
|
||||||
|
get() = canSendMessages
|
||||||
|
@Transient
|
||||||
|
override val canSendVideos: Boolean?
|
||||||
|
get() = canSendMessages
|
||||||
|
@Transient
|
||||||
|
override val canSendVideoNotes: Boolean?
|
||||||
|
get() = canSendMessages
|
||||||
|
@Transient
|
||||||
|
override val canSendVoiceNotes: Boolean?
|
||||||
|
get() = canSendMessages
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object : KSerializer<ChatPermissions> {
|
||||||
|
operator fun invoke(
|
||||||
|
canSendMessages: Boolean? = null,
|
||||||
|
canSendAudios: Boolean? = null,
|
||||||
|
canSendDocuments: Boolean? = null,
|
||||||
|
canSendPhotos: Boolean? = null,
|
||||||
|
canSendVideos: Boolean? = null,
|
||||||
|
canSendVideoNotes: Boolean? = null,
|
||||||
|
canSendVoiceNotes: Boolean? = null,
|
||||||
|
canSendPolls: Boolean? = null,
|
||||||
|
canSendOtherMessages: Boolean? = null,
|
||||||
|
canAddWebPagePreviews: Boolean? = null,
|
||||||
|
canChangeInfo: Boolean? = null,
|
||||||
|
canInviteUsers: Boolean? = null,
|
||||||
|
canPinMessages: Boolean? = null
|
||||||
|
) = Granular(
|
||||||
|
canSendMessages = canSendMessages,
|
||||||
|
canSendAudios = canSendAudios,
|
||||||
|
canSendDocuments = canSendDocuments,
|
||||||
|
canSendPhotos = canSendPhotos,
|
||||||
|
canSendVideos = canSendVideos,
|
||||||
|
canSendVideoNotes = canSendVideoNotes,
|
||||||
|
canSendVoiceNotes = canSendVoiceNotes,
|
||||||
|
canSendPolls = canSendPolls,
|
||||||
|
canSendOtherMessages = canSendOtherMessages,
|
||||||
|
canAddWebPagePreviews = canAddWebPagePreviews,
|
||||||
|
canChangeInfo = canChangeInfo,
|
||||||
|
canInviteUsers = canInviteUsers,
|
||||||
|
canPinMessages = canPinMessages
|
||||||
|
)
|
||||||
|
|
||||||
|
private val realSerializer = Granular.serializer()
|
||||||
|
private val commonSerializer = Common.serializer()
|
||||||
|
override val descriptor: SerialDescriptor
|
||||||
|
get() = realSerializer.descriptor
|
||||||
|
|
||||||
|
override fun deserialize(decoder: Decoder): ChatPermissions {
|
||||||
|
return realSerializer.deserialize(decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(encoder: Encoder, value: ChatPermissions) {
|
||||||
|
realSerializer.serialize(
|
||||||
|
encoder,
|
||||||
|
(value as? Granular) ?: value.run {
|
||||||
|
Granular(
|
||||||
|
canSendMessages = canSendMessages,
|
||||||
|
canSendAudios = canSendAudios,
|
||||||
|
canSendDocuments = canSendDocuments,
|
||||||
|
canSendPhotos = canSendPhotos,
|
||||||
|
canSendVideos = canSendVideos,
|
||||||
|
canSendVideoNotes = canSendVideoNotes,
|
||||||
|
canSendVoiceNotes = canSendVoiceNotes,
|
||||||
|
canSendPolls = canSendPolls,
|
||||||
|
canSendOtherMessages = canSendOtherMessages,
|
||||||
|
canAddWebPagePreviews = canAddWebPagePreviews,
|
||||||
|
canChangeInfo = canChangeInfo,
|
||||||
|
canInviteUsers = canInviteUsers,
|
||||||
|
canPinMessages = canPinMessages
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copying current instance as [ChatPermissions], but realizations of this interface may differently override this
|
||||||
|
* method
|
||||||
|
*/
|
||||||
|
fun copyGranular(
|
||||||
|
canSendMessages: Boolean? = this.canSendMessages,
|
||||||
|
canSendAudios: Boolean? = this.canSendAudios,
|
||||||
|
canSendDocuments: Boolean? = this.canSendDocuments,
|
||||||
|
canSendPhotos: Boolean? = this.canSendPhotos,
|
||||||
|
canSendVideos: Boolean? = this.canSendVideos,
|
||||||
|
canSendVideoNotes: Boolean? = this.canSendVideoNotes,
|
||||||
|
canSendVoiceNotes: Boolean? = this.canSendVoiceNotes,
|
||||||
|
canSendPolls: Boolean? = this.canSendPolls,
|
||||||
|
canSendOtherMessages: Boolean? = this.canSendOtherMessages,
|
||||||
|
canAddWebPagePreviews: Boolean? = this.canAddWebPagePreviews,
|
||||||
|
canChangeInfo: Boolean? = this.canChangeInfo,
|
||||||
|
canInviteUsers: Boolean? = this.canInviteUsers,
|
||||||
|
canPinMessages: Boolean? = this.canPinMessages
|
||||||
|
): ChatPermissions = ChatPermissions(
|
||||||
|
canSendMessages = canSendMessages,
|
||||||
|
canSendAudios = canSendAudios,
|
||||||
|
canSendDocuments = canSendDocuments,
|
||||||
|
canSendPhotos = canSendPhotos,
|
||||||
|
canSendVideos = canSendVideos,
|
||||||
|
canSendVideoNotes = canSendVideoNotes,
|
||||||
|
canSendVoiceNotes = canSendVoiceNotes,
|
||||||
|
canSendPolls = canSendPolls,
|
||||||
|
canSendOtherMessages = canSendOtherMessages,
|
||||||
|
canAddWebPagePreviews = canAddWebPagePreviews,
|
||||||
|
canChangeInfo = canChangeInfo,
|
||||||
|
canInviteUsers = canInviteUsers,
|
||||||
|
canPinMessages = canPinMessages
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copying current instance as [ChatPermissions], but realizations of this interface may differently override this
|
||||||
|
* method
|
||||||
|
*/
|
||||||
|
fun copyCommon(
|
||||||
|
canSendPolls: Boolean? = this.canSendPolls,
|
||||||
|
canSendOtherMessages: Boolean? = this.canSendOtherMessages,
|
||||||
|
canAddWebPagePreviews: Boolean? = this.canAddWebPagePreviews,
|
||||||
|
canChangeInfo: Boolean? = this.canChangeInfo,
|
||||||
|
canInviteUsers: Boolean? = this.canInviteUsers,
|
||||||
|
canPinMessages: Boolean? = this.canPinMessages
|
||||||
|
): ChatPermissions = ChatPermissions(
|
||||||
|
canSendMessages = null,
|
||||||
|
canSendAudios = null,
|
||||||
|
canSendDocuments = null,
|
||||||
|
canSendPhotos = null,
|
||||||
|
canSendVideos = null,
|
||||||
|
canSendVideoNotes = null,
|
||||||
|
canSendVoiceNotes = null,
|
||||||
|
canSendPolls = canSendPolls,
|
||||||
|
canSendOtherMessages = canSendOtherMessages,
|
||||||
|
canAddWebPagePreviews = canAddWebPagePreviews,
|
||||||
|
canChangeInfo = canChangeInfo,
|
||||||
|
canInviteUsers = canInviteUsers,
|
||||||
|
canPinMessages = canPinMessages
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
val LeftRestrictionsChatPermissions = ChatPermissions(
|
val LeftRestrictionsChatPermissions = ChatPermissions(
|
||||||
canSendMessages = true,
|
canSendMessages = true,
|
||||||
canSendMediaMessages = true,
|
canSendAudios = true,
|
||||||
|
canSendDocuments = true,
|
||||||
|
canSendPhotos = true,
|
||||||
|
canSendVideos = true,
|
||||||
|
canSendVideoNotes = true,
|
||||||
|
canSendVoiceNotes = true,
|
||||||
canSendPolls = true,
|
canSendPolls = true,
|
||||||
canSendOtherMessages = true,
|
canSendOtherMessages = true,
|
||||||
canAddWebPagePreviews = true,
|
canAddWebPagePreviews = true,
|
||||||
@ -37,7 +264,12 @@ val LeftRestrictionsChatPermissions = ChatPermissions(
|
|||||||
|
|
||||||
val RestrictionsChatPermissions = ChatPermissions(
|
val RestrictionsChatPermissions = ChatPermissions(
|
||||||
canSendMessages = false,
|
canSendMessages = false,
|
||||||
canSendMediaMessages = false,
|
canSendAudios = false,
|
||||||
|
canSendDocuments = false,
|
||||||
|
canSendPhotos = false,
|
||||||
|
canSendVideos = false,
|
||||||
|
canSendVideoNotes = false,
|
||||||
|
canSendVoiceNotes = false,
|
||||||
canSendPolls = false,
|
canSendPolls = false,
|
||||||
canSendOtherMessages = false,
|
canSendOtherMessages = false,
|
||||||
canAddWebPagePreviews = false,
|
canAddWebPagePreviews = false,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package dev.inmo.tgbotapi.types.chat.member
|
package dev.inmo.tgbotapi.types.chat.member
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
|
import dev.inmo.tgbotapi.types.chat.ChatPermissions
|
||||||
import dev.inmo.tgbotapi.types.chat.User
|
import dev.inmo.tgbotapi.types.chat.User
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
|
||||||
@ -13,15 +14,25 @@ data class RestrictedChatMember(
|
|||||||
@SerialName(isMemberField)
|
@SerialName(isMemberField)
|
||||||
val isMember: Boolean = false,
|
val isMember: Boolean = false,
|
||||||
@SerialName(canSendMessagesField)
|
@SerialName(canSendMessagesField)
|
||||||
val canSendMessages: Boolean = false,
|
override val canSendMessages: Boolean = false,
|
||||||
@SerialName(canSendMediaMessagesField)
|
@SerialName(canSendAudiosField)
|
||||||
val canSendMediaMessages: Boolean = false,
|
override val canSendAudios: Boolean = false,
|
||||||
|
@SerialName(canSendDocumentsField)
|
||||||
|
override val canSendDocuments: Boolean = false,
|
||||||
|
@SerialName(canSendPhotosField)
|
||||||
|
override val canSendPhotos: Boolean = false,
|
||||||
|
@SerialName(canSendVideosField)
|
||||||
|
override val canSendVideos: Boolean = false,
|
||||||
|
@SerialName(canSendVideoNotesField)
|
||||||
|
override val canSendVideoNotes: Boolean = false,
|
||||||
|
@SerialName(canSendVoiceNotesField)
|
||||||
|
override val canSendVoiceNotes: Boolean = false,
|
||||||
@SerialName(canSendPollsField)
|
@SerialName(canSendPollsField)
|
||||||
val canSendPolls: Boolean = false,
|
override val canSendPolls: Boolean = false,
|
||||||
@SerialName(canSendOtherMessagesField)
|
@SerialName(canSendOtherMessagesField)
|
||||||
val canSendOtherMessages: Boolean = false,
|
override val canSendOtherMessages: Boolean = false,
|
||||||
@SerialName(canAddWebPagePreviewsField)
|
@SerialName(canAddWebPagePreviewsField)
|
||||||
val canAddWebpagePreviews: Boolean = false,
|
override val canAddWebPagePreviews: Boolean = false,
|
||||||
@SerialName(canChangeInfoField)
|
@SerialName(canChangeInfoField)
|
||||||
override val canChangeInfo: Boolean = false,
|
override val canChangeInfo: Boolean = false,
|
||||||
@SerialName(canInviteUsersField)
|
@SerialName(canInviteUsersField)
|
||||||
@ -30,7 +41,7 @@ data class RestrictedChatMember(
|
|||||||
override val canPinMessages: Boolean = false,
|
override val canPinMessages: Boolean = false,
|
||||||
@SerialName(canManageTopicsField)
|
@SerialName(canManageTopicsField)
|
||||||
override val canManageTopics: Boolean = false
|
override val canManageTopics: Boolean = false
|
||||||
) : BannedChatMember, SpecialRightsChatMember {
|
) : BannedChatMember, SpecialRightsChatMember, ChatPermissions {
|
||||||
@SerialName(statusField)
|
@SerialName(statusField)
|
||||||
@Required
|
@Required
|
||||||
private val type: String = "restricted"
|
private val type: String = "restricted"
|
||||||
|
@ -29,6 +29,8 @@ import dev.inmo.tgbotapi.types.passport.PassportData
|
|||||||
import dev.inmo.tgbotapi.types.payments.Invoice
|
import dev.inmo.tgbotapi.types.payments.Invoice
|
||||||
import dev.inmo.tgbotapi.types.payments.SuccessfulPayment
|
import dev.inmo.tgbotapi.types.payments.SuccessfulPayment
|
||||||
import dev.inmo.tgbotapi.types.polls.Poll
|
import dev.inmo.tgbotapi.types.polls.Poll
|
||||||
|
import dev.inmo.tgbotapi.types.request.ChatShared
|
||||||
|
import dev.inmo.tgbotapi.types.request.UserShared
|
||||||
import dev.inmo.tgbotapi.types.venue.Venue
|
import dev.inmo.tgbotapi.types.venue.Venue
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -93,6 +95,9 @@ internal data class RawMessage(
|
|||||||
private val dice: Dice? = null,
|
private val dice: Dice? = null,
|
||||||
private val successful_payment: SuccessfulPayment? = null,
|
private val successful_payment: SuccessfulPayment? = null,
|
||||||
|
|
||||||
|
private val user_shared: UserShared? = null,
|
||||||
|
private val chat_shared: ChatShared? = null,
|
||||||
|
|
||||||
// Voice Chat Service Messages
|
// Voice Chat Service Messages
|
||||||
private val video_chat_scheduled: VideoChatScheduled? = null,
|
private val video_chat_scheduled: VideoChatScheduled? = null,
|
||||||
private val video_chat_started: VideoChatStarted? = null,
|
private val video_chat_started: VideoChatStarted? = null,
|
||||||
@ -249,6 +254,8 @@ internal data class RawMessage(
|
|||||||
successful_payment != null -> SuccessfulPaymentEvent(successful_payment)
|
successful_payment != null -> SuccessfulPaymentEvent(successful_payment)
|
||||||
connected_website != null -> UserLoggedIn(connected_website)
|
connected_website != null -> UserLoggedIn(connected_website)
|
||||||
web_app_data != null -> web_app_data
|
web_app_data != null -> web_app_data
|
||||||
|
user_shared != null -> user_shared
|
||||||
|
chat_shared != null -> chat_shared
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.request
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.ChatId
|
||||||
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
|
import dev.inmo.tgbotapi.types.UserId
|
||||||
|
import dev.inmo.tgbotapi.types.chatIdField
|
||||||
|
import dev.inmo.tgbotapi.types.requestIdField
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ChatShared(
|
||||||
|
@SerialName(requestIdField)
|
||||||
|
override val requestId: RequestId,
|
||||||
|
@SerialName(chatIdField)
|
||||||
|
override val chatId: ChatId
|
||||||
|
) : ChatSharedRequest
|
@ -0,0 +1,8 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.request
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
|
import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.PrivateEvent
|
||||||
|
|
||||||
|
sealed interface ChatSharedRequest : RequestResponse, PrivateEvent {
|
||||||
|
val chatId: ChatIdentifier
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.request
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlin.jvm.JvmInline
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
@JvmInline
|
||||||
|
value class RequestId(
|
||||||
|
val int: Int
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun random() = RequestId(Random.nextInt())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.request
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.utils.internal.ClassCastsIncluded
|
||||||
|
|
||||||
|
@ClassCastsIncluded
|
||||||
|
sealed interface RequestResponse {
|
||||||
|
val requestId: RequestId
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package dev.inmo.tgbotapi.types.request
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.types.ChatId
|
||||||
|
import dev.inmo.tgbotapi.types.UserId
|
||||||
|
import dev.inmo.tgbotapi.types.requestIdField
|
||||||
|
import dev.inmo.tgbotapi.types.userIdField
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class UserShared(
|
||||||
|
@SerialName(requestIdField)
|
||||||
|
override val requestId: RequestId,
|
||||||
|
@SerialName(userIdField)
|
||||||
|
val userId: UserId
|
||||||
|
) : ChatSharedRequest {
|
||||||
|
override val chatId: ChatId
|
||||||
|
get() = userId
|
||||||
|
}
|
@ -113,6 +113,7 @@ import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.URLInlineKeyboardBu
|
|||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.UnknownInlineKeyboardButton
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.UnknownInlineKeyboardButton
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.WebAppInlineKeyboardButton
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.WebAppInlineKeyboardButton
|
||||||
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||||
|
import dev.inmo.tgbotapi.types.buttons.KeyboardButtonRequestUser
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.buttons.ReplyForce
|
import dev.inmo.tgbotapi.types.buttons.ReplyForce
|
||||||
import dev.inmo.tgbotapi.types.buttons.ReplyKeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.ReplyKeyboardMarkup
|
||||||
@ -433,6 +434,10 @@ import dev.inmo.tgbotapi.types.queries.callback.MessageCallbackQuery
|
|||||||
import dev.inmo.tgbotapi.types.queries.callback.MessageDataCallbackQuery
|
import dev.inmo.tgbotapi.types.queries.callback.MessageDataCallbackQuery
|
||||||
import dev.inmo.tgbotapi.types.queries.callback.MessageGameShortNameCallbackQuery
|
import dev.inmo.tgbotapi.types.queries.callback.MessageGameShortNameCallbackQuery
|
||||||
import dev.inmo.tgbotapi.types.queries.callback.UnknownCallbackQueryType
|
import dev.inmo.tgbotapi.types.queries.callback.UnknownCallbackQueryType
|
||||||
|
import dev.inmo.tgbotapi.types.request.ChatShared
|
||||||
|
import dev.inmo.tgbotapi.types.request.ChatSharedRequest
|
||||||
|
import dev.inmo.tgbotapi.types.request.RequestResponse
|
||||||
|
import dev.inmo.tgbotapi.types.request.UserShared
|
||||||
import dev.inmo.tgbotapi.types.update.CallbackQueryUpdate
|
import dev.inmo.tgbotapi.types.update.CallbackQueryUpdate
|
||||||
import dev.inmo.tgbotapi.types.update.ChannelPostUpdate
|
import dev.inmo.tgbotapi.types.update.ChannelPostUpdate
|
||||||
import dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate
|
import dev.inmo.tgbotapi.types.update.ChatJoinRequestUpdate
|
||||||
@ -1879,6 +1884,34 @@ public inline fun <T>
|
|||||||
InlineKeyboardButton.ifWebAppInlineKeyboardButton(block: (WebAppInlineKeyboardButton) -> T): T?
|
InlineKeyboardButton.ifWebAppInlineKeyboardButton(block: (WebAppInlineKeyboardButton) -> T): T?
|
||||||
= webAppInlineKeyboardButtonOrNull() ?.let(block)
|
= webAppInlineKeyboardButtonOrNull() ?.let(block)
|
||||||
|
|
||||||
|
public inline fun KeyboardButtonRequestUser.anyOrNull(): KeyboardButtonRequestUser.Any? = this as?
|
||||||
|
dev.inmo.tgbotapi.types.buttons.KeyboardButtonRequestUser.Any
|
||||||
|
|
||||||
|
public inline fun KeyboardButtonRequestUser.anyOrThrow(): KeyboardButtonRequestUser.Any = this as
|
||||||
|
dev.inmo.tgbotapi.types.buttons.KeyboardButtonRequestUser.Any
|
||||||
|
|
||||||
|
public inline fun <T> KeyboardButtonRequestUser.ifAny(block: (KeyboardButtonRequestUser.Any) -> T):
|
||||||
|
T? = anyOrNull() ?.let(block)
|
||||||
|
|
||||||
|
public inline fun KeyboardButtonRequestUser.botOrNull(): KeyboardButtonRequestUser.Bot? = this as?
|
||||||
|
dev.inmo.tgbotapi.types.buttons.KeyboardButtonRequestUser.Bot
|
||||||
|
|
||||||
|
public inline fun KeyboardButtonRequestUser.botOrThrow(): KeyboardButtonRequestUser.Bot = this as
|
||||||
|
dev.inmo.tgbotapi.types.buttons.KeyboardButtonRequestUser.Bot
|
||||||
|
|
||||||
|
public inline fun <T> KeyboardButtonRequestUser.ifBot(block: (KeyboardButtonRequestUser.Bot) -> T):
|
||||||
|
T? = botOrNull() ?.let(block)
|
||||||
|
|
||||||
|
public inline fun KeyboardButtonRequestUser.commonOrNull(): KeyboardButtonRequestUser.Common? = this
|
||||||
|
as? dev.inmo.tgbotapi.types.buttons.KeyboardButtonRequestUser.Common
|
||||||
|
|
||||||
|
public inline fun KeyboardButtonRequestUser.commonOrThrow(): KeyboardButtonRequestUser.Common = this
|
||||||
|
as dev.inmo.tgbotapi.types.buttons.KeyboardButtonRequestUser.Common
|
||||||
|
|
||||||
|
public inline fun <T>
|
||||||
|
KeyboardButtonRequestUser.ifCommon(block: (KeyboardButtonRequestUser.Common) -> T): T? =
|
||||||
|
commonOrNull() ?.let(block)
|
||||||
|
|
||||||
public inline fun KeyboardMarkup.inlineKeyboardMarkupOrNull(): InlineKeyboardMarkup? = this as?
|
public inline fun KeyboardMarkup.inlineKeyboardMarkupOrNull(): InlineKeyboardMarkup? = this as?
|
||||||
dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
|
||||||
|
|
||||||
@ -3031,6 +3064,33 @@ public inline fun ChatEvent.successfulPaymentEventOrThrow(): SuccessfulPaymentEv
|
|||||||
public inline fun <T> ChatEvent.ifSuccessfulPaymentEvent(block: (SuccessfulPaymentEvent) -> T): T? =
|
public inline fun <T> ChatEvent.ifSuccessfulPaymentEvent(block: (SuccessfulPaymentEvent) -> T): T? =
|
||||||
successfulPaymentEventOrNull() ?.let(block)
|
successfulPaymentEventOrNull() ?.let(block)
|
||||||
|
|
||||||
|
public inline fun ChatEvent.chatSharedOrNull(): ChatShared? = this as?
|
||||||
|
dev.inmo.tgbotapi.types.request.ChatShared
|
||||||
|
|
||||||
|
public inline fun ChatEvent.chatSharedOrThrow(): ChatShared = this as
|
||||||
|
dev.inmo.tgbotapi.types.request.ChatShared
|
||||||
|
|
||||||
|
public inline fun <T> ChatEvent.ifChatShared(block: (ChatShared) -> T): T? = chatSharedOrNull()
|
||||||
|
?.let(block)
|
||||||
|
|
||||||
|
public inline fun ChatEvent.chatSharedRequestOrNull(): ChatSharedRequest? = this as?
|
||||||
|
dev.inmo.tgbotapi.types.request.ChatSharedRequest
|
||||||
|
|
||||||
|
public inline fun ChatEvent.chatSharedRequestOrThrow(): ChatSharedRequest = this as
|
||||||
|
dev.inmo.tgbotapi.types.request.ChatSharedRequest
|
||||||
|
|
||||||
|
public inline fun <T> ChatEvent.ifChatSharedRequest(block: (ChatSharedRequest) -> T): T? =
|
||||||
|
chatSharedRequestOrNull() ?.let(block)
|
||||||
|
|
||||||
|
public inline fun ChatEvent.userSharedOrNull(): UserShared? = this as?
|
||||||
|
dev.inmo.tgbotapi.types.request.UserShared
|
||||||
|
|
||||||
|
public inline fun ChatEvent.userSharedOrThrow(): UserShared = this as
|
||||||
|
dev.inmo.tgbotapi.types.request.UserShared
|
||||||
|
|
||||||
|
public inline fun <T> ChatEvent.ifUserShared(block: (UserShared) -> T): T? = userSharedOrNull()
|
||||||
|
?.let(block)
|
||||||
|
|
||||||
public inline fun ForwardInfo.byAnonymousOrNull(): ForwardInfo.ByAnonymous? = this as?
|
public inline fun ForwardInfo.byAnonymousOrNull(): ForwardInfo.ByAnonymous? = this as?
|
||||||
dev.inmo.tgbotapi.types.message.ForwardInfo.ByAnonymous
|
dev.inmo.tgbotapi.types.message.ForwardInfo.ByAnonymous
|
||||||
|
|
||||||
@ -4659,6 +4719,33 @@ public inline fun Poll.quizPollOrThrow(): QuizPoll = this as dev.inmo.tgbotapi.t
|
|||||||
|
|
||||||
public inline fun <T> Poll.ifQuizPoll(block: (QuizPoll) -> T): T? = quizPollOrNull() ?.let(block)
|
public inline fun <T> Poll.ifQuizPoll(block: (QuizPoll) -> T): T? = quizPollOrNull() ?.let(block)
|
||||||
|
|
||||||
|
public inline fun RequestResponse.chatSharedOrNull(): ChatShared? = this as?
|
||||||
|
dev.inmo.tgbotapi.types.request.ChatShared
|
||||||
|
|
||||||
|
public inline fun RequestResponse.chatSharedOrThrow(): ChatShared = this as
|
||||||
|
dev.inmo.tgbotapi.types.request.ChatShared
|
||||||
|
|
||||||
|
public inline fun <T> RequestResponse.ifChatShared(block: (ChatShared) -> T): T? =
|
||||||
|
chatSharedOrNull() ?.let(block)
|
||||||
|
|
||||||
|
public inline fun RequestResponse.chatSharedRequestOrNull(): ChatSharedRequest? = this as?
|
||||||
|
dev.inmo.tgbotapi.types.request.ChatSharedRequest
|
||||||
|
|
||||||
|
public inline fun RequestResponse.chatSharedRequestOrThrow(): ChatSharedRequest = this as
|
||||||
|
dev.inmo.tgbotapi.types.request.ChatSharedRequest
|
||||||
|
|
||||||
|
public inline fun <T> RequestResponse.ifChatSharedRequest(block: (ChatSharedRequest) -> T): T? =
|
||||||
|
chatSharedRequestOrNull() ?.let(block)
|
||||||
|
|
||||||
|
public inline fun RequestResponse.userSharedOrNull(): UserShared? = this as?
|
||||||
|
dev.inmo.tgbotapi.types.request.UserShared
|
||||||
|
|
||||||
|
public inline fun RequestResponse.userSharedOrThrow(): UserShared = this as
|
||||||
|
dev.inmo.tgbotapi.types.request.UserShared
|
||||||
|
|
||||||
|
public inline fun <T> RequestResponse.ifUserShared(block: (UserShared) -> T): T? =
|
||||||
|
userSharedOrNull() ?.let(block)
|
||||||
|
|
||||||
public inline fun Update.callbackQueryUpdateOrNull(): CallbackQueryUpdate? = this as?
|
public inline fun Update.callbackQueryUpdateOrNull(): CallbackQueryUpdate? = this as?
|
||||||
dev.inmo.tgbotapi.types.update.CallbackQueryUpdate
|
dev.inmo.tgbotapi.types.update.CallbackQueryUpdate
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package dev.inmo.tgbotapi.extensions.utils.types.buttons
|
package dev.inmo.tgbotapi.extensions.utils.types.buttons
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.types.buttons.*
|
import dev.inmo.tgbotapi.types.buttons.*
|
||||||
|
import dev.inmo.tgbotapi.types.buttons.reply.requestChatReplyButton
|
||||||
|
import dev.inmo.tgbotapi.types.buttons.reply.requestUserReplyButton
|
||||||
|
import dev.inmo.tgbotapi.types.chat.member.ChatAdministratorRights
|
||||||
|
import dev.inmo.tgbotapi.types.request.RequestId
|
||||||
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
|
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
|
||||||
import dev.inmo.tgbotapi.utils.*
|
import dev.inmo.tgbotapi.utils.*
|
||||||
|
|
||||||
@ -138,3 +142,164 @@ inline fun ReplyKeyboardRowBuilder.webAppButton(
|
|||||||
text: String,
|
text: String,
|
||||||
url: String
|
url: String
|
||||||
) = webAppButton(text, WebAppInfo(url))
|
) = webAppButton(text, WebAppInfo(url))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestUserKeyboardButton]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun ReplyKeyboardRowBuilder.requestUserButton(
|
||||||
|
text: String,
|
||||||
|
requestUser: KeyboardButtonRequestUser
|
||||||
|
) = add(
|
||||||
|
requestUserReplyButton(
|
||||||
|
text,
|
||||||
|
requestUser
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Bot]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun ReplyKeyboardRowBuilder.requestBotButton(
|
||||||
|
text: String,
|
||||||
|
requestId: RequestId
|
||||||
|
) = requestUserButton(
|
||||||
|
text,
|
||||||
|
KeyboardButtonRequestUser.Bot(requestId)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Common]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun ReplyKeyboardRowBuilder.requestUserButton(
|
||||||
|
text: String,
|
||||||
|
requestId: RequestId,
|
||||||
|
premiumUser: Boolean? = null
|
||||||
|
) = requestUserButton(
|
||||||
|
text,
|
||||||
|
KeyboardButtonRequestUser.Common(requestId, premiumUser)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestUserKeyboardButton] with [KeyboardButtonRequestUser.Any]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun ReplyKeyboardRowBuilder.requestUserOrBotButton(
|
||||||
|
text: String,
|
||||||
|
requestId: RequestId
|
||||||
|
) = requestUserButton(
|
||||||
|
text,
|
||||||
|
KeyboardButtonRequestUser.Any(requestId)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestChatKeyboardButton]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun ReplyKeyboardRowBuilder.requestChatButton(
|
||||||
|
text: String,
|
||||||
|
requestChat: KeyboardButtonRequestChat
|
||||||
|
) = add(
|
||||||
|
requestChatReplyButton(
|
||||||
|
text,
|
||||||
|
requestChat
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestChatKeyboardButton] with [KeyboardButtonRequestChat]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun ReplyKeyboardRowBuilder.requestChatButton(
|
||||||
|
text: String,
|
||||||
|
requestId: RequestId,
|
||||||
|
isChannel: Boolean? = null,
|
||||||
|
isForum: Boolean? = null,
|
||||||
|
isPublic: Boolean? = null,
|
||||||
|
isOwnedBy: Boolean? = null,
|
||||||
|
userRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botIsMember: Boolean? = null
|
||||||
|
) = requestChatButton(
|
||||||
|
text,
|
||||||
|
KeyboardButtonRequestChat(
|
||||||
|
requestId = requestId,
|
||||||
|
isChannel = isChannel,
|
||||||
|
isForum = isForum,
|
||||||
|
isPublic = isPublic,
|
||||||
|
isOwnedBy = isOwnedBy,
|
||||||
|
userRightsInChat = userRightsInChat,
|
||||||
|
botRightsInChat = botRightsInChat,
|
||||||
|
botIsMember = botIsMember
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestChatKeyboardButton] with [KeyboardButtonRequestChat.Channel]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun ReplyKeyboardRowBuilder.requestChannelButton(
|
||||||
|
text: String,
|
||||||
|
requestId: RequestId,
|
||||||
|
isPublic: Boolean? = null,
|
||||||
|
isOwnedBy: Boolean? = null,
|
||||||
|
userRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botIsMember: Boolean? = null
|
||||||
|
) = requestChatButton(
|
||||||
|
text,
|
||||||
|
KeyboardButtonRequestChat.Channel(
|
||||||
|
requestId = requestId,
|
||||||
|
isPublic = isPublic,
|
||||||
|
isOwnedBy = isOwnedBy,
|
||||||
|
userRightsInChat = userRightsInChat,
|
||||||
|
botRightsInChat = botRightsInChat,
|
||||||
|
botIsMember = botIsMember
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and put [RequestChatKeyboardButton] with [KeyboardButtonRequestChat.Group]
|
||||||
|
*
|
||||||
|
* @see replyKeyboard
|
||||||
|
* @see ReplyKeyboardBuilder.row
|
||||||
|
*/
|
||||||
|
inline fun ReplyKeyboardRowBuilder.requestGroupButton(
|
||||||
|
text: String,
|
||||||
|
requestId: RequestId,
|
||||||
|
isForum: Boolean? = null,
|
||||||
|
isPublic: Boolean? = null,
|
||||||
|
isOwnedBy: Boolean? = null,
|
||||||
|
userRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botRightsInChat: ChatAdministratorRights? = null,
|
||||||
|
botIsMember: Boolean? = null
|
||||||
|
) = requestChatButton(
|
||||||
|
text,
|
||||||
|
KeyboardButtonRequestChat.Group(
|
||||||
|
requestId = requestId,
|
||||||
|
isForum = isForum,
|
||||||
|
isPublic = isPublic,
|
||||||
|
isOwnedBy = isOwnedBy,
|
||||||
|
userRightsInChat = userRightsInChat,
|
||||||
|
botRightsInChat = botRightsInChat,
|
||||||
|
botIsMember = botIsMember
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@ -5,7 +5,6 @@ import dev.inmo.tgbotapi.bot.RequestsExecutor
|
|||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.bot.exceptions.*
|
import dev.inmo.tgbotapi.bot.exceptions.*
|
||||||
import dev.inmo.tgbotapi.extensions.utils.updates.convertWithMediaGroupUpdates
|
import dev.inmo.tgbotapi.extensions.utils.updates.convertWithMediaGroupUpdates
|
||||||
import dev.inmo.tgbotapi.extensions.utils.updates.lastUpdateIdentifier
|
|
||||||
import dev.inmo.tgbotapi.requests.GetUpdates
|
import dev.inmo.tgbotapi.requests.GetUpdates
|
||||||
import dev.inmo.tgbotapi.requests.webhook.DeleteWebhook
|
import dev.inmo.tgbotapi.requests.webhook.DeleteWebhook
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
@ -24,7 +23,8 @@ fun TelegramBot.longPollingFlow(
|
|||||||
timeoutSeconds: Seconds = 30,
|
timeoutSeconds: Seconds = 30,
|
||||||
exceptionsHandler: (ExceptionHandler<Unit>)? = null,
|
exceptionsHandler: (ExceptionHandler<Unit>)? = null,
|
||||||
allowedUpdates: List<String>? = ALL_UPDATES_LIST,
|
allowedUpdates: List<String>? = ALL_UPDATES_LIST,
|
||||||
autoDisableWebhooks: Boolean = true
|
autoDisableWebhooks: Boolean = true,
|
||||||
|
autoSkipTimeoutExceptions: Boolean = true
|
||||||
): Flow<Update> = channelFlow {
|
): Flow<Update> = channelFlow {
|
||||||
if (autoDisableWebhooks) {
|
if (autoDisableWebhooks) {
|
||||||
runCatchingSafely {
|
runCatchingSafely {
|
||||||
@ -32,58 +32,77 @@ fun TelegramBot.longPollingFlow(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val contextSafelyExceptionHandler = coroutineContext[ContextSafelyExceptionHandlerKey]
|
||||||
|
val contextToWork = if (contextSafelyExceptionHandler == null || !autoSkipTimeoutExceptions) {
|
||||||
|
coroutineContext
|
||||||
|
} else {
|
||||||
|
coroutineContext + ContextSafelyExceptionHandler { e ->
|
||||||
|
if (e is HttpRequestTimeoutException || (e is CommonBotException && e.cause is HttpRequestTimeoutException)) {
|
||||||
|
return@ContextSafelyExceptionHandler
|
||||||
|
} else {
|
||||||
|
contextSafelyExceptionHandler.handler(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var lastUpdateIdentifier: UpdateIdentifier? = null
|
var lastUpdateIdentifier: UpdateIdentifier? = null
|
||||||
|
|
||||||
while (isActive) {
|
withContext(contextToWork) {
|
||||||
safely(
|
while (isActive) {
|
||||||
{ e ->
|
safely(
|
||||||
exceptionsHandler ?.invoke(e)
|
{ e ->
|
||||||
if (e is RequestException) {
|
val isHttpRequestTimeoutException = e is HttpRequestTimeoutException || (e is CommonBotException && e.cause is HttpRequestTimeoutException)
|
||||||
delay(1000L)
|
if (isHttpRequestTimeoutException && autoSkipTimeoutExceptions) {
|
||||||
|
return@safely
|
||||||
|
}
|
||||||
|
exceptionsHandler ?.invoke(e)
|
||||||
|
if (e is RequestException) {
|
||||||
|
delay(1000L)
|
||||||
|
}
|
||||||
|
if (e is GetUpdatesConflict && (exceptionsHandler == null || exceptionsHandler == defaultSafelyExceptionHandler)) {
|
||||||
|
println("Warning!!! Other bot with the same bot token requests updates with getUpdate in parallel")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (e is GetUpdatesConflict && (exceptionsHandler == null || exceptionsHandler == defaultSafelyExceptionHandler)) {
|
) {
|
||||||
println("Warning!!! Other bot with the same bot token requests updates with getUpdate in parallel")
|
val updates = execute(
|
||||||
|
GetUpdates(
|
||||||
|
offset = lastUpdateIdentifier?.plus(1),
|
||||||
|
timeout = timeoutSeconds,
|
||||||
|
allowed_updates = allowedUpdates
|
||||||
|
)
|
||||||
|
).let { originalUpdates ->
|
||||||
|
val converted = originalUpdates.convertWithMediaGroupUpdates()
|
||||||
|
/**
|
||||||
|
* Dirty hack for cases when the media group was retrieved not fully:
|
||||||
|
*
|
||||||
|
* We are throw out the last media group and will reretrieve it again in the next get updates
|
||||||
|
* and it will guarantee that it is full
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Dirty hack for cases when the media group was retrieved not fully:
|
||||||
|
*
|
||||||
|
* We are throw out the last media group and will reretrieve it again in the next get updates
|
||||||
|
* and it will guarantee that it is full
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
originalUpdates.size == getUpdatesLimit.last
|
||||||
|
&& ((converted.last() as? BaseSentMessageUpdate) ?.data as? CommonMessage<*>) ?.content is MediaGroupContent<*>
|
||||||
|
) {
|
||||||
|
converted - converted.last()
|
||||||
|
} else {
|
||||||
|
converted
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
) {
|
|
||||||
val updates = execute(
|
|
||||||
GetUpdates(
|
|
||||||
offset = lastUpdateIdentifier?.plus(1),
|
|
||||||
timeout = timeoutSeconds,
|
|
||||||
allowed_updates = allowedUpdates
|
|
||||||
)
|
|
||||||
).let { originalUpdates ->
|
|
||||||
val converted = originalUpdates.convertWithMediaGroupUpdates()
|
|
||||||
/**
|
|
||||||
* Dirty hack for cases when the media group was retrieved not fully:
|
|
||||||
*
|
|
||||||
* We are throw out the last media group and will reretrieve it again in the next get updates
|
|
||||||
* and it will guarantee that it is full
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Dirty hack for cases when the media group was retrieved not fully:
|
|
||||||
*
|
|
||||||
* We are throw out the last media group and will reretrieve it again in the next get updates
|
|
||||||
* and it will guarantee that it is full
|
|
||||||
*/
|
|
||||||
if (
|
|
||||||
originalUpdates.size == getUpdatesLimit.last
|
|
||||||
&& ((converted.last() as? BaseSentMessageUpdate) ?.data as? CommonMessage<*>) ?.content is MediaGroupContent<*>
|
|
||||||
) {
|
|
||||||
converted - converted.last()
|
|
||||||
} else {
|
|
||||||
converted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
safelyWithResult {
|
safelyWithResult {
|
||||||
for (update in updates) {
|
for (update in updates) {
|
||||||
send(update)
|
send(update)
|
||||||
|
|
||||||
lastUpdateIdentifier = update.updateId
|
lastUpdateIdentifier = update.updateId
|
||||||
|
}
|
||||||
|
}.onFailure {
|
||||||
|
cancel(it as? CancellationException ?: return@onFailure)
|
||||||
}
|
}
|
||||||
}.onFailure {
|
|
||||||
cancel(it as? CancellationException ?: return@onFailure)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,8 +114,15 @@ fun TelegramBot.startGettingOfUpdatesByLongPolling(
|
|||||||
exceptionsHandler: (ExceptionHandler<Unit>)? = null,
|
exceptionsHandler: (ExceptionHandler<Unit>)? = null,
|
||||||
allowedUpdates: List<String>? = ALL_UPDATES_LIST,
|
allowedUpdates: List<String>? = ALL_UPDATES_LIST,
|
||||||
autoDisableWebhooks: Boolean = true,
|
autoDisableWebhooks: Boolean = true,
|
||||||
|
autoSkipTimeoutExceptions: Boolean = true,
|
||||||
updatesReceiver: UpdateReceiver<Update>
|
updatesReceiver: UpdateReceiver<Update>
|
||||||
): Job = longPollingFlow(timeoutSeconds, exceptionsHandler, allowedUpdates, autoDisableWebhooks).subscribeSafely(
|
): Job = longPollingFlow(
|
||||||
|
timeoutSeconds = timeoutSeconds,
|
||||||
|
exceptionsHandler = exceptionsHandler,
|
||||||
|
allowedUpdates = allowedUpdates,
|
||||||
|
autoDisableWebhooks = autoDisableWebhooks,
|
||||||
|
autoSkipTimeoutExceptions = autoSkipTimeoutExceptions
|
||||||
|
).subscribeSafely(
|
||||||
scope,
|
scope,
|
||||||
exceptionsHandler ?: defaultSafelyExceptionHandler,
|
exceptionsHandler ?: defaultSafelyExceptionHandler,
|
||||||
updatesReceiver
|
updatesReceiver
|
||||||
@ -111,7 +137,7 @@ fun TelegramBot.createAccumulatedUpdatesRetrieverFlow(
|
|||||||
avoidCallbackQueries: Boolean = false,
|
avoidCallbackQueries: Boolean = false,
|
||||||
exceptionsHandler: ExceptionHandler<Unit>? = null,
|
exceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
allowedUpdates: List<String>? = ALL_UPDATES_LIST,
|
allowedUpdates: List<String>? = ALL_UPDATES_LIST,
|
||||||
autoDisableWebhooks: Boolean = true,
|
autoDisableWebhooks: Boolean = true
|
||||||
): Flow<Update> = longPollingFlow(
|
): Flow<Update> = longPollingFlow(
|
||||||
timeoutSeconds = 0,
|
timeoutSeconds = 0,
|
||||||
exceptionsHandler = {
|
exceptionsHandler = {
|
||||||
@ -122,7 +148,8 @@ fun TelegramBot.createAccumulatedUpdatesRetrieverFlow(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
allowedUpdates = allowedUpdates,
|
allowedUpdates = allowedUpdates,
|
||||||
autoDisableWebhooks = autoDisableWebhooks
|
autoDisableWebhooks = autoDisableWebhooks,
|
||||||
|
autoSkipTimeoutExceptions = false
|
||||||
).filter {
|
).filter {
|
||||||
!(it is InlineQueryUpdate && avoidInlineQueries || it is CallbackQueryUpdate && avoidCallbackQueries)
|
!(it is InlineQueryUpdate && avoidInlineQueries || it is CallbackQueryUpdate && avoidCallbackQueries)
|
||||||
}
|
}
|
||||||
@ -191,9 +218,18 @@ fun TelegramBot.longPolling(
|
|||||||
timeoutSeconds: Seconds = 30,
|
timeoutSeconds: Seconds = 30,
|
||||||
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
||||||
autoDisableWebhooks: Boolean = true,
|
autoDisableWebhooks: Boolean = true,
|
||||||
|
autoSkipTimeoutExceptions: Boolean = true,
|
||||||
exceptionsHandler: ExceptionHandler<Unit>? = null
|
exceptionsHandler: ExceptionHandler<Unit>? = null
|
||||||
): Job = updatesFilter.run {
|
): Job = updatesFilter.run {
|
||||||
startGettingOfUpdatesByLongPolling(timeoutSeconds, scope, exceptionsHandler, allowedUpdates, autoDisableWebhooks, asUpdateReceiver)
|
startGettingOfUpdatesByLongPolling(
|
||||||
|
timeoutSeconds = timeoutSeconds,
|
||||||
|
scope = scope,
|
||||||
|
exceptionsHandler = exceptionsHandler,
|
||||||
|
allowedUpdates = allowedUpdates,
|
||||||
|
autoDisableWebhooks = autoDisableWebhooks,
|
||||||
|
autoSkipTimeoutExceptions = autoSkipTimeoutExceptions,
|
||||||
|
updatesReceiver = asUpdateReceiver
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,8 +244,9 @@ fun TelegramBot.longPolling(
|
|||||||
exceptionsHandler: ExceptionHandler<Unit>? = null,
|
exceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
flowsUpdatesFilterUpdatesKeeperCount: Int = 100,
|
flowsUpdatesFilterUpdatesKeeperCount: Int = 100,
|
||||||
autoDisableWebhooks: Boolean = true,
|
autoDisableWebhooks: Boolean = true,
|
||||||
|
autoSkipTimeoutExceptions: Boolean = true,
|
||||||
flowUpdatesPreset: FlowsUpdatesFilter.() -> Unit
|
flowUpdatesPreset: FlowsUpdatesFilter.() -> Unit
|
||||||
): Job = longPolling(FlowsUpdatesFilter(flowsUpdatesFilterUpdatesKeeperCount).apply(flowUpdatesPreset), timeoutSeconds, scope, autoDisableWebhooks, exceptionsHandler)
|
): Job = longPolling(FlowsUpdatesFilter(flowsUpdatesFilterUpdatesKeeperCount).apply(flowUpdatesPreset), timeoutSeconds, scope, autoDisableWebhooks, autoSkipTimeoutExceptions, exceptionsHandler)
|
||||||
|
|
||||||
fun RequestsExecutor.startGettingOfUpdatesByLongPolling(
|
fun RequestsExecutor.startGettingOfUpdatesByLongPolling(
|
||||||
updatesFilter: UpdatesFilter,
|
updatesFilter: UpdatesFilter,
|
||||||
@ -217,11 +254,13 @@ fun RequestsExecutor.startGettingOfUpdatesByLongPolling(
|
|||||||
exceptionsHandler: ExceptionHandler<Unit>? = null,
|
exceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
||||||
autoDisableWebhooks: Boolean = true,
|
autoDisableWebhooks: Boolean = true,
|
||||||
|
autoSkipTimeoutExceptions: Boolean = true,
|
||||||
): Job = startGettingOfUpdatesByLongPolling(
|
): Job = startGettingOfUpdatesByLongPolling(
|
||||||
timeoutSeconds,
|
timeoutSeconds,
|
||||||
scope,
|
scope,
|
||||||
exceptionsHandler,
|
exceptionsHandler,
|
||||||
updatesFilter.allowedUpdates,
|
updatesFilter.allowedUpdates,
|
||||||
autoDisableWebhooks,
|
autoDisableWebhooks,
|
||||||
|
autoSkipTimeoutExceptions,
|
||||||
updatesFilter.asUpdateReceiver
|
updatesFilter.asUpdateReceiver
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user